Date: Tue, 5 Dec 2000 11:16:54 -0800 (PST) From: Jim.Pirzyk@disney.com To: FreeBSD-gnats-submit@freebsd.org Subject: bin/23300: make assumes readdir return '.' and '..' first Message-ID: <200012051916.eB5JGr169436@snoopy.fan.fa.disney.com> Resent-Message-ID: <200012051920.eB5JK2h13241@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 23300 >Category: bin >Synopsis: make assumes readdir returns '.' and '..' for the first two calls. >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Dec 05 11:20:02 PST 2000 >Closed-Date: >Last-Modified: >Originator: Jim Pirzyk >Release: FreeBSD 4.2-RELEASE i386 >Organization: >Environment: the /usr/src tree mounted over NFS from an SGI IRIX server running XFS. >Description: The readdir on a specific NFS dir will not return '.' and '..' as the first entries. Make assumes that the first two calls to readdir will return those. The make fails because it cannot find the file 'S' (which is returned second, see below) >How-To-Repeat: Running this short C program shows that '.' and '..' are not the first two entries returned by readdir. --- listdir.c --- #include <stdio.h> #include <sys/types.h> #include <dirent.h> void main (int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) { (void)list_files (argv[i]); } } void list_files (char *dir) { DIR *d = opendir (dir); struct dirent *dp; if ( d ) { while (dp=readdir(d)) { printf ("%s\n", dp->d_name); } } else { printf ("Could not open %s\n", dir); } closedir(dir); } --- output from listdir (run by ./listdir /usr/src/contrib/groff/devX100 ) --- . S .. CB CI CR HB HI HR NB NI NR TB TI TR CBI HBI NBI TBI DESC >Fix: *** ./usr.bin/make/dir.c.orig Tue Dec 5 10:54:57 2000 --- ./usr.bin/make/dir.c Tue Dec 5 11:05:40 2000 *************** *** 1060,1067 **** --- 1060,1069 ---- /* * Skip the first two entries -- these will *always* be . and .. */ + /* (void)readdir(d); (void)readdir(d); + */ while ((dp = readdir (d)) != (struct dirent *) NULL) { #if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */ *************** *** 1074,1079 **** --- 1076,1093 ---- continue; } #endif /* sun && d_ino */ + + /* + * Skip the '.' and '..' entries, XFS over NFS filesystems + * since SGI does not guarentee that '.' and '..' are the + * first two entries returned from readdir(). + */ + if (dp->d_name[0] == '.' && + (dp->d_name[1] == NULL || + (dp->d_name[1] == '.' && dp->d_name[2] == NULL))) { + continue; + } + (void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL); } (void) closedir (d); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200012051916.eB5JGr169436>