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.
This commit is contained in:
Christopher Faylor 2003-09-08 04:04:19 +00:00
parent d31c5928dd
commit 0c7b55727a
6 changed files with 93 additions and 57 deletions

View File

@ -1,3 +1,19 @@
2003-09-07 Christopher Faylor <cgf@redhat.com>
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 <cgf@redhat.com> 2003-09-07 Christopher Faylor <cgf@redhat.com>
* include/cygwin/in.h: Don't define ipv6 stuff unless we call for it * include/cygwin/in.h: Don't define ipv6 stuff unless we call for it

View File

@ -71,6 +71,14 @@ dirfd (DIR *dir)
return dir->__d_dirent->d_fd; 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 */ /* opendir: POSIX 5.1.2.1 */
extern "C" DIR * extern "C" DIR *
opendir (const char *name) opendir (const char *name)
@ -91,7 +99,9 @@ opendir (const char *name)
res = NULL; res = NULL;
} }
if (!res && fh) if (res)
res->__flags = 0;
else if (fh)
delete fh; delete fh;
return res; return res;
} }
@ -110,7 +120,23 @@ readdir (DIR *dir)
return NULL; 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) if (res)
{ {
@ -119,11 +145,15 @@ readdir (DIR *dir)
if (res->d_name[0] == '.') if (res->d_name[0] == '.')
{ {
if (res->d_name[1] == '\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') else if (res->d_name[1] != '.' || res->d_name[2] != '\0')
goto hashit; goto hashit;
else else
{ {
dir->__flags |= opendir_saw_dot_dot;
char *p, up[strlen (dir->__d_dirname) + 1]; char *p, up[strlen (dir->__d_dirname) + 1];
strcpy (up, dir->__d_dirname); strcpy (up, dir->__d_dirname);
if (!(p = strrchr (up, '\\'))) 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->d_ino = hash_path_name (dino, res->d_name);
} }
} }
dir->__d_dirent->old_d_ino = dir->__d_dirent->d_ino; // just truncate
return res; return res;
} }
@ -157,7 +186,7 @@ telldir64 (DIR *dir)
if (dir->__d_cookie != __DIRENT_COOKIE) if (dir->__d_cookie != __DIRENT_COOKIE)
return 0; return 0;
return ((fhandler_base *) dir->__d_u.__d_data.__fh)->telldir (dir); return ((fhandler_base *) dir->__fh)->telldir (dir);
} }
/* telldir */ /* telldir */
@ -175,7 +204,8 @@ seekdir64 (DIR *dir, _off64_t loc)
if (dir->__d_cookie != __DIRENT_COOKIE) if (dir->__d_cookie != __DIRENT_COOKIE)
return; 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 */ /* seekdir */
@ -194,7 +224,8 @@ rewinddir (DIR *dir)
if (dir->__d_cookie != __DIRENT_COOKIE) if (dir->__d_cookie != __DIRENT_COOKIE)
return; 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 */ /* 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. */ /* Reset the marker in case the caller tries to use `dir' again. */
dir->__d_cookie = 0; 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); cygheap->fdtab.release (dir->__d_dirent->d_fd);

View File

