Date: Tue, 26 Dec 2000 18:49:33 +0200 From: "Eli Zaretskii" 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" To: "Eli Zaretskii" 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: 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 -------