Date: Wed, 11 Sep 1996 22:31:07 -0400 From: dj (DJ Delorie) Message-Id: <199609120231.WAA17793@delorie.com> To: djgpp-workers Subject: readdir & / I applied this patch to make readdir() return entries for "." and ".." even for root directories. The fact that it didn't use to cost me a few CDR blanks, because mkisofs requires this behavior. Comments? Is there ever a case where opendir("/") returns "." and ".." on its own? If so, any reason why calling findfirst an extra time (to see if "." is returned) would be a bad thing? DJ diff -c3 -r src/libc/posix/dirent/dirstruc.h /v2/src/libc/posix/dirent/dirstruc.h *** src/libc/posix/dirent/dirstruc.h Tue Dec 20 03:12:42 1994 --- /v2/src/libc/posix/dirent/dirstruc.h Wed Sep 11 22:23:52 1996 *************** *** 7,10 **** --- 7,11 ---- int flags; struct ffblk ff; struct dirent de; + int need_fake_dot_dotdot; /* 0=no, 1=.., 2=. */ }; diff -c3 -r src/libc/posix/dirent/opendir.c /v2/src/libc/posix/dirent/opendir.c *** src/libc/posix/dirent/opendir.c Sat Aug 31 21:09:32 1996 --- /v2/src/libc/posix/dirent/opendir.c Wed Sep 11 22:27:00 1996 *************** *** 34,39 **** --- 34,46 ---- /* Make absolute path */ _fixpath(name, dir->name); + /* If we're doing opendir of the root directory, we need to + fake out the . and .. entries, as some unix programs (like + mkisofs) expect them and fail if they don't exist */ + dir->need_fake_dot_dotdot = 0; + if (dir->name[1] == ':' && dir->name[2] == '/' && dir->name[3] == 0) + dir->need_fake_dot_dotdot = 2; + /* Ensure that directory to be accessed exists */ if (access(dir->name, D_OK)) { diff -c3 -r src/libc/posix/dirent/readdir.c /v2/src/libc/posix/dirent/readdir.c *** src/libc/posix/dirent/readdir.c Sat Aug 31 21:09:32 1996 --- /v2/src/libc/posix/dirent/readdir.c Wed Sep 11 22:28:54 1996 *************** *** 12,17 **** --- 12,30 ---- { int done; int oerrno = errno; + + if (dir->need_fake_dot_dotdot) + { + /* Fake out . and .. on /; see opendir for comments */ + dir->need_fake_dot_dotdot --; + if (dir->need_fake_dot_dotdot) + strcpy(dir->de.d_name, "."); + else + strcpy(dir->de.d_name, ".."); + dir->de.d_namlen = strlen(dir->de.d_name); + return &(dir->de); + } + if (dir->num_read) done = findnext(&dir->ff); else