From 281bd334ac254ee5b9c875f55980444069489395 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 9 Jul 2007 17:02:37 +0000 Subject: [PATCH] * dir.cc (closedir): Revert change from 2007-06-29. * fhandler.h (dirent_valid_fd): Drop. * fhandler_disk_file.cc (fhandler_disk_file::opendir): If opening a real dir, use the underlying fhandler to keep track of the directory handle. In fdopendir case use original io_handle from fhandler. Use fhandler's io_handle in subsequent directory functions throughout. Create handle non-inheritable and set close-on-exec flag. (readdir_get_ino): Drop dirent_isroot case. (fhandler_disk_file::readdir): Handle dirent_isroot case here. (fhandler_disk_file::rewinddir): Revert change from 2007-07-05. Use NtClose instead of CloseHandle. * fhandler_virtual.cc (fhandler_virtual::opendir): Drop adding dirent_valid_fd flag. Set close-on-exec flag. --- winsup/cygwin/ChangeLog | 16 ++++ winsup/cygwin/dir.cc | 6 +- winsup/cygwin/fhandler.h | 3 +- winsup/cygwin/fhandler_disk_file.cc | 138 +++++++++++++--------------- winsup/cygwin/fhandler_virtual.cc | 2 +- 5 files changed, 83 insertions(+), 82 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3be55cd30..26cae0977 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2007-07-09 Corinna Vinschen + + * dir.cc (closedir): Revert change from 2007-06-29. + * fhandler.h (dirent_valid_fd): Drop. + * fhandler_disk_file.cc (fhandler_disk_file::opendir): If opening a + real dir, use the underlying fhandler to keep track of the directory + handle. In fdopendir case use original io_handle from fhandler. Use + fhandler's io_handle in subsequent directory functions throughout. + Create handle non-inheritable and set close-on-exec flag. + (readdir_get_ino): Drop dirent_isroot case. + (fhandler_disk_file::readdir): Handle dirent_isroot case here. + (fhandler_disk_file::rewinddir): Revert change from 2007-07-05. Use + NtClose instead of CloseHandle. + * fhandler_virtual.cc (fhandler_virtual::opendir): Drop adding + dirent_valid_fd flag. Set close-on-exec flag. + 2007-07-08 Christopher Faylor * Makefile.in (DLL_OFILES): Add newly-imported random.o. Eliminate diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 2ce0488c5..822a5e5fe 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -260,11 +260,7 @@ closedir (DIR *dir) int res = ((fhandler_base *) dir->__fh)->closedir (dir); - /* 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); + cygheap->fdtab.release (dir->__d_fd); free (dir->__d_dirname); free (dir->__d_dirent); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 79c9c3da6..996f361cc 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -52,10 +52,9 @@ enum dirent_states dirent_isroot = 0x0008, dirent_set_d_ino = 0x0010, dirent_get_d_ino = 0x0020, - dirent_valid_fd = 0x0040, /* Global flags which must not be deleted on rewinddir or seekdir. */ - dirent_info_mask = 0x0078 + dirent_info_mask = 0x0038 }; enum conn_state diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index a4fe0b325..34d95bc6b 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1566,42 +1566,35 @@ fhandler_disk_file::opendir (int fd) dir->__d_internal = (unsigned) new __DIR_mounts (pc.normalized_path); d_cachepos (dir) = 0; - if (!pc.iscygdrive ()) + if (pc.iscygdrive ()) + cfd->nohandle (true); + else { - OBJECT_ATTRIBUTES attr; - 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; - - if (fd >= 0 && get_handle ()) - { - /* fdopendir() case. Just initialize with the emtpy upath - and reuse the exisiting handle. */ - InitializeObjectAttributes (&attr, &upath, - OBJ_CASE_INSENSITIVE | OBJ_INHERIT, - get_handle (), NULL); - } - else + if (fd < 0) { /* opendir() case. Initialize with given directory name and NULL directory handle. */ + OBJECT_ATTRIBUTES attr; + 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, + InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, sa.lpSecurityDescriptor); - } - status = NtOpenFile (&dir->__handle, - SYNCHRONIZE | FILE_LIST_DIRECTORY, - &attr, &io, FILE_SHARE_VALID_FLAGS, - FILE_SYNCHRONOUS_IO_NONALERT - | FILE_OPEN_FOR_BACKUP_INTENT - | FILE_DIRECTORY_FILE); - if (!NT_SUCCESS (status)) - { - __seterrno_from_nt_status (status); - goto free_mounts; + status = NtOpenFile (&get_handle (), + SYNCHRONIZE | FILE_LIST_DIRECTORY, + &attr, &io, FILE_SHARE_VALID_FLAGS, + FILE_SYNCHRONOUS_IO_NONALERT + | FILE_OPEN_FOR_BACKUP_INTENT + | FILE_DIRECTORY_FILE); + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + goto free_mounts; + } } /* FileIdBothDirectoryInformation is apparently unsupported on @@ -1620,10 +1613,7 @@ fhandler_disk_file::opendir (int fd) } } if (fd >= 0) - { - dir->__flags |= dirent_valid_fd; - dir->__d_fd = fd; - } + dir->__d_fd = fd; else { /* Filling cfd with `this' (aka storing this in the file @@ -1632,9 +1622,9 @@ fhandler_disk_file::opendir (int fd) fhandler twice, once in opendir() in dir.cc, the second time on exit. Nasty, nasty... */ cfd = this; - cfd->nohandle (true); dir->__d_fd = cfd; } + set_close_on_exec (true); dir->__fh = this; res = dir; } @@ -1717,31 +1707,26 @@ readdir_get_ino (DIR *dir, const char *path, bool dot_dot) HANDLE hdl; __ino64_t ino = 0; - if (!(dir->__flags & dirent_isroot)) + strcpy (fname, path); + if (dot_dot) + strcat (fname, (*fname && fname[strlen (fname) - 1] == '/') + ? ".." : "/.."); + path_conv pc (fname, PC_SYM_NOFOLLOW); + if (pc.isspecial ()) { - strcpy (fname, path); - if (dot_dot) - strcat (fname, (*fname && fname[strlen (fname) - 1] == '/') - ? ".." : "/.."); - path_conv pc (fname, PC_SYM_NOFOLLOW); - if (pc.isspecial ()) - { - if (!lstat64 (fname, &st)) - ino = st.st_ino; - } - else if (!pc.hasgood_inode ()) - ino = hash_path_name (0, pc); - else if ((hdl = CreateFile (pc, GENERIC_READ, FILE_SHARE_VALID_FLAGS, - NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL)) - != INVALID_HANDLE_VALUE) - { - ino = readdir_get_ino_by_handle (hdl); - CloseHandle (hdl); - } + if (!lstat64 (fname, &st)) + ino = st.st_ino; + } + else if (!pc.hasgood_inode ()) + ino = hash_path_name (0, pc); + else if ((hdl = CreateFile (pc, GENERIC_READ, FILE_SHARE_VALID_FLAGS, + NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL)) + != INVALID_HANDLE_VALUE) + { + ino = readdir_get_ino_by_handle (hdl); + CloseHandle (hdl); } - else - ino = readdir_get_ino_by_handle (dir->__handle); return ino; } @@ -1761,7 +1746,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de) { if ((dir->__flags & dirent_get_d_ino)) { - status = NtQueryDirectoryFile (dir->__handle, NULL, NULL, 0, &io, + status = NtQueryDirectoryFile (get_handle (), NULL, NULL, 0, &io, d_cache (dir), DIR_BUF_SIZE, FileIdBothDirectoryInformation, FALSE, NULL, dir->__d_position == 0); @@ -1804,7 +1789,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de) { if (d_cachepos (dir) == 0) { - status = NtQueryDirectoryFile (dir->__handle, NULL, NULL, + status = NtQueryDirectoryFile (get_handle (), NULL, NULL, 0, &io, d_cache (dir), DIR_BUF_SIZE, FileBothDirectoryInformation, FALSE, NULL, cnt == 0); @@ -1822,7 +1807,7 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de) } } if (!(dir->__flags & dirent_get_d_ino)) - status = NtQueryDirectoryFile (dir->__handle, NULL, NULL, 0, &io, + status = NtQueryDirectoryFile (get_handle (), NULL, NULL, 0, &io, d_cache (dir), DIR_BUF_SIZE, FileBothDirectoryInformation, FALSE, NULL, dir->__d_position == 0); @@ -1857,17 +1842,20 @@ go_ahead: if (dir->__d_position == 0 && buf->FileNameLength == 2 && FileName[0] == '.') - de->d_ino = readdir_get_ino_by_handle (dir->__handle); + de->d_ino = readdir_get_ino_by_handle (get_handle ()); else if (dir->__d_position == 1 && buf->FileNameLength == 4 && FileName[0] == '.' && FileName[1] == '.') - de->d_ino = readdir_get_ino (dir, pc.normalized_path, true); + if (!(dir->__flags & dirent_isroot)) + de->d_ino = readdir_get_ino (dir, pc.normalized_path, true); + else + de->d_ino = readdir_get_ino_by_handle (get_handle ()); else { HANDLE hdl; UNICODE_STRING upath = {buf->FileNameLength, CYG_MAX_PATH * 2, FileName}; InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, - dir->__handle , NULL); + get_handle () , NULL); if (!NtOpenFile (&hdl, READ_CONTROL, &attr, &io, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT)) @@ -1891,7 +1879,7 @@ go_ahead: else if (!(dir->__flags & dirent_saw_dot)) { strcpy (de->d_name , "."); - de->d_ino = readdir_get_ino_by_handle (dir->__handle); + de->d_ino = readdir_get_ino_by_handle (get_handle ()); dir->__d_position++; dir->__flags |= dirent_saw_dot; res = 0; @@ -1899,7 +1887,10 @@ go_ahead: else if (!(dir->__flags & dirent_saw_dot_dot)) { strcpy (de->d_name , ".."); - de->d_ino = readdir_get_ino (dir, pc.normalized_path, true); + if (!(dir->__flags & dirent_isroot)) + de->d_ino = readdir_get_ino (dir, pc.normalized_path, true); + else + de->d_ino = readdir_get_ino_by_handle (get_handle ()); dir->__d_position++; dir->__flags |= dirent_saw_dot_dot; res = 0; @@ -1940,9 +1931,8 @@ fhandler_disk_file::rewinddir (DIR *dir) IO_STATUS_BLOCK io; HANDLE new_dir; - InitializeObjectAttributes (&attr, &fname, - OBJ_CASE_INSENSITIVE | OBJ_INHERIT, - dir->__handle, NULL); + InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE, + get_handle (), NULL); status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT @@ -1954,8 +1944,8 @@ fhandler_disk_file::rewinddir (DIR *dir) RtlNtStatusToDosError (status)); else { - CloseHandle (dir->__handle); - dir->__handle = new_dir; + NtClose (get_handle ()); + set_io_handle (new_dir); } } dir->__d_position = 0; @@ -1969,14 +1959,14 @@ fhandler_disk_file::closedir (DIR *dir) NTSTATUS status; delete d_mounts (dir); - if (!dir->__handle) + if (!get_handle ()) /* ignore */; - else if (dir->__handle == INVALID_HANDLE_VALUE) + else if (get_handle () == INVALID_HANDLE_VALUE) { set_errno (EBADF); res = -1; } - else if (!NT_SUCCESS (status = NtClose (dir->__handle))) + else if (!NT_SUCCESS (status = NtClose (get_handle ()))) { __seterrno_from_nt_status (status); res = -1; diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index f5a9f7eeb..4db2cf726 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -80,7 +80,6 @@ fhandler_virtual::opendir (int fd) if (fd >= 0) { - dir->__flags |= dirent_valid_fd; dir->__d_fd = fd; res = dir; dir->__fh = this; @@ -98,6 +97,7 @@ fhandler_virtual::opendir (int fd) res = dir; } } + close_on_exec (true); } syscall_printf ("%p = opendir (%s)", res, get_name ());