diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-06-29 15:13:01 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-06-29 15:13:01 +0000 |
commit | 40570a828e0ed00cf570a2d7fa41ddae887c1367 (patch) | |
tree | 86f1a9e5322b57c1b2567a1e85b308e0ff932816 /winsup/cygwin/fhandler_disk_file.cc | |
parent | 8931495a1417c7dc1b6c56d0120efb40a1fa030b (diff) | |
download | cygnal-40570a828e0ed00cf570a2d7fa41ddae887c1367.tar.gz cygnal-40570a828e0ed00cf570a2d7fa41ddae887c1367.tar.bz2 cygnal-40570a828e0ed00cf570a2d7fa41ddae887c1367.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 353c45ba5..d693a9ddb 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1514,7 +1514,7 @@ struct __DIR_cache #define d_mounts(d) ((__DIR_mounts *) (d)->__d_internal) DIR * -fhandler_disk_file::opendir () +fhandler_disk_file::opendir (int fd) { DIR *dir; DIR *res = NULL; @@ -1542,9 +1542,9 @@ fhandler_disk_file::opendir () { strcpy (d_dirname (dir), get_win32_name ()); dir->__d_dirent->__d_version = __DIRENT_VERSION; - cygheap_fdnew fd; + cygheap_fdnew cfd; - if (fd < 0) + if (cfd < 0 && fd < 0) goto free_dirent; /* FindFirstFile doesn't seem to like duplicate /'s. @@ -1569,15 +1569,28 @@ fhandler_disk_file::opendir () if (!pc.iscygdrive ()) { OBJECT_ATTRIBUTES attr; - WCHAR wpath[CYG_MAX_PATH + 10]; - UNICODE_STRING upath = {0, sizeof (wpath), wpath}; - IO_STATUS_BLOCK io; NTSTATUS status; + IO_STATUS_BLOCK io; + WCHAR wpath[CYG_MAX_PATH + 10] = { 0 }; + UNICODE_STRING upath = {0, sizeof (wpath), wpath}; SECURITY_ATTRIBUTES sa = sec_none; - pc.get_nt_native_path (upath); - InitializeObjectAttributes (&attr, &upath, - OBJ_CASE_INSENSITIVE | OBJ_INHERIT, - NULL, sa.lpSecurityDescriptor); + + if (fd >= 0 && get_handle ()) + { + /* fdopendir() case. Just initialize with the emtpy upath + and reuse the exisiting handle. */ + InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, + get_handle (), NULL); + } + else + { + /* opendir() case. Initialize with given directory name and + NULL directory handle. */ + pc.get_nt_native_path (upath); + InitializeObjectAttributes (&attr, &upath, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + NULL, sa.lpSecurityDescriptor); + } status = NtOpenFile (&dir->__handle, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_VALID_FLAGS, @@ -1605,13 +1618,22 @@ fhandler_disk_file::opendir () dir->__flags |= dirent_get_d_ino; } } - /* Filling fd with `this' (aka storing this in the file descriptor table - should only happen after it's clear that opendir doesn't fail, - otherwise we end up cfree'ing the fhandler twice, once in opendir() - in dir.cc, the second time on exit. Nasty, nasty... */ - fd = this; - fd->nohandle (true); - dir->__d_fd = fd; + if (fd >= 0) + { + dir->__flags |= dirent_valid_fd; + dir->__d_fd = fd; + } + else + { + /* Filling cfd with `this' (aka storing this in the file + descriptor table should only happen after it's clear that + opendir doesn't fail, otherwise we end up cfree'ing the + fhandler twice, once in opendir() in dir.cc, the second + time on exit. Nasty, nasty... */ + cfd = this; + cfd->nohandle (true); + dir->__d_fd = cfd; + } dir->__fh = this; res = dir; } @@ -2011,11 +2033,11 @@ fhandler_cygdrive::fstat (struct __stat64 *buf) } DIR * -fhandler_cygdrive::opendir () +fhandler_cygdrive::opendir (int fd) { DIR *dir; - dir = fhandler_disk_file::opendir (); + dir = fhandler_disk_file::opendir (fd); if (dir && !ndrives) set_drives (); |