Mail Archives: djgpp-workers/2000/12/26/12:26:05
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 -