@ -593,7 +593,7 @@ fhandler_disk_file::opendir (path_conv& real_name)
fd = this; fd = this;
fd->set_nohandle (true); fd->set_nohandle (true);
dir->__d_dirent->d_fd = fd; dir->__d_dirent->d_fd = fd;
dir->__d_u.__d_data.__fh = this; dir->__fh = this;
/* FindFirstFile doesn't seem to like duplicate /'s. */ /* FindFirstFile doesn't seem to like duplicate /'s. */
len = strlen (dir->__d_dirname); len = strlen (dir->__d_dirname);
if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) if (len == 0 || isdirsep (dir->__d_dirname[len - 1]))
@ -601,7 +601,7 @@ fhandler_disk_file::opendir (path_conv& real_name)
else else
strcat (dir->__d_dirname, "\\*"); /**/ strcat (dir->__d_dirname, "\\*"); /**/
dir->__d_cookie = __DIRENT_COOKIE; 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_position = 0;
dir->__d_dirhash = get_namehash (); dir->__d_dirhash = get_namehash ();
@ -622,25 +622,25 @@ fhandler_disk_file::readdir (DIR *dir)
HANDLE handle; HANDLE handle;
struct dirent *res = NULL; struct dirent *res = NULL;
if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE if (dir->__handle == INVALID_HANDLE_VALUE
&& dir->__d_position == 0) && dir->__d_position == 0)
{ {
handle = FindFirstFileA (dir->__d_dirname, &buf); handle = FindFirstFileA (dir->__d_dirname, &buf);
DWORD lasterr = GetLastError (); DWORD lasterr = GetLastError ();
dir->__d_u.__d_data.__handle = handle; dir->__handle = handle;
if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES)) if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES))
{ {
seterrno_from_win_error (__FILE__, __LINE__, lasterr); seterrno_from_win_error (__FILE__, __LINE__, lasterr);
return res; return res;
} }
} }
else if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE) else if (dir->__handle == INVALID_HANDLE_VALUE)
return res; return res;
else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf)) else if (!FindNextFileA (dir->__handle, &buf))
{ {
DWORD lasterr = GetLastError (); DWORD lasterr = GetLastError ();
(void) FindClose (dir->__d_u.__d_data.__handle); (void) FindClose (dir->__handle);
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; dir->__handle = INVALID_HANDLE_VALUE;
/* POSIX says you shouldn't set errno when readdir can't /* POSIX says you shouldn't set errno when readdir can't
find any more files; so, if another error we leave it set. */ find any more files; so, if another error we leave it set. */
if (lasterr != ERROR_NO_MORE_FILES) if (lasterr != ERROR_NO_MORE_FILES)
@ -697,10 +697,10 @@ fhandler_disk_file::seekdir (DIR *dir, _off64_t loc)
void void
fhandler_disk_file::rewinddir (DIR *dir) 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); (void) FindClose (dir->__handle);
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; dir->__handle = INVALID_HANDLE_VALUE;
} }
dir->__d_position = 0; dir->__d_position = 0;
} }
@ -709,8 +709,8 @@ int
fhandler_disk_file::closedir (DIR *dir) fhandler_disk_file::closedir (DIR *dir)
{ {
int res = 0; int res = 0;
if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE && if (dir->__handle != INVALID_HANDLE_VALUE &&
FindClose (dir->__d_u.__d_data.__handle) == 0) FindClose (dir->__handle) == 0)
{ {
__seterrno (); __seterrno ();
res = -1; res = -1;
@ -728,14 +728,10 @@ fhandler_cygdrive::fhandler_cygdrive (int unit) :
void void
fhandler_cygdrive::set_drives () fhandler_cygdrive::set_drives ()
{ {
const int len = 1 + 26 * DRVSZ; const int len = 2 + 26 * DRVSZ;
char *p = (char *) crealloc ((void *) win32_path_name, char *p = (char *) crealloc ((void *) win32_path_name, len);
sizeof (".") + sizeof ("..") + len);
win32_path_name = pdrive = p; win32_path_name = pdrive = p;
strcpy (p, ".");
strcpy (p + sizeof ("."), "..");
p += sizeof (".") + sizeof ("..");
ndrives = GetLogicalDriveStrings (len, p) / DRVSZ; ndrives = GetLogicalDriveStrings (len, p) / DRVSZ;
} }

View File

@ -291,13 +291,13 @@ fhandler_registry::readdir (DIR * dir)
res = dir->__d_dirent; res = dir->__d_dirent;
goto out; goto out;
} }
if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE if (dir->__handle == INVALID_HANDLE_VALUE
&& dir->__d_position == 0) && dir->__d_position == 0)
{ {
handle = open_key (path + 1, KEY_READ, false); 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; goto out;
if (dir->__d_position < SPECIAL_DOT_FILE_COUNT) 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, /* 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? * 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, (dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
buf, &buf_size, NULL, NULL, NULL, NULL); buf, &buf_size, NULL, NULL, NULL, NULL);
else else
error = 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, SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL,
NULL); NULL);
if (error == ERROR_NO_MORE_ITEMS if (error == ERROR_NO_MORE_ITEMS
@ -329,8 +329,8 @@ retry:
} }
if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA) if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
{ {
RegCloseKey ((HKEY) dir->__d_u.__d_data.__handle); RegCloseKey ((HKEY) dir->__handle);
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; dir->__handle = INVALID_HANDLE_VALUE;
if (error != ERROR_NO_MORE_ITEMS) if (error != ERROR_NO_MORE_ITEMS)
seterrno_from_win_error (__FILE__, __LINE__, error); seterrno_from_win_error (__FILE__, __LINE__, error);
goto out; goto out;
@ -372,10 +372,10 @@ fhandler_registry::seekdir (DIR * dir, _off64_t loc)
void void
fhandler_registry::rewinddir (DIR * dir) 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); (void) RegCloseKey ((HKEY) dir->__handle);
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; dir->__handle = INVALID_HANDLE_VALUE;
} }
dir->__d_position = 0; dir->__d_position = 0;
return; return;
@ -385,8 +385,8 @@ int
fhandler_registry::closedir (DIR * dir) fhandler_registry::closedir (DIR * dir)
{ {
int res = 0; int res = 0;
if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE && if (dir->__handle != INVALID_HANDLE_VALUE &&
RegCloseKey ((HKEY) dir->__d_u.__d_data.__handle) != ERROR_SUCCESS) RegCloseKey ((HKEY) dir->__handle) != ERROR_SUCCESS)
{ {
__seterrno (); __seterrno ();
res = -1; res = -1;

View File

@ -77,9 +77,9 @@ fhandler_virtual::opendir (path_conv& pc)
fd = this; fd = this;
fd->set_nohandle (true); fd->set_nohandle (true);
dir->__d_dirent->d_fd = fd; dir->__d_dirent->d_fd = fd;
dir->__d_u.__d_data.__fh = this; dir->__fh = this;
dir->__d_cookie = __DIRENT_COOKIE; 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_position = 0;
dir->__d_dirhash = get_namehash (); dir->__d_dirhash = get_namehash ();

View File

@ -1,6 +1,6 @@
/* Posix dirent.h for WIN32. /* 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 This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for 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 */ __ino64_t d_ino; /* still junk but with more bits */
long d_fd; /* File descriptor of open directory. long d_fd; /* File descriptor of open directory.
Used since Cygwin 1.3.3. */ 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? */ char d_name[256]; /* FIXME: use NAME_MAX? */
}; };
#else #else
@ -33,7 +33,7 @@ struct dirent
long d_version; long d_version;
ino_t d_ino; ino_t d_ino;
long d_fd; long d_fd;
unsigned long old_d_ino; unsigned long __unused;
char d_name[256]; char d_name[256];
}; };
#else #else
@ -51,6 +51,7 @@ struct dirent
#define __DIRENT_COOKIE 0xdede4242 #define __DIRENT_COOKIE 0xdede4242
#pragma pack(push,4)
typedef struct __DIR typedef struct __DIR
{ {
/* This is first to set alignment in non _COMPILING_NEWLIB case. */ /* This is first to set alignment in non _COMPILING_NEWLIB case. */
@ -58,20 +59,12 @@ typedef struct __DIR
struct dirent *__d_dirent; struct dirent *__d_dirent;
char *__d_dirname; /* directory name with trailing '*' */ char *__d_dirname; /* directory name with trailing '*' */
_off_t __d_position; /* used by telldir/seekdir */ _off_t __d_position; /* used by telldir/seekdir */
unsigned long __d_dirhash; /* hash of directory name for use by __ino64_t __d_dirhash; /* hash of directory name for use by readdir */
readdir */
union
{
#ifdef __INSIDE_CYGWIN__
struct
{
void *__handle; void *__handle;
void *__fh; void *__fh;
} __d_data; unsigned __flags;
#endif
char __d_filler[16];
} __d_u;
} DIR; } DIR;
#pragma pack(pop)
DIR *opendir (const char *); DIR *opendir (const char *);
struct dirent *readdir (DIR *); struct dirent *readdir (DIR *);