From 40570a828e0ed00cf570a2d7fa41ddae887c1367 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 29 Jun 2007 15:13:01 +0000 Subject: * cygwin.din: Export fdopendir. * dir.cc (opendir): Call fhandler's opendir with fd set to -1. (fdopendir): New function. (seekdir64): Use dirent_info_mask. (rewinddir): Ditto. (closedir): Only release underlying file descriptor if it has been reserved by opendir itself. * fhandler.cc (fhandler_base::opendir): Accommodate new parameter. * fhandler.h (dirent_states): Add dirent_valid_fd and dirent_info_mask. (fhander_XXX::opendir): Add file descriptor parameter. Use regparms. (fhandler_procnet::opendir): Drop declaration. * fhandler_disk_file.cc (fhandler_disk_file::opendir): Ditto. If called from fdopendir, use existing handle to re-open directory with valid flags. Rename fd to cfd. Use only if no valid incoming fd. (fhandler_cygdrive::opendir): Accommodate new parameter. * fhandler_process.cc (fhandler_process::opendir): Ditto. * fhandler_procnet.cc (fhandler_procnet::opendir): Drop definition. * fhandler_virtual.cc (fhandler_virtual::opendir): Accommodate new parameter. Only create new file descriptor entry if called from opendir. Remove duplicated setting of dir->__flags. * posix.sgml: Add fdopendir to list of implemented Solaris functions. * include/cygwin/version.h: Bump API minor number. * include/sys/dirent.h: Declare fdopendir. --- winsup/cygwin/dir.cc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'winsup/cygwin/dir.cc') diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 3d0dbae7b..2ce0488c5 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -61,7 +61,7 @@ opendir (const char *name) if (!fh) res = NULL; else if (fh->exists ()) - res = fh->opendir (); + res = fh->opendir (-1); else { set_errno (ENOENT); @@ -73,6 +73,17 @@ opendir (const char *name) return res; } +extern "C" DIR * +fdopendir (int fd) +{ + DIR *res = NULL; + + cygheap_fdget cfd (fd); + if (cfd >= 0) + res = cfd->opendir (fd); + return res; +} + static int readdir_worker (DIR *dir, dirent *de) { @@ -204,7 +215,7 @@ seekdir64 (DIR *dir, _off64_t loc) if (dir->__d_cookie != __DIRENT_COOKIE) return; - dir->__flags &= (dirent_isroot | dirent_get_d_ino | dirent_set_d_ino); + dir->__flags &= dirent_info_mask; return ((fhandler_base *) dir->__fh)->seekdir (dir, loc); } @@ -225,7 +236,7 @@ rewinddir (DIR *dir) if (dir->__d_cookie != __DIRENT_COOKIE) return; - dir->__flags &= (dirent_isroot | dirent_get_d_ino | dirent_set_d_ino); + dir->__flags &= dirent_info_mask; return ((fhandler_base *) dir->__fh)->rewinddir (dir); } @@ -249,7 +260,11 @@ closedir (DIR *dir) int res = ((fhandler_base *) dir->__fh)->closedir (dir); - cygheap->fdtab.release (dir->__d_fd); + /* If the directory has been opened by fdopendir, the descriptor + entry is used elsewhere in the application and must not be removed + from the descriptor table. */ + if (!(dir->__flags & dirent_valid_fd)) + cygheap->fdtab.release (dir->__d_fd); free (dir->__d_dirname); free (dir->__d_dirent); -- cgit v1.2.3