Skip site navigation (1)Skip section navigation (2)
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>