Mail Archives: djgpp-workers/1998/11/08/07:48:54
On Mon, 2 Nov 1998, DJ Delorie wrote:
> > This seems easy to fix inside `closedir'. Should I?
>
> If you like.
As usual, there were more to this than met the eye ;-). It turned out
we leak not one, but two handles, the additional one from that
findfirst that checks whether "." is reported in root diectories. In
addition, `rewinddir' adds yet another handle to the lossage, and it
doesn't repeat that magic which fakes the "." and ".." entries when
necessary...
Here's a patch that should settle all this mess:
*** src/libc/posix/dirent/opendir.c~0 Sun Aug 31 13:56:34 1997
--- src/libc/posix/dirent/opendir.c Sat Nov 7 13:44:02 1998
***************
*** 11,18 ****
--- 11,52 ----
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
+ #include <libc/dosio.h>
+ #include <dpmi.h>
#include "dirstruc.h"
+ void
+ _lfn_find_close(int handle)
+ {
+ __dpmi_regs r;
+
+ r.x.bx = handle;
+ r.x.ax = 0x71a1;
+ __dpmi_int(0x21, &r);
+ if (r.x.flags & 1)
+ {
+ errno = __doserr_to_errno(r.x.ax);
+ }
+ }
+
+ 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);
+ dir->ff.lfn_handle = 0;
+ }
+ }
+ }
+
DIR *
opendir(const char *name)
{
*************** opendir(const char *name)
*** 67,80 ****
/* 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;
}
--- 101,107 ----
/* 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 */
! __set_need_fake_dot_dotdot(dir);
return dir;
}
*** src/libc/posix/dirent/closedir.c~0 Mon Dec 26 15:50:52 1994
--- src/libc/posix/dirent/closedir.c Sat Nov 7 13:44:38 1998
***************
*** 1,12 ****
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <stdlib.h>
#include <dirent.h>
#include "dirstruc.h"
int
closedir(DIR *dir)
{
free(dir->name);
free(dir);
! return 0;
}
--- 1,23 ----
+ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <stdlib.h>
+ #include <errno.h>
#include <dirent.h>
#include "dirstruc.h"
int
closedir(DIR *dir)
{
+ int retval = 0;
+ int e = errno;
+
+ errno = 0;
+ rewinddir(dir); /* under LFN this closes the search handle */
+ if (errno == 0)
+ errno = e;
+ else
+ retval = -1;
free(dir->name);
free(dir);
! return retval;
}
*** src/libc/posix/dirent/rewinddi.c~0 Mon Dec 26 15:50:34 1994
--- src/libc/posix/dirent/rewinddi.c Sat Nov 7 13:33:24 1998
***************
*** 1,9 ****
--- 1,21 ----
+ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <dirent.h>
+ #include <fcntl.h>
#include "dirstruc.h"
void
rewinddir(DIR *dir)
{
+ /* If we are using LFN-aware functions, close the handle used by
+ Windows 9X during the search (readdir will open a new one). */
+ if (_USE_LFN && dir->ff.lfn_handle)
+ {
+ _lfn_find_close(dir->ff.lfn_handle);
+ dir->ff.lfn_handle = 0; /* 0 means it's closed */
+ }
+
+ /* Recompute need_fake_dot_dotdot member. See comments in opendir.c. */
+ __set_need_fake_dot_dotdot(dir);
dir->num_read = 0;
}
*** include/dirent.h~1 Sat Nov 7 12:35:26 1998
--- include/dirent.h Sat Nov 7 13:33:32 1998
***************
*** 34,39 ****
--- 34,41 ----
void seekdir(DIR *_dir, long _loc);
long telldir(DIR *_dir);
+ void __set_need_fake_dot_dotdot(DIR *_dir);
+ void _lfn_find_close(int _handle);
#endif /* !_POSIX_SOURCE */
#endif /* !__STRICT_ANSI__ */
*** src/docs/kb/wc202.t~1 Sat Nov 7 12:43:02 1998
--- src/docs/kb/wc202.txi Sat Nov 7 13:54:40 1998
***************
*** 485,487 ****
--- 485,497 ----
files/directories from the search.
@findex opendir
@findex readdir
+
+ @code{opendir}, @code{closedir} and @code{rewinddir} don't lose search
+ handles anymore when long file names are supported. @code{rewinddir}
+ and @code{seekdir} will not miss the (possibly faked) @file{.} and
+ @file{..} entries in root directories.
+ @findex opendir, does not lose search handles
+ @findex closedir, does not lose search handles
+ @findex rewinddir, does not lose search handles
+ @findex seekdir, and @file{.} and @file{..} entries
+ @findex rewinddir, and @file{.} and @file{..} entries
- Raw text -