diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2006-01-28 00:50:42 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2006-01-28 00:50:42 +0300 |
commit | 9e5f45ed6fe599c1e7e0f640c8e63936ebaa6d55 (patch) | |
tree | cdb795d81f92b97438b53288ee17fbf35c3131cb /winsup/cygwin/dir.cc | |
parent | e7a9c71d623f88b6d41a769b0ec8e223a958175d (diff) |
* 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.
Diffstat (limited to 'winsup/cygwin/dir.cc')
-rw-r--r-- | winsup/cygwin/dir.cc | 67 |
1 files changed, 32 insertions, 35 deletions
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 2e3901dab..eb665b91f 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -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 + 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) { -#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 + 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); } -#endif } - 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); } |