* 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.
This commit is contained in:
Corinna Vinschen 2007-07-09 17:02:37 +00:00
parent bffcbe34be
commit 281bd334ac
5 changed files with 83 additions and 82 deletions

View File

@ -1,3 +1,19 @@
2007-07-09 Corinna Vinschen <corinna@vinschen.de>
* 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 <me+cygwin@cgf.cx>
* Makefile.in (DLL_OFILES): Add newly-imported random.o. Eliminate

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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 ());