From 868fb2ff6992142de60d6ff31da0ac84ddcf9363 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 21 Jan 2006 02:24:17 +0000 Subject: * include/cygwin/version.h: Bump API minor number to 151. * dir.cc (__opendir_with_d_ino): New function. (opendir): Set flag if we should be calculating inodes. (readdir_worker): Calculate d_ino by calling stat if the user has asked for it. (seekdir64): Maintain all persistent flag settings. * fhandler.h (dirent_states): Add dirent_set_d_ino. * fhandler_disk_file.cc (fhandler_disk_file::opendir): Reflect changes to dirent structure. * fhandler_virtual.cc (fhandler_virtual::opendir): Ditto. * include/sys/dirent.h (struct dirent): Coalesce two similar structures. Remove all threads of the apparently highly confusing references to inodes. Add support for calculating a real inode if __USE_EXPENSIVE_CYGWIN_D_INO is defined. --- winsup/cygwin/dir.cc | 81 ++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 47 deletions(-) (limited to 'winsup/cygwin/dir.cc') diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 14f02d9a1..403b5574b 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -39,7 +39,16 @@ dirfd (DIR *dir) syscall_printf ("-1 = dirfd (%p)", dir); return -1; } - return dir->__d_dirent->d_fd; + return dir->__d_fd; +} + +extern "C" DIR * +__opendir_with_d_ino (const char *name) +{ + DIR *res = opendir (name); + if (res) + res->__flags |= dirent_set_d_ino; + return res; } /* opendir: POSIX 5.1.2.1 */ @@ -61,7 +70,7 @@ opendir (const char *name) } if (res) - /* nothing */; + res->__flags |= CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO ? dirent_set_d_ino : 0; else if (fh) delete fh; return res; @@ -100,58 +109,36 @@ readdir_worker (DIR *dir, dirent *de) } } - if (res) - /* error return */; - else if (!CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO) - { - de->__invalid_d_ino = (ino_t) -1; - de->__invalid_ino32 = (uint32_t) -1; - if (de->d_name[0] == '.') - { - 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; - } - } - else + if (!res) { /* 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] == '.') + 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 { - if (de->d_name[1] == '\0') - { - de->__invalid_d_ino = dir->__d_dirhash; - dir->__flags |= dirent_saw_dot; - } - else if (de->d_name[1] != '.' || de->d_name[2] != '\0') - goto hashit; + 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 { - dir->__flags |= dirent_saw_dot_dot; - char *p, up[strlen (dir->__d_dirname) + 1]; - strcpy (up, dir->__d_dirname); - if (!(p = strrchr (up, '\\'))) - goto hashit; - *p = '\0'; - if (!(p = strrchr (up, '\\'))) - de->__invalid_d_ino = hash_path_name (0, "."); - else - { - *p = '\0'; - de->__invalid_d_ino = hash_path_name (0, up); - } + de->__dirent_internal = hash_path_name (0, dir->__d_dirname); + de->__dirent_internal = hash_path_name (de->__dirent_internal, de->d_name); } } - else - { - hashit: - __ino64_t dino = hash_path_name (dir->__d_dirhash, "\\"); - de->__invalid_d_ino = hash_path_name (dino, de->d_name); - } - de->__invalid_ino32 = de->__invalid_d_ino; // for legacy applications + de->__dirent_internal1 = de->__dirent_internal; } + return res; } @@ -210,7 +197,7 @@ seekdir64 (DIR *dir, _off64_t loc) if (dir->__d_cookie != __DIRENT_COOKIE) return; - dir->__flags &= dirent_isroot; + dir->__flags &= (dirent_isroot | dirent_set_d_ino); return ((fhandler_base *) dir->__fh)->seekdir (dir, loc); } @@ -255,7 +242,7 @@ closedir (DIR *dir) int res = ((fhandler_base *) dir->__fh)->closedir (dir); - cygheap->fdtab.release (dir->__d_dirent->d_fd); + cygheap->fdtab.release (dir->__d_fd); free (dir->__d_dirname); free (dir->__d_dirent); -- cgit v1.2.3