Mail Archives: djgpp-workers/2001/05/07/05:52:50
Hello.
Eli Zaretskii wrote:
>
> On Mon, 7 May 2001, Richard Dawe wrote:
> > Debugging libc I see that rewinddir() calls
> > __set_need_fake_dot_dotdot().
> > __set_need_fake_dot_dotdot() calls findfirst(). On a floppy with no
> > files findfirst() fails, returing ENOENT. Hence
> > __set_need_fake_dot_dotdot() sets errno. It seems to me that it should
> > not set errno.
>
> I think it should know about ENOENT and ENMFILE, and if that's what
> errno gets after findfirst, __set_need_fake_dot_dotdot should restore
> the previous value of errno. But if findfirst comes with some other
> errno, like EACCES, it should let it be.
OK, that's what I've implemented. It seems to fix the problem on Win98 SE.
Please find below a patch that will apply to 2.03 or CVS version of
src/libc/posix/dirent/opendir.c. I rebuilt ls with a patched version of
opendir.c and put it here:
http://www.phekda.freeserve.co.uk/richdawe/djgpp/fileutils/
The file is ls.exe.gz.
Eli, would it be possible to try this out on DOS 5 please, when you have
time? I'd be grateful. Presumably the error ENMFILE is generated under
plain DOS, whereas ENOENT is generated when you have LFN support?
If the patch is OK, shall I commit it to CVS?
> If this turns to be the solution, please put the modifed library
> sources into the djgpp subdirectory, and add the appropriate text to
> the README, so that people could build binaries without bugs.
Yep, I will do that.
> Thanks for debugging this.
You're welcome!
Bye, Rich =]
--
Richard Dawe
http://www.phekda.freeserve.co.uk/richdawe/
*** /develop/djgpp/src/libc/posix/dirent/opendir.c Tue Aug 22
19:38:04 2000
--- /develop/ports/gnu.dev/filutil4.0/djgpp/opendir.c.latest Mon May 7
10:34:56 2001
***************
*** 36,48 ****
void
__set_need_fake_dot_dotdot(DIR *dir)
{
dir->need_fake_dot_dotdot = 0;
if (strlen(dir->name) == 6) /* "d:/" + "*.*" */
! {
/* 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;
if (_USE_LFN && dir->ff.lfn_handle)
{
_lfn_find_close(dir->ff.lfn_handle);
--- 36,59 ----
void
__set_need_fake_dot_dotdot(DIR *dir)
{
+ int oerrno = errno;
+
dir->need_fake_dot_dotdot = 0;
if (strlen(dir->name) == 6) /* "d:/" + "*.*" */
! {
/* 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;
+
+ /* Restore errno in certain cases. findfirst() will fail for empty
+ * root directories on drives, but this should not be considered
+ * an error. */
+ if ((errno == ENOENT) || (errno == ENMFILE))
+ errno = oerrno;
+ }
+
if (_USE_LFN && dir->ff.lfn_handle)
{
_lfn_find_close(dir->ff.lfn_handle);
- Raw text -