Date: Sun, 8 Nov 1998 14:47:20 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Re: lfn for dos In-Reply-To: <199811021631.LAA21792@indy.delorie.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 #include #include + #include + #include #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 #include #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 + #include #include #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 + #include #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