Bug#173913: more details on this
On Mon, Dec 23, 2002 at 03:14:33AM +0900, GOTO Masanori wrote:
> At Sun, 22 Dec 2002 09:12:16 -0500,
> Ben Collins wrote:
> > > fcntl64(3, F_SETFD, FD_CLOEXEC) = -1 ENOSYS (Function not implemented)
> > > fcntl(3, F_SETFD, FD_CLOEXEC) = 0
> > > brk(0) = 0x805b000
> > > brk(0x805c000) = 0x805c000
> > > getdents64(0x3, 0x805a6f8, 0x1000, 0) = -1 ENOSYS (Function not implemented)
> >
> > You see how the fcntl64 falls back to fcntl? Getdents64 should do the
> > same and it isn't. I bet all the problems are on 2.2.x kernels, and
> > 2.4.x works fine.
> >
> > This is a glibc bug. Getdents64 needs to be fixed to fallback to
> > getdents when getdents64 returns ENOSYS.
>
> Yes. It's so serious. All 2.2 users get this crash.
> This problem is occured by below change.
>
> 2002-12-01 Roland McGrath <roland@redhat.com>
>
> * sysdeps/unix/sysv/linux/getdents.c (__GETDENTS): Fix condition
> testing getdents64 return value.
>
> --- sysdeps/unix/sysv/linux/getdents.c 3 Nov 2002 03:47:49 -0000 1.19
> +++ sysdeps/unix/sysv/linux/getdents.c 2 Dec 2002 21:01:50 -0000 1.20
> @@ -126,7 +126,7 @@
> retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),
> kbytes);
> # ifndef __ASSUME_GETDENTS64_SYSCALL
> - if (retval != -1 && errno != -EINVAL)
> + if (retval != -1 || errno != EINVAL)
> # endif
> {
> const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)
>
> This patch fixes getdents error bug, on the contrary if retval == -1 &&
> errno == ENOSYS, then this function returns error. I think below
> patch fixes the problem (but someone think it's something ad-hoc).
>
> --- sysdeps/unix/sysv/linux/getdents.c.org 2002-12-14 02:09:29.000000000 +0900
> +++ sysdeps/unix/sysv/linux/getdents.c 2002-12-23 02:15:12.000000000 +0900
> @@ -126,7 +126,7 @@
> retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),
> kbytes);
> # ifndef __ASSUME_GETDENTS64_SYSCALL
> - if (retval != -1 || errno != EINVAL)
> + if (retval != -1 || (errno != EINVAL && errno != ENOSYS))
> # endif
> {
> const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)
>
>
> I test it on kernel 2.2, it works fine. I experimentally commit this
> patch in cvs named as glibc23-getdents64-fix.dpatch. If no one
> objects, I send it to upstream and release -7 quickly. Any comments
> are welcome. Ben, Drow?
This looks right to me, please send it to libc-alpha.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
Reply to: