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  <[EMAIL PROTECTED]>
        
        * 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?

s390x issue is another -6 problem. Is this OK already? If not, we have
to resolve ASAP. Gerhard, Jeff?

-- gotom


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to