diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | linuxthreads/ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/getdents.c | 12 |
3 files changed, 19 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index 2c6ecb0ad7..31afab7af9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2000-04-09 Ulrich Drepper <drepper@redhat.com> + * sysdeps/unix/sysv/linux/getdents.c (__getdents): Avoid initial + lseek call be passing in a buffer which never allow a successful + first getdents syscall if not at leas the initial entry can be + stored in the user buffer. + * localedata/Makefile: Add rules to clean up directories created by new strfmon tests. diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index fff24c8a03..86e02aac61 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,9 @@ +2000-04-09 Ulrich Drepper <drepper@redhat.com> + + * signals.c (sigaction): Fix return value for the case SIG is one + of the signals the implementation uses. + Patch by Xavier.Leroy@inria.fr. + 2000-04-01 Andreas Jaeger <aj@suse.de> * attr.c: Use shlib-compat macros. diff --git a/sysdeps/unix/sysv/linux/getdents.c b/sysdeps/unix/sysv/linux/getdents.c index d142843cbe..5f1e7c1b30 100644 --- a/sysdeps/unix/sysv/linux/getdents.c +++ b/sysdeps/unix/sysv/linux/getdents.c @@ -17,6 +17,7 @@ Boston, MA 02111-1307, USA. */ #include <alloca.h> +#include <assert.h> #include <errno.h> #include <dirent.h> #include <stddef.h> @@ -33,7 +34,7 @@ #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -extern int __syscall_getdents __P ((int fd, char *buf, size_t nbytes)); +extern int __syscall_getdents (int fd, char *buf, size_t nbytes); /* For Linux we need a special version of this file since the definition of `struct dirent' is not the same for the kernel and @@ -67,7 +68,7 @@ ssize_t internal_function __getdents (int fd, char *buf, size_t nbytes) { - off_t last_offset = __lseek (fd, 0, SEEK_CUR); + off_t last_offset = -1; size_t red_nbytes; struct kernel_dirent *skdp, *kdp; struct dirent *dp; @@ -75,8 +76,10 @@ __getdents (int fd, char *buf, size_t nbytes) const size_t size_diff = (offsetof (struct dirent, d_name) - offsetof (struct kernel_dirent, d_name)); - red_nbytes = nbytes - ((nbytes / (offsetof (struct dirent, d_name) + 14)) - * size_diff); + red_nbytes = MIN (nbytes + - ((nbytes / (offsetof (struct dirent, d_name) + 14)) + * size_diff), + nbytes - size_diff); dp = (struct dirent *) buf; skdp = kdp = __alloca (red_nbytes); @@ -97,6 +100,7 @@ __getdents (int fd, char *buf, size_t nbytes) { /* Our heuristic failed. We read too many entries. Reset the stream. */ + assert (last_offset != -1); __lseek (fd, last_offset, SEEK_SET); if ((char *) dp == buf) |