From 0c7b55727aff6848f72afc41c149d9d4dfc3cdb5 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 8 Sep 2003 04:04:19 +0000 Subject: [PATCH] Throughout, remove __d_u.__d_data fields from DIR structure. * include/sys/dirent.h (dirent): Remvoe old_d_ino. (DIR): Make __d_dirhash a 64 bit value. Remove __d_data and __d_u. Add __flags. * dir.cc (opendir_states): New enum. (opendir): Clear new DIR __flags field. (readdir): Fill in '.' and '..' entries if we hit EOF and we haven't seen them already. Nuke setting of old_d_ino. (rewinddir): Reset DIR __flags field. (seekdir64): Ditto. * fhandler_disk_file.cc (fhandler_cygdrive::fhandler_cygdrive): Remove special handling of "." and ".." since they are now handled automatically. --- winsup/cygwin/ChangeLog | 16 ++++++++++ winsup/cygwin/dir.cc | 47 ++++++++++++++++++++++++----- winsup/cygwin/fhandler_disk_file.cc | 34 +++++++++------------ winsup/cygwin/fhandler_registry.cc | 24 +++++++-------- winsup/cygwin/fhandler_virtual.cc | 4 +-- winsup/cygwin/include/sys/dirent.h | 25 ++++++--------- 6 files changed, 93 insertions(+), 57 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 462b999e1..6c463790d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2003-09-07 Christopher Faylor + + Throughout, remove __d_u.__d_data fields from DIR structure. + * include/sys/dirent.h (dirent): Remvoe old_d_ino. + (DIR): Make __d_dirhash a 64 bit value. Remove __d_data and __d_u. + Add __flags. + * dir.cc (opendir_states): New enum. + (opendir): Clear new DIR __flags field. + (readdir): Fill in '.' and '..' entries if we hit EOF and we haven't + seen them already. Nuke setting of old_d_ino. + (rewinddir): Reset DIR __flags field. + (seekdir64): Ditto. + * fhandler_disk_file.cc (fhandler_cygdrive::fhandler_cygdrive): Remove + special handling of "." and ".." since they are now handled + automatically. + 2003-09-07 Christopher Faylor * include/cygwin/in.h: Don't define ipv6 stuff unless we call for it diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index d5b8dc5e9..6fd2804d4 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -71,6 +71,14 @@ dirfd (DIR *dir) return dir->__d_dirent->d_fd; } +enum opendir_states +{ + opendir_ok = 0, + opendir_saw_dot = 1, + opendir_saw_dot_dot = 2, + opendir_saw_eof = 4 +}; + /* opendir: POSIX 5.1.2.1 */ extern "C" DIR * opendir (const char *name) @@ -91,7 +99,9 @@ opendir (const char *name) res = NULL; } - if (!res && fh) + if (res) + res->__flags = 0; + else if (fh) delete fh; return res; } @@ -110,7 +120,23 @@ readdir (DIR *dir) return NULL; } - dirent *res = ((fhandler_base *) dir->__d_u.__d_data.__fh)->readdir (dir); + dirent *res = ((fhandler_base *) dir->__fh)->readdir (dir); + + if (!res) + { + if (!(dir->__flags & opendir_saw_dot)) + { + res = dir->__d_dirent; + strcpy (res->d_name, "."); + dir->__flags |= opendir_saw_dot; + } + else if (!(dir->__flags & opendir_saw_dot_dot)) + { + res = dir->__d_dirent; + strcpy (res->d_name, ".."); + dir->__flags |= opendir_saw_dot_dot; + } + } if (res) { @@ -119,11 +145,15 @@ readdir (DIR *dir) if (res->d_name[0] == '.') { if (res->d_name[1] == '\0') - dir->__d_dirent->d_ino = dir->__d_dirhash; + { + dir->__d_dirent->d_ino = dir->__d_dirhash; + dir->__flags |= opendir_saw_dot; + } else if (res->d_name[1] != '.' || res->d_name[2] != '\0') goto hashit; else { + dir->__flags |= opendir_saw_dot_dot; char *p, up[strlen (dir->__d_dirname) + 1]; strcpy (up, dir->__d_dirname); if (!(p = strrchr (up, '\\'))) @@ -145,7 +175,6 @@ readdir (DIR *dir) dir->__d_dirent->d_ino = hash_path_name (dino, res->d_name); } } - dir->__d_dirent->old_d_ino = dir->__d_dirent->d_ino; // just truncate return res; } @@ -157,7 +186,7 @@ telldir64 (DIR *dir) if (dir->__d_cookie != __DIRENT_COOKIE) return 0; - return ((fhandler_base *) dir->__d_u.__d_data.__fh)->telldir (dir); + return ((fhandler_base *) dir->__fh)->telldir (dir); } /* telldir */ @@ -175,7 +204,8 @@ seekdir64 (DIR *dir, _off64_t loc) if (dir->__d_cookie != __DIRENT_COOKIE) return; - return ((fhandler_base *) dir->__d_u.__d_data.__fh)->seekdir (dir, loc); + dir->__flags = 0; + return ((fhandler_base *) dir->__fh)->seekdir (dir, loc); } /* seekdir */ @@ -194,7 +224,8 @@ rewinddir (DIR *dir) if (dir->__d_cookie != __DIRENT_COOKIE) return; - return ((fhandler_base *) dir->__d_u.__d_data.__fh)->rewinddir (dir); + dir->__flags = 0; + return ((fhandler_base *) dir->__fh)->rewinddir (dir); } /* closedir: POSIX 5.1.2.1 */ @@ -214,7 +245,7 @@ closedir (DIR *dir) /* Reset the marker in case the caller tries to use `dir' again. */ dir->__d_cookie = 0; - int res = ((fhandler_base *) dir->__d_u.__d_data.__fh)->closedir (dir); + int res = ((fhandler_base *) dir->__fh)->closedir (dir); cygheap->fdtab.release (dir->__d_dirent->d_fd); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 5b873a045..e687efc63 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -593,7 +593,7 @@ fhandler_disk_file::opendir (path_conv& real_name) fd = this; fd->set_nohandle (true); dir->__d_dirent->d_fd = fd; - dir->__d_u.__d_data.__fh = this; + dir->__fh = this; /* FindFirstFile doesn't seem to like duplicate /'s. */ len = strlen (dir->__d_dirname); if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) @@ -601,7 +601,7 @@ fhandler_disk_file::opendir (path_conv& real_name) else strcat (dir->__d_dirname, "\\*"); /**/ dir->__d_cookie = __DIRENT_COOKIE; - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + dir->__handle = INVALID_HANDLE_VALUE; dir->__d_position = 0; dir->__d_dirhash = get_namehash (); @@ -622,25 +622,25 @@ fhandler_disk_file::readdir (DIR *dir) HANDLE handle; struct dirent *res = NULL; - if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE + if (dir->__handle == INVALID_HANDLE_VALUE && dir->__d_position == 0) { handle = FindFirstFileA (dir->__d_dirname, &buf); DWORD lasterr = GetLastError (); - dir->__d_u.__d_data.__handle = handle; + dir->__handle = handle; if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES)) { seterrno_from_win_error (__FILE__, __LINE__, lasterr); return res; } } - else if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE) + else if (dir->__handle == INVALID_HANDLE_VALUE) return res; - else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf)) + else if (!FindNextFileA (dir->__handle, &buf)) { DWORD lasterr = GetLastError (); - (void) FindClose (dir->__d_u.__d_data.__handle); - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + (void) FindClose (dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; /* POSIX says you shouldn't set errno when readdir can't find any more files; so, if another error we leave it set. */ if (lasterr != ERROR_NO_MORE_FILES) @@ -697,10 +697,10 @@ fhandler_disk_file::seekdir (DIR *dir, _off64_t loc) void fhandler_disk_file::rewinddir (DIR *dir) { - if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE) + if (dir->__handle != INVALID_HANDLE_VALUE) { - (void) FindClose (dir->__d_u.__d_data.__handle); - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + (void) FindClose (dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; } dir->__d_position = 0; } @@ -709,8 +709,8 @@ int fhandler_disk_file::closedir (DIR *dir) { int res = 0; - if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE && - FindClose (dir->__d_u.__d_data.__handle) == 0) + if (dir->__handle != INVALID_HANDLE_VALUE && + FindClose (dir->__handle) == 0) { __seterrno (); res = -1; @@ -728,14 +728,10 @@ fhandler_cygdrive::fhandler_cygdrive (int unit) : void fhandler_cygdrive::set_drives () { - const int len = 1 + 26 * DRVSZ; - char *p = (char *) crealloc ((void *) win32_path_name, - sizeof (".") + sizeof ("..") + len); + const int len = 2 + 26 * DRVSZ; + char *p = (char *) crealloc ((void *) win32_path_name, len); win32_path_name = pdrive = p; - strcpy (p, "."); - strcpy (p + sizeof ("."), ".."); - p += sizeof (".") + sizeof (".."); ndrives = GetLogicalDriveStrings (len, p) / DRVSZ; } diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index 39a89204e..7e8eb23fb 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -291,13 +291,13 @@ fhandler_registry::readdir (DIR * dir) res = dir->__d_dirent; goto out; } - if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE + if (dir->__handle == INVALID_HANDLE_VALUE && dir->__d_position == 0) { handle = open_key (path + 1, KEY_READ, false); - dir->__d_u.__d_data.__handle = handle; + dir->__handle = handle; } - if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE) + if (dir->__handle == INVALID_HANDLE_VALUE) goto out; if (dir->__d_position < SPECIAL_DOT_FILE_COUNT) { @@ -311,12 +311,12 @@ retry: /* For the moment, the type of key is ignored here. when write access is added, * maybe add an extension for the type of each value? */ - error = RegEnumValue ((HKEY) dir->__d_u.__d_data.__handle, + error = RegEnumValue ((HKEY) dir->__handle, (dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16, buf, &buf_size, NULL, NULL, NULL, NULL); else error = - RegEnumKeyEx ((HKEY) dir->__d_u.__d_data.__handle, dir->__d_position - + RegEnumKeyEx ((HKEY) dir->__handle, dir->__d_position - SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL, NULL); if (error == ERROR_NO_MORE_ITEMS @@ -329,8 +329,8 @@ retry: } if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA) { - RegCloseKey ((HKEY) dir->__d_u.__d_data.__handle); - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + RegCloseKey ((HKEY) dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; if (error != ERROR_NO_MORE_ITEMS) seterrno_from_win_error (__FILE__, __LINE__, error); goto out; @@ -372,10 +372,10 @@ fhandler_registry::seekdir (DIR * dir, _off64_t loc) void fhandler_registry::rewinddir (DIR * dir) { - if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE) + if (dir->__handle != INVALID_HANDLE_VALUE) { - (void) RegCloseKey ((HKEY) dir->__d_u.__d_data.__handle); - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + (void) RegCloseKey ((HKEY) dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; } dir->__d_position = 0; return; @@ -385,8 +385,8 @@ int fhandler_registry::closedir (DIR * dir) { int res = 0; - if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE && - RegCloseKey ((HKEY) dir->__d_u.__d_data.__handle) != ERROR_SUCCESS) + if (dir->__handle != INVALID_HANDLE_VALUE && + RegCloseKey ((HKEY) dir->__handle) != ERROR_SUCCESS) { __seterrno (); res = -1; diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 2c149566d..c3a355397 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -77,9 +77,9 @@ fhandler_virtual::opendir (path_conv& pc) fd = this; fd->set_nohandle (true); dir->__d_dirent->d_fd = fd; - dir->__d_u.__d_data.__fh = this; + dir->__fh = this; dir->__d_cookie = __DIRENT_COOKIE; - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + dir->__handle = INVALID_HANDLE_VALUE; dir->__d_position = 0; dir->__d_dirhash = get_namehash (); diff --git a/winsup/cygwin/include/sys/dirent.h b/winsup/cygwin/include/sys/dirent.h index a077169b9..1e6996f87 100644 --- a/winsup/cygwin/include/sys/dirent.h +++ b/winsup/cygwin/include/sys/dirent.h @@ -1,6 +1,6 @@ /* Posix dirent.h for WIN32. - Copyright 2001 Red Hat, Inc. + Copyright 2001, 2002, 2003 Red Hat, Inc. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for @@ -23,7 +23,7 @@ struct dirent __ino64_t d_ino; /* still junk but with more bits */ long d_fd; /* File descriptor of open directory. Used since Cygwin 1.3.3. */ - __ino32_t old_d_ino; /* Just for compatibility, it's junk */ + unsigned __flags; /* Used internally. */ char d_name[256]; /* FIXME: use NAME_MAX? */ }; #else @@ -33,7 +33,7 @@ struct dirent long d_version; ino_t d_ino; long d_fd; - unsigned long old_d_ino; + unsigned long __unused; char d_name[256]; }; #else @@ -51,6 +51,7 @@ struct dirent #define __DIRENT_COOKIE 0xdede4242 +#pragma pack(push,4) typedef struct __DIR { /* This is first to set alignment in non _COMPILING_NEWLIB case. */ @@ -58,20 +59,12 @@ typedef struct __DIR struct dirent *__d_dirent; char *__d_dirname; /* directory name with trailing '*' */ _off_t __d_position; /* used by telldir/seekdir */ - unsigned long __d_dirhash; /* hash of directory name for use by - readdir */ - union - { -#ifdef __INSIDE_CYGWIN__ - struct - { - void *__handle; - void *__fh; - } __d_data; -#endif - char __d_filler[16]; - } __d_u; + __ino64_t __d_dirhash; /* hash of directory name for use by readdir */ + void *__handle; + void *__fh; + unsigned __flags; } DIR; +#pragma pack(pop) DIR *opendir (const char *); struct dirent *readdir (DIR *);