* autoload.cc (NtQueryDirectoryFile): Define.

* dir.cc (__opendir_with_d_ino): Just call opendir.
	(opendir): Remove CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO handling.
	(readdir_worker): Only try generating d_ino if it's 0.
	Utilize namehash of directories fhandler.  Call readdir_get_ino to
	generate d_ino for "..".
	(seekdir64): Keep dirent_set_d_ino flag.
	* fhandler.h (enum dirent_states): Add dirent_get_d_ino.
	(class fhandler_disk_file): Declare new private methods readdir_helper
	and readdir_9x.
	* fhandler_disk_file.cc (path_conv::hasgood_inode): New method to
	evaluate if a filesystem has reliable inode numbers.
	(fhandler_base::fstat_by_handle): Accomodate structure member name
	change from IndexNumber to FileId.
	(fhandler_base::fstat_helper): Call hasgood_inode here.
	(fhandler_disk_file::opendir): Call fhaccess only for real files.
	Don't append '*' to __d_dirname here, move to readdir_9x.  On NT,
	open directory handle here.  Set dirent_get_d_ino and dirent_set_d_ino
	flags according to wincap and filesystem.
	(fhandler_disk_file::readdir_helper): New method to implement readdir
	postprocessing only once.
	(readdir_get_ino_by_handle): New static function.
	(readdir_get_ino): New function to centralize inode number evaluation
	in case inode number hasn't been returned by NtQueryDirectoryFile.
	(fhandler_disk_file::readdir): Move old functionality to readdir_9x.
	Call readdir_9x when on 9x/Me.  Implement NT specific readdir here.
	(fhandler_disk_file::readdir_9x): Move 9x specific readdir here.
	(fhandler_disk_file::seekdir): Accomodate new NT readdir method.
	(fhandler_disk_file::closedir): Ditto.
	(fhandler_cygdrive::fstat): Set d_ino to namehash. Add comment.
	(fhandler_cygdrive::opendir): Call get_namehash to prepare later
	correct evaluation of d_ino.
	(fhandler_cygdrive::readdir): Replace recursion with loop. Evaluate
	drive's d_ino by calling readdir_get_ino.
	* fhandler_proc.cc (fhandler_proc::readdir): Set dirent_saw_dot and
	dirent_saw_dot_dot to avoid seeing . and .. entries twice.
	* fhandler_process.cc (fhandler_process::readdir): Ditto.
	* fhandler_registry.cc (fhandler_registry::readdir): Ditto.
	* ntdll.h (STATUS_INVALID_PARAMETER): New define.
	(STATUS_INVALID_LEVEL): New define.
	(struct _FILE_INTERNAL_INFORMATION): Rename member IndexNumber to
	FileId (as in Nebbitt).
	* path.h (path_conv::hasgood_inode): Now implemented in
	fhandler_disk_file.cc.
	* wincap.h (wincaps::has_fileid_dirinfo): New element.
	* wincap.cc: Implement above element throughout.
	* winsup.h (readdir_get_ino): Add declaration.
	* include/sys/dirent.h (struct dirent): Slightly rename structure
	members to accomodate changes.
	Remove __USE_EXPENSIVE_CYGWIN_D_INO handling and declaration of
	__opendir_with_d_ino.
This commit is contained in:
Corinna Vinschen
2006-01-27 21:50:42 +00:00
parent e7a9c71d62
commit 9e5f45ed6f
14 changed files with 474 additions and 204 deletions

View File

@@ -42,13 +42,12 @@ dirfd (DIR *dir)
return dir->__d_fd;
}
/* Symbol kept for backward compatibility. Don't remove. Don't declare
in public header file. */
extern "C" DIR *
__opendir_with_d_ino (const char *name)
{
DIR *res = opendir (name);
if (res)
res->__flags |= dirent_set_d_ino;
return res;
return opendir (name);
}
/* opendir: POSIX 5.1.2.1 */
@@ -69,9 +68,7 @@ opendir (const char *name)
res = NULL;
}
if (res)
res->__flags |= CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO ? dirent_set_d_ino : 0;
else if (fh)
if (!res && fh)
delete fh;
return res;
}
@@ -89,6 +86,7 @@ readdir_worker (DIR *dir, dirent *de)
return EBADF;
}
de->d_ino = 0;
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
if (res == ENMFILE)
@@ -109,39 +107,38 @@ readdir_worker (DIR *dir, dirent *de)
}
}
if (!res)
if (!res && !de->d_ino)
{
/* Compute d_ino by combining filename hash with the directory hash
(which was stored in dir->__d_dirhash when opendir was called). */
if (de->d_name[0] != '.')
/* relax */;
else if (de->d_name[1] == '\0')
dir->__flags |= dirent_saw_dot;
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
dir->__flags |= dirent_saw_dot_dot;
if (!(dir->__flags & dirent_set_d_ino))
de->__dirent_internal = 0;
else
bool is_dot = false;
bool is_dot_dot = false;
if (de->d_name[0] == '.')
{
#if 0
size_t len = strlen (dir->__d_dirname) + strlen (de->d_name);
char *path = (char *) alloca (len);
char *p = strchr (strcpy (path, dir->__d_dirname), '\0');
strcpy (p - 1, de->d_name);
struct __stat64 st;
if (lstat64 (path, &st) == 0)
de->__dirent_internal = st.st_ino;
else
{
#endif
de->__dirent_internal = hash_path_name (0, dir->__d_dirname);
de->__dirent_internal = hash_path_name (de->__dirent_internal, de->d_name);
#if 0
}
#endif
if (de->d_name[1] == '\0')
is_dot = true;
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
is_dot_dot = true;
}
if (is_dot_dot && !(dir->__flags & dirent_isroot))
de->d_ino = readdir_get_ino (dir,
((fhandler_base *) dir->__fh)->get_name (),
true);
else
{
/* Compute d_ino by combining filename hash with directory hash. */
de->d_ino = ((fhandler_base *) dir->__fh)->get_namehash ();
if (!is_dot && !is_dot_dot)
{
const char *w32name = ((fhandler_base *) dir->__fh)->get_win32_name ();
/* A drive's root dir has a trailing backslash already. */
if (w32name[1] != ':' || w32name[2] != '\\' || w32name[3])
de->d_ino = hash_path_name (de->d_ino, "\\");
de->d_ino = hash_path_name (de->d_ino, de->d_name);
}
}
de->__dirent_internal1 = de->__dirent_internal;
}
de->__d_internal1 = de->d_ino;
return res;
}
@@ -201,7 +198,7 @@ seekdir64 (DIR *dir, _off64_t loc)
if (dir->__d_cookie != __DIRENT_COOKIE)
return;
dir->__flags &= (dirent_isroot | dirent_set_d_ino);
dir->__flags &= (dirent_isroot | dirent_get_d_ino | dirent_set_d_ino);
return ((fhandler_base *) dir->__fh)->seekdir (dir, loc);
}