delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/11/08/07:48:54

Date: Sun, 8 Nov 1998 14:47:20 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: DJ Delorie <dj AT delorie DOT com>
cc: djgpp-workers AT delorie DOT com
Subject: Re: lfn for dos
In-Reply-To: <199811021631.LAA21792@indy.delorie.com>
Message-ID: <Pine.SUN.3.91.981108144352.13039C-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

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 -


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