Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2006-01-21 05:24:17 +0300
committerChristopher Faylor <me@cgf.cx>2006-01-21 05:24:17 +0300
commit868fb2ff6992142de60d6ff31da0ac84ddcf9363 (patch)
treef03159b6200450e06f348f4b67ddcc3585e754c3
parent54abc854d09c5b411a22406de19cbd7cdf88e748 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/cygwin.din2
-rw-r--r--winsup/cygwin/dir.cc81
-rw-r--r--winsup/cygwin/fhandler.h3
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc5
-rw-r--r--winsup/cygwin/fhandler_virtual.cc6
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/include/sys/dirent.h32
8 files changed, 75 insertions, 74 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 38d26317d..37ccebf6d 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 5efc6fd94..770923d54 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 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);
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 462a62a07..525e37ce8 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 7243d591f..ce0738b4a 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 414d5c83f..98620f4cc 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 c7bba5013..797dd37c0 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 b17c2e91d..511fbb373 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 *);