NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/44722



The following reply was made to PR bin/44722; it has been noted by GNATS.

From: Alan Barrett <apb%cequrux.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: bin/44722
Date: Sun, 18 Sep 2011 11:55:31 +0200

 > With a low file descriptor limit ls lists the contents of
 > subdirectories instead of the current directory.
 
 I can replicate this.  It's difficult to debug, because if you make
 the file descriptor limit low enough to exhibit the problem, then gdb
 doesn't work properly.
 
 You can simulate the prioblem by making the __opendir2 call in line
 654 of ftc.s fail on the first call and succeed on the second call, as
 follows:
 
 cd src/bin/ls ;
 cp ../../lib/libc/gen/fts.c ./fts.c ;
 patch ./fts.c <<'ENDPATCH'
 --- ../../lib/libc/gen/fts.c
 +++ ./fts.c
 @@ -42,7 +42,6 @@
   #endif
   #endif /* LIBC_SCCS and not lint */
   
 -#include "namespace.h"
   #include <sys/param.h>
   #include <sys/stat.h>
   
 @@ -651,7 +650,17 @@
   #else
   #define      __opendir2(path, flag) opendir(path)
   #endif
 -      if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
 +      {
 +              static int ncalls = 0;
 +
 +              if (++ncalls == 1) {
 +                      errno = EMFILE;
 +                      dirp = NULL;
 +              } else {
 +                      dirp = __opendir2(cur->fts_accpath, oflag);
 +              }
 +      }
 +      if (dirp == NULL) {
                if (type == BREAD) {
                        cur->fts_info = FTS_DNR;
                        cur->fts_errno = errno;
 ENDPATCH
 patch ./Makefile <<'ENDPATCH'
 --- Makefile
 +++ Makefile
 @@ -2,7 +2,9 @@
   #      @(#)Makefile    8.1 (Berkeley) 6/2/93
   
   PROG=  ls
 -SRCS=  cmp.c ls.c main.c print.c util.c
 +SRCS=  cmp.c ls.c main.c print.c util.c fts.c
 +
 +COPTS= -O0 -g
   
   LDADD+=        -lutil
   DPADD+=        ${LIBUTIL}
 ENDPATCH
 
 Now you can build a modified version of ls, and use gdb to debug it.
 
 The call to fts_children() in line 417 of the traverse() function in
 ls.c returns NULL.
 
 The comment in lines 496 to 502 of ls.c says "We ignore the error case
 since it will be replicated on the next call to fts_read()", but in
 fact the error case is not replicated later.
 
 The test in line 503 of the display() function in ls.c just returns.
 
 The loop beginning lin line 429 of the traverse() function in ls.c
 ends up printing the wrong information.
 
 It's certainly wrong to assume that the same error will occur twice,
 but it's not yet clear to me whether the bug is in fts_read() or in
 traverse() or in display().
 
 Perhaps fts_read() should have noticed the "cur->fts_info = FTS_DNR"
 status that was stored by the earlier fts_build() (line 665 of the
 patched fts.c).
 
 Perhaps traverse() should have noticed the error return from
 fts_children() in line 417 of ls.c, and should have reported the error
 without performing the fts_read() loop in line 429 of ls.c.
 
 Perhaps display() should have reported the error before returning in
 line 504 of ls.c.
 
 --apb (Alan Barrett)
 


Home | Main Index | Thread Index | Old Index