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