delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/12/26/12:26:05

Date: Tue, 26 Dec 2000 18:49:33 +0200
From: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
Sender: halo1 AT zahav DOT net DOT il
To: djgpp-workers AT delorie DOT com
Message-Id: <7263-Tue26Dec2000184932+0200-eliz@is.elta.co.il>
X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: RE: Draft patch for opendir() extension
Reply-To: djgpp-workers AT delorie DOT com

Tim asked me to forward this response to the list.

------- Start of forwarded message -------
From: "Tim Van Holder" <tim DOT van DOT holder AT pandora DOT be>
To: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
Subject: RE: Draft patch for opendir() extension
Date: Tue, 26 Dec 2000 11:39:30 +0100
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
In-Reply-To: <Pine DOT SUN DOT 3 DOT 91 DOT 1001226105119 DOT 28098B-100000 AT is>
Importance: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400
X-MIME-Autoconverted: from quoted-printable to 8bit by is.elta.co.il id MAA28980
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Length: 6220
X-Status: A

>  - Why would an application want to fake directory entries, and for
>    what kind of functionality?  Until now, we have been talking about
>    /dev/* pseudo-files only, which don't need such a general-purpose
>    mechanism.
Aside from the /dev stuff, which was indeed my main target (so ls /dev
would list them), I was thinking along the line of sockets - on Unix,
they're actual directory entries. With libsocket, also having them
appear as entries in the directory _might_ be useful. And there may
be other future uses (maybe DJGPP will support other special files
through fsext in the future).

> - In what kind of data structure(s) will the fake entries be stored?
Will depend on what info I'll need to keep. Probably a list or array
of structures containing a name and its associated fd(s).

>  - How would an application register and deregister entries in
>    practice?  In what directory (or directories) will those entries be
>    visible, and what API does an application need to control this?
An fsext_open hook would call register (name, fd). An fsext_close hook
would then deregister an entry by fd. No API should be required outside
of this.

> - Can fake entries be registered before an opendir call for their
>   parent directory?  Can they be deregistered before closedir is
>   called?
Yes, but that would not have an effect - the list of fake entries is
added to the DIR structure during opendir and is not changed.

> - Will the fake entries appear in the beginning or the end of the
>   real entries?
Currently the order is fake dots/fake entries/real entries.
It might be better to add them at the end, I suppose.

> - Why do we need to invent a special mechanism?  Isn't it enough to
>   define an __FSEXT_dir hook that would be called by all these
>   functions, in the same manner as __FSEXT_open hook is called by
>   _open?
I suppose this is a viable alternative, but this would require all
fsext functions to maintain their own list of faked entries, and do a
lookup to check for relevant entries. Using a separate mechanism allows
for a simple register/deregister call on their end, with all associated
management and lookup handled in a central location.

> > This patch also fixes a bug in telldir/seekdir.
> 
> Please don't mix patches for different problems together.  Please send
> the telldir patches separately.
Couldn't be done here, as the fix here relies on the rest of the changes.
A 'regular' patch is appended.

> Anyway, I'm not sure what is the bug you are trying to solve.  Can you
> give an example of a series of calls to opendir, readdir, telldir, and
> seekdir where the current implementation fails?
D = opendir ("/"); // has entries: foo, bar, hello, world and xyzzy
readdir (D); // '.'
readdir (D); // '..'
readdir (D); // 'foo'
readdir (D); // 'bar'
readdir (D); // 'hello'
readdir (D); // 'world'
pos = telldir(D); // pos gets 4, as that's the number of real entries read
seekdir (D, pos); // rewinds, calles readdir pos times
readdir (D); // should get 'xyzzy', but actually gets 'hello'

Whenever fake dots are added, telldir returns a bad value.

> > + char**
> > + __fsext_entries (const char* d)
> It is not clear why do you need this function.  Since the fake entries
> are stored in an array accessible from the DIR structure, what do you
> need __fsext_entries for?
The structure would store all faked entries. This function returns
a NULL-terminated array of the relevant names (i.e. those that live
in the directory being opened). I don't propose to make the list of
faked entries freely accessible, unless some other use makes this
desirable.

> Please explain the need for the `exists' member.
To know whether the directory only contains fake entries (so we
don't try running findfirst() on it).

> I also don't understand why do you need both fsext_entries and
> fsext_entry, since they both are used to index into the same array.
> Isn't num_read enough for that?
Actually, fsext_entries is an array of strings, fsext_entry is used
to index into it. Using num_read only would require also keeping the
number of strings in the fsext_entries array and then computing where
we were in the list.

> I don't understand this: why do you keep reporting data to the
> application if the directory doesn't exist?  This code is about fake
> directory entries, not about fake directories, isn't it?
> 
> Also, how is the fact that dir->fsext_entries is non-NULL relevant to
> whether the directory may or may not be non-existent?
Take the case of /dev. While you might have c:/dev, this is far from
certain. If an fsext supports /dev/zero, we want opendir ("/dev") to
list it. After all, we allow a stat() to succeed on it as well.

> What is the special meaning of dir->exists == 2?  If this is not a
> simple boolean variable, I think the name `exists' is inappropriate.
I know; this was a quick hack, as there was no good way to tell
whether findfirst() had already been called. So I reused the exists
variable I'd added. A new name would indeed be more appropriate.

== Start of patch for telldir/seekdir inconsistency ==
Index: readdir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/readdir.c,v
retrieving revision 1.3
diff -c -r1.3 readdir.c
*** readdir.c   1998/11/15 13:47:22     1.3
- --- readdir.c   2000/12/26 10:19:35
***************
*** 17,26 ****
    int oerrno = errno;
    int mbsize;

!   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
- --- 17,26 ----
    int oerrno = errno;
    int mbsize;

!   if (dir->num_read < dir->need_fake_dot_dotdot)
    {
      /* Fake out . and .. on /; see opendir for comments */
!     dir->num_read++;
      if (dir->need_fake_dot_dotdot)
        strcpy(dir->de.d_name, ".");
      else
***************
*** 29,35 ****
      return &(dir->de);
    }

!   if (dir->num_read)
      done = findnext(&dir->ff);
    else
    {
- --- 29,35 ----
      return &(dir->de);
    }

!   if (dir->num_read > dir->need_fake_dot_dotdot)
      done = findnext(&dir->ff);
    else
    {
------- End of forwarded message -------

- Raw text -


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