delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/11/05/01:02:35

Date: Tue, 5 Nov 1996 07:54:21 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: DJ Delorie <dj AT delorie DOT com>
Cc: robert DOT hoehne AT mathematik DOT tu-chemnitz DOT de, djgpp-workers AT delorie DOT com
Subject: Re: Problems with opendir() and glob()
In-Reply-To: <199611042344.SAA26450@delorie.com>
Message-Id: <Pine.SUN.3.91.961105073948.1570A-100000@is>
Mime-Version: 1.0

On Mon, 4 Nov 1996, DJ Delorie wrote:

> > subst drive, findfirst for "s:/" (if s is substed) does not
> > report "." but findfirst for "s:/*.*" reports ".". The result of
> > this is, when you do
> 
> Why would findfirst("s:/") return *anything*?  It's a directory, not a
> wildcard.

Robert have chosen an unclear wording IMHO.  The real problem as far as I
can see it is that `opendir' called findfirst("s:/") instead of
findfirst("s:/*.*") where it tried to see if "." is returned from the
directory.  It just happens that *real* root directories always fail
`findfirst', so this code worked.  But on a SUBSTed drive, `findfirst'
succeeds for the root directory, and that's where the bug became obvious. 
What Robert *meant* to say (I think) was that a call like findfirst("s:/")
succeeds but doesn't return a ".", and so `opendir' thinks it must fake
"." and "..", but then `readdir' also finds "." and ".." on its own, so
you get them twice. 

Btw: is it safe to assume that if a "." is found, then ".." will also be 
found, and that "." is always the first entry returned by `findfirst'?  
The original code did that, and I didn't change this in the patch below, 
but I wonder whether some network redirector could pull a trick on us.

Here's the fix (tested with `ls' on a SUBSTed drive):

*** src/libc/posix/dirent/opendir.c~0	Mon Nov  4 18:25:18 1996
--- src/libc/posix/dirent/opendir.c	Mon Nov  4 18:33:58 1996
***************
*** 34,51 ****
    /* 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)
-   {
-     /* see if findfirst finds "." anyway */
-     int done = findfirst(dir->name, &dir->ff, FA_ARCH|FA_RDONLY|FA_DIREC|FA_SYSTEM);
-     if (done || strcmp(dir->ff.ff_name, "."))
-       dir->need_fake_dot_dotdot = 2;
-   }
- 
    /* Ensure that directory to be accessed exists */
    if (access(dir->name, D_OK))
    {
--- 34,39 ----
***************
*** 69,79 ****
        break;
      }
    }
- 
    dir->name[length++] = '/';
    dir->name[length++] = '*';
    dir->name[length++] = '.';
    dir->name[length++] = '*';
    dir->name[length++] = 0;
    return dir;
  }
--- 57,79 ----
        break;
      }
    }
    dir->name[length++] = '/';
    dir->name[length++] = '*';
    dir->name[length++] = '.';
    dir->name[length++] = '*';
    dir->name[length++] = 0;
+ 
+   /* 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] == '/' && length == 7)
+   {
+     /* see if findfirst finds "." anyway */
+     if (findfirst(dir->name, &dir->ff, FA_ARCH|FA_RDONLY|FA_DIREC)
+ 	|| strcmp(dir->ff.ff_name, "."))
+       dir->need_fake_dot_dotdot = 2;
+   }
+ 
    return dir;
  }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019