diff options
author | Christopher Faylor <me@cgf.cx> | 2006-01-21 02:24:17 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2006-01-21 02:24:17 +0000 |
commit | 868fb2ff6992142de60d6ff31da0ac84ddcf9363 (patch) | |
tree | f03159b6200450e06f348f4b67ddcc3585e754c3 /winsup | |
parent | 54abc854d09c5b411a22406de19cbd7cdf88e748 (diff) | |
download | newlib-868fb2ff6992142de60d6ff31da0ac84ddcf9363.zip newlib-868fb2ff6992142de60d6ff31da0ac84ddcf9363.tar.gz newlib-868fb2ff6992142de60d6ff31da0ac84ddcf9363.tar.bz2 |
* 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.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 17 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 2 | ||||
-rw-r--r-- | winsup/cygwin/dir.cc | 81 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 5 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_virtual.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/include/sys/dirent.h | 32 |
8 files changed, 75 insertions, 74 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 38d2631..37ccebf 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,22 @@ 2006-01-20 Christopher Faylor <cgf@timesys.com> + * 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. + +2006-01-20 Christopher Faylor <cgf@timesys.com> + * include/sys/dirent.h: Add comments for people who are REALLY confused about whether they should be using something called __invalid_d_ino or not. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 5efc6fd..770923d 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -993,7 +993,7 @@ open SIGFE _open = open SIGFE _open64 opendir SIGFE -_opendir = opendir SIGFE +__opendir_with_d_ino SIGFE openlog SIGFE _openlog = openlog SIGFE openpty SIGFE diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 14f02d9..403b557 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); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 462a62a..525e37c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -47,7 +47,8 @@ enum dirent_states dirent_isroot = 0x0008, dirent_saw_cygdrive = 0x0010, dirent_saw_dev = 0x0020, - dirent_saw_proc = 0x0040 + dirent_saw_proc = 0x0040, + dirent_set_d_ino = 0x0080 }; enum conn_state diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 7243d59..ce0738b 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1359,7 +1359,7 @@ fhandler_disk_file::opendir () else { strcpy (dir->__d_dirname, get_win32_name ()); - dir->__d_dirent->d_version = __DIRENT_VERSION; + dir->__d_dirent->__d_version = __DIRENT_VERSION; cygheap_fdnew fd; if (fd < 0) @@ -1367,7 +1367,7 @@ fhandler_disk_file::opendir () fd = this; fd->nohandle (true); - dir->__d_dirent->d_fd = fd; + dir->__d_fd = fd; dir->__fh = this; /* FindFirstFile doesn't seem to like duplicate /'s. */ len = strlen (dir->__d_dirname); @@ -1378,7 +1378,6 @@ fhandler_disk_file::opendir () dir->__d_cookie = __DIRENT_COOKIE; dir->__handle = INVALID_HANDLE_VALUE; dir->__d_position = 0; - dir->__d_dirhash = get_namehash (); res = dir; dir->__flags = (pc.normalized_path[0] == '/' && pc.normalized_path[1] == '\0') ? dirent_isroot : 0; diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 414d5c8..98620f4 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -71,18 +71,18 @@ fhandler_virtual::opendir () else { strcpy (dir->__d_dirname, get_name ()); - dir->__d_dirent->d_version = __DIRENT_VERSION; + dir->__d_dirent->__d_version = __DIRENT_VERSION; cygheap_fdnew fd; if (fd >= 0) { fd = this; fd->nohandle (true); - dir->__d_dirent->d_fd = fd; + dir->__d_fd = fd; dir->__fh = this; dir->__d_cookie = __DIRENT_COOKIE; dir->__handle = INVALID_HANDLE_VALUE; dir->__d_position = 0; - dir->__d_dirhash = get_namehash (); + // dir->__d_dirhash = get_namehash (); dir->__flags = dirent_saw_dot | dirent_saw_dot_dot; res = dir; res->__flags = 0; diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index c7bba50..797dd37 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -286,12 +286,13 @@ details. */ 148: Add open(2) flags O_SYNC, O_RSYNC, O_DSYNC and O_DIRECT. 149: Add open(2) flag O_NOFOLLOW. 150: Export getsubopt. + 151: Export __opendir_with_d_ino */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 150 +#define CYGWIN_VERSION_API_MINOR 151 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/sys/dirent.h b/winsup/cygwin/include/sys/dirent.h index b17c2e9..511fbb3 100644 --- a/winsup/cygwin/include/sys/dirent.h +++ b/winsup/cygwin/include/sys/dirent.h @@ -16,27 +16,16 @@ #define __DIRENT_VERSION 2 #pragma pack(push,4) -#ifdef __INSIDE_CYGWIN__ +#if defined(__INSIDE_CYGWIN__) || defined (__CYGWIN_USE_BIG_TYPES__) struct dirent { - long d_version; /* Used since Cygwin 1.3.3. */ - __ino64_t __invalid_d_ino; /* DO NOT USE: No longer available since cygwin 1.5.19 */ - long d_fd; /* File descriptor of open directory. - Used since Cygwin 1.3.3. */ - unsigned __invalid_ino32; /* DO NOT USE: No longer available since cygwin 1.5.19 */ + long __d_version; /* Used internally */ + __ino64_t __dirent_internal; + __uint32_t __dirent_unused1; + __uint32_t __dirent_internal1; char d_name[256]; /* FIXME: use NAME_MAX? */ }; #else -#ifdef __CYGWIN_USE_BIG_TYPES__ -struct dirent -{ - long d_version; - ino_t __invalid_d_ino; /* DO NOT USE: No longer available since cygwin 1.5.19 */ - long d_fd; - unsigned long __invalid_ino32; /* DO NOT USE: No longer available since cygwin 1.5.19 */ - char d_name[256]; -}; -#else struct dirent { long d_version; @@ -46,7 +35,6 @@ struct dirent char d_name[256]; }; #endif -#endif #pragma pack(pop) #define __DIRENT_COOKIE 0xdede4242 @@ -59,14 +47,22 @@ typedef struct __DIR struct dirent *__d_dirent; char *__d_dirname; /* directory name with trailing '*' */ _off_t __d_position; /* used by telldir/seekdir */ - __ino64_t __d_dirhash; /* hash of directory name for use by readdir */ + int __d_fd; + unsigned __d_unused; void *__handle; void *__fh; unsigned __flags; } DIR; #pragma pack(pop) +#ifndef __USE_EXPENSIVE_CYGWIN_D_INO DIR *opendir (const char *); +#else +#define d_ino __dirent_internal +DIR *__opendir_with_d_ino (const char *); +#define opendir __opendir_with_d_ino +#endif + struct dirent *readdir (DIR *); int readdir_r (DIR *, struct dirent *, struct dirent **); void rewinddir (DIR *); |