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:
authorCorinna Vinschen <corinna@vinschen.de>2006-01-28 00:50:42 +0300
committerCorinna Vinschen <corinna@vinschen.de>2006-01-28 00:50:42 +0300
commit9e5f45ed6fe599c1e7e0f640c8e63936ebaa6d55 (patch)
treecdb795d81f92b97438b53288ee17fbf35c3131cb
parente7a9c71d623f88b6d41a769b0ec8e223a958175d (diff)
* autoload.cc (NtQueryDirectoryFile): Define.
* dir.cc (__opendir_with_d_ino): Just call opendir. (opendir): Remove CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO handling. (readdir_worker): Only try generating d_ino if it's 0. Utilize namehash of directories fhandler. Call readdir_get_ino to generate d_ino for "..". (seekdir64): Keep dirent_set_d_ino flag. * fhandler.h (enum dirent_states): Add dirent_get_d_ino. (class fhandler_disk_file): Declare new private methods readdir_helper and readdir_9x. * fhandler_disk_file.cc (path_conv::hasgood_inode): New method to evaluate if a filesystem has reliable inode numbers. (fhandler_base::fstat_by_handle): Accomodate structure member name change from IndexNumber to FileId. (fhandler_base::fstat_helper): Call hasgood_inode here. (fhandler_disk_file::opendir): Call fhaccess only for real files. Don't append '*' to __d_dirname here, move to readdir_9x. On NT, open directory handle here. Set dirent_get_d_ino and dirent_set_d_ino flags according to wincap and filesystem. (fhandler_disk_file::readdir_helper): New method to implement readdir postprocessing only once. (readdir_get_ino_by_handle): New static function. (readdir_get_ino): New function to centralize inode number evaluation in case inode number hasn't been returned by NtQueryDirectoryFile. (fhandler_disk_file::readdir): Move old functionality to readdir_9x. Call readdir_9x when on 9x/Me. Implement NT specific readdir here. (fhandler_disk_file::readdir_9x): Move 9x specific readdir here. (fhandler_disk_file::seekdir): Accomodate new NT readdir method. (fhandler_disk_file::closedir): Ditto. (fhandler_cygdrive::fstat): Set d_ino to namehash. Add comment. (fhandler_cygdrive::opendir): Call get_namehash to prepare later correct evaluation of d_ino. (fhandler_cygdrive::readdir): Replace recursion with loop. Evaluate drive's d_ino by calling readdir_get_ino. * fhandler_proc.cc (fhandler_proc::readdir): Set dirent_saw_dot and dirent_saw_dot_dot to avoid seeing . and .. entries twice. * fhandler_process.cc (fhandler_process::readdir): Ditto. * fhandler_registry.cc (fhandler_registry::readdir): Ditto. * ntdll.h (STATUS_INVALID_PARAMETER): New define. (STATUS_INVALID_LEVEL): New define. (struct _FILE_INTERNAL_INFORMATION): Rename member IndexNumber to FileId (as in Nebbitt). * path.h (path_conv::hasgood_inode): Now implemented in fhandler_disk_file.cc. * wincap.h (wincaps::has_fileid_dirinfo): New element. * wincap.cc: Implement above element throughout. * winsup.h (readdir_get_ino): Add declaration. * include/sys/dirent.h (struct dirent): Slightly rename structure members to accomodate changes. Remove __USE_EXPENSIVE_CYGWIN_D_INO handling and declaration of __opendir_with_d_ino.
-rw-r--r--winsup/cygwin/ChangeLog54
-rw-r--r--winsup/cygwin/autoload.cc3
-rw-r--r--winsup/cygwin/dir.cc67
-rw-r--r--winsup/cygwin/fhandler.h5
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc425
-rw-r--r--winsup/cygwin/fhandler_proc.cc1
-rw-r--r--winsup/cygwin/fhandler_process.cc3
-rw-r--r--winsup/cygwin/fhandler_registry.cc3
-rw-r--r--winsup/cygwin/include/sys/dirent.h17
-rw-r--r--winsup/cygwin/ntdll.h6
-rw-r--r--winsup/cygwin/path.h5
-rw-r--r--winsup/cygwin/wincap.cc39
-rw-r--r--winsup/cygwin/wincap.h2
-rw-r--r--winsup/cygwin/winsup.h4
14 files changed, 452 insertions, 182 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 1cb69b9ef..778f13fe6 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,57 @@
+2006-01-26 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc (NtQueryDirectoryFile): Define.
+ * dir.cc (__opendir_with_d_ino): Just call opendir.
+ (opendir): Remove CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO handling.
+ (readdir_worker): Only try generating d_ino if it's 0.
+ Utilize namehash of directories fhandler. Call readdir_get_ino to
+ generate d_ino for "..".
+ (seekdir64): Keep dirent_set_d_ino flag.
+ * fhandler.h (enum dirent_states): Add dirent_get_d_ino.
+ (class fhandler_disk_file): Declare new private methods readdir_helper
+ and readdir_9x.
+ * fhandler_disk_file.cc (path_conv::hasgood_inode): New method to
+ evaluate if a filesystem has reliable inode numbers.
+ (fhandler_base::fstat_by_handle): Accomodate structure member name
+ change from IndexNumber to FileId.
+ (fhandler_base::fstat_helper): Call hasgood_inode here.
+ (fhandler_disk_file::opendir): Call fhaccess only for real files.
+ Don't append '*' to __d_dirname here, move to readdir_9x. On NT,
+ open directory handle here. Set dirent_get_d_ino and dirent_set_d_ino
+ flags according to wincap and filesystem.
+ (fhandler_disk_file::readdir_helper): New method to implement readdir
+ postprocessing only once.
+ (readdir_get_ino_by_handle): New static function.
+ (readdir_get_ino): New function to centralize inode number evaluation
+ in case inode number hasn't been returned by NtQueryDirectoryFile.
+ (fhandler_disk_file::readdir): Move old functionality to readdir_9x.
+ Call readdir_9x when on 9x/Me. Implement NT specific readdir here.
+ (fhandler_disk_file::readdir_9x): Move 9x specific readdir here.
+ (fhandler_disk_file::seekdir): Accomodate new NT readdir method.
+ (fhandler_disk_file::closedir): Ditto.
+ (fhandler_cygdrive::fstat): Set d_ino to namehash. Add comment.
+ (fhandler_cygdrive::opendir): Call get_namehash to prepare later
+ correct evaluation of d_ino.
+ (fhandler_cygdrive::readdir): Replace recursion with loop. Evaluate
+ drive's d_ino by calling readdir_get_ino.
+ * fhandler_proc.cc (fhandler_proc::readdir): Set dirent_saw_dot and
+ dirent_saw_dot_dot to avoid seeing . and .. entries twice.
+ * fhandler_process.cc (fhandler_process::readdir): Ditto.
+ * fhandler_registry.cc (fhandler_registry::readdir): Ditto.
+ * ntdll.h (STATUS_INVALID_PARAMETER): New define.
+ (STATUS_INVALID_LEVEL): New define.
+ (struct _FILE_INTERNAL_INFORMATION): Rename member IndexNumber to
+ FileId (as in Nebbitt).
+ * path.h (path_conv::hasgood_inode): Now implemented in
+ fhandler_disk_file.cc.
+ * wincap.h (wincaps::has_fileid_dirinfo): New element.
+ * wincap.cc: Implement above element throughout.
+ * winsup.h (readdir_get_ino): Add declaration.
+ * include/sys/dirent.h (struct dirent): Slightly rename structure
+ members to accomodate changes.
+ Remove __USE_EXPENSIVE_CYGWIN_D_INO handling and declaration of
+ __opendir_with_d_ino.
+
2006-01-27 Christopher Faylor <cgf@timesys.com>
* spawn.cc (spawn_guts): Fix potential handle leak when failing exec.
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 0d76ebeae..333bff56d 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -1,6 +1,6 @@
/* autoload.cc: all dynamic load stuff.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -385,6 +385,7 @@ LoadDLLfuncEx (NtLockVirtualMemory, 16, ntdll, 1)
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
+LoadDLLfuncEx2 (NtQueryDirectoryFile, 44, ntdll, 1, 1)
LoadDLLfuncEx2 (NtQueryInformationFile, 20, ntdll, 1, 1)
LoadDLLfuncEx (NtQueryInformationProcess, 20, ntdll, 1)
LoadDLLfuncEx2 (NtQueryObject, 20, ntdll, 1, 1)
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index 2e3901dab..eb665b91f 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -42,13 +42,12 @@ dirfd (DIR *dir)
return dir->__d_fd;
}
+/* Symbol kept for backward compatibility. Don't remove. Don't declare
+ in public header file. */
extern "C" DIR *
__opendir_with_d_ino (const char *name)
{
- DIR *res = opendir (name);
- if (res)
- res->__flags |= dirent_set_d_ino;
- return res;
+ return opendir (name);
}
/* opendir: POSIX 5.1.2.1 */
@@ -69,9 +68,7 @@ opendir (const char *name)
res = NULL;
}
- if (res)
- res->__flags |= CYGWIN_VERSION_CHECK_FOR_NEEDS_D_INO ? dirent_set_d_ino : 0;
- else if (fh)
+ if (!res && fh)
delete fh;
return res;
}
@@ -89,6 +86,7 @@ readdir_worker (DIR *dir, dirent *de)
return EBADF;
}
+ de->d_ino = 0;
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
if (res == ENMFILE)
@@ -109,39 +107,38 @@ readdir_worker (DIR *dir, dirent *de)
}
}
- if (!res)
+ if (!res && !de->d_ino)
{
- /* 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] != '.')
- /* 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
+ bool is_dot = false;
+ bool is_dot_dot = false;
+
+ if (de->d_name[0] == '.')
{
-#if 0
- 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
+ if (de->d_name[1] == '\0')
+ is_dot = true;
+ else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
+ is_dot_dot = true;
+ }
+
+ if (is_dot_dot && !(dir->__flags & dirent_isroot))
+ de->d_ino = readdir_get_ino (dir,
+ ((fhandler_base *) dir->__fh)->get_name (),
+ true);
+ else
+ {
+ /* Compute d_ino by combining filename hash with directory hash. */
+ de->d_ino = ((fhandler_base *) dir->__fh)->get_namehash ();
+ if (!is_dot && !is_dot_dot)
{
-#endif
- de->__dirent_internal = hash_path_name (0, dir->__d_dirname);
- de->__dirent_internal = hash_path_name (de->__dirent_internal, de->d_name);
-#if 0
+ const char *w32name = ((fhandler_base *) dir->__fh)->get_win32_name ();
+ /* A drive's root dir has a trailing backslash already. */
+ if (w32name[1] != ':' || w32name[2] != '\\' || w32name[3])
+ de->d_ino = hash_path_name (de->d_ino, "\\");
+ de->d_ino = hash_path_name (de->d_ino, de->d_name);
}
-#endif
}
- de->__dirent_internal1 = de->__dirent_internal;
}
+ de->__d_internal1 = de->d_ino;
return res;
}
@@ -201,7 +198,7 @@ seekdir64 (DIR *dir, _off64_t loc)
if (dir->__d_cookie != __DIRENT_COOKIE)
return;
- dir->__flags &= (dirent_isroot | dirent_set_d_ino);
+ dir->__flags &= (dirent_isroot | dirent_get_d_ino | dirent_set_d_ino);
return ((fhandler_base *) dir->__fh)->seekdir (dir, loc);
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 525e37ce8..82152019b 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -48,7 +48,8 @@ enum dirent_states
dirent_saw_cygdrive = 0x0010,
dirent_saw_dev = 0x0020,
dirent_saw_proc = 0x0040,
- dirent_set_d_ino = 0x0080
+ dirent_set_d_ino = 0x0080,
+ dirent_get_d_ino = 0x0100
};
enum conn_state
@@ -650,6 +651,8 @@ class fhandler_dev_tape: public fhandler_dev_raw
class fhandler_disk_file: public fhandler_base
{
void touch_ctime ();
+ int readdir_helper (DIR *, dirent *, DWORD, DWORD, char *) __attribute__ ((regparm (3)));
+ int readdir_9x (DIR *, dirent *) __attribute__ ((regparm (3)));
public:
fhandler_disk_file ();
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index b534b7fb0..d6b1cd282 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1,7 +1,7 @@
/* fhandler_disk_file.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005 Red Hat, Inc.
+ 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -96,6 +96,38 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
return count + saw_dot;
}
+bool
+path_conv::hasgood_inode ()
+{
+ /* Assume that if a drive has ACL support it MAY have valid "inodes".
+ It definitely does not have valid inodes if it does not have ACL
+ support. Decouple from has_acls() which follows smbntsec setting. */
+ if (!(fs_flags () & FILE_PERSISTENT_ACLS) || drive_type () == DRIVE_UNKNOWN)
+ return false;
+ if (drive_type () == DRIVE_REMOTE)
+ {
+ /* From own experiments and replies from the Cygwin mailing list,
+ we're now trying to figure out how to determine remote file
+ systems which are capable of returning persistent inode
+ numbers. It seems that NT4 NTFS, when accessed remotly, and
+ some other remote file systems return unreliable values in
+ nFileIndex. The common factor of these unreliable remote FS
+ seem to be that FILE_SUPPORTS_OBJECT_IDS isn't set, even though
+ this should have nothing to do with inode numbers.
+ An exception is Samba, which seems to return valid inode numbers
+ without having the FILE_SUPPORTS_OBJECT_IDS flag set. So we're
+ testing for the flag values returned by a 3.x Samba explicitely
+ for now. */
+#define FS_IS_SAMBA (FILE_CASE_SENSITIVE_SEARCH \
+ | FILE_CASE_PRESERVED_NAMES \
+ | FILE_PERSISTENT_ACLS)
+ if (!(fs_flags () & FILE_SUPPORTS_OBJECT_IDS)
+ && fs_flags () != FS_IS_SAMBA)
+ return false;
+ }
+ return true;
+}
+
int __stdcall
fhandler_base::fstat_by_handle (struct __stat64 *buf)
{
@@ -139,8 +171,8 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
pfai->StandardInformation.EndOfFile.HighPart,
pfai->StandardInformation.EndOfFile.LowPart,
pfai->StandardInformation.AllocationSize.QuadPart,
- pfai->InternalInformation.IndexNumber.HighPart,
- pfai->InternalInformation.IndexNumber.LowPart,
+ pfai->InternalInformation.FileId.HighPart,
+ pfai->InternalInformation.FileId.LowPart,
pfai->StandardInformation.NumberOfLinks,
pfai->BasicInformation.FileAttributes);
}
@@ -315,53 +347,11 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
let's try it with `1' as link count. */
buf->st_nlink = pc.ndisk_links (nNumberOfLinks);
- /* Assume that if a drive has ACL support it MAY have valid "inodes".
- It definitely does not have valid inodes if it does not have ACL
- support. Decouple from has_acls() which follows smbntsec setting. */
- switch ((pc.fs_flags () & FILE_PERSISTENT_ACLS)
- && (nFileIndexHigh || nFileIndexLow)
- ? pc.drive_type () : DRIVE_UNKNOWN)
- {
- case DRIVE_FIXED:
- case DRIVE_REMOVABLE:
- case DRIVE_CDROM:
- case DRIVE_RAMDISK:
- /* Although the documentation indicates otherwise, it seems like
- "inodes" on these devices are persistent, at least across reboots. */
- buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32)
- | (__ino64_t) nFileIndexLow;
- break;
-
- case DRIVE_REMOTE:
- /* From own experiments and replies from the Cygwin mailing list,
- we're now trying to figure out how to determine remote file
- systems which are capable of returning persistent inode
- numbers. It seems that NT4 NTFS, when accessed remotly, and
- some other remote file systems return unreliable values in
- nFileIndex. The common factor of these unreliable remote FS
- seem to be that FILE_SUPPORTS_OBJECT_IDS isn't set, even though
- this should have nothing to do with inode numbers.
- An exception is Samba, which seems to return valid inode numbers
- without having the FILE_SUPPORTS_OBJECT_IDS flag set. So we're
- testing for the flag values returned by a 3.x Samba explicitely
- for now. */
-#define FS_IS_SAMBA (FILE_CASE_SENSITIVE_SEARCH \
- | FILE_CASE_PRESERVED_NAMES \
- | FILE_PERSISTENT_ACLS)
- if ((pc.fs_flags () & FILE_SUPPORTS_OBJECT_IDS)
- || pc.fs_flags () == FS_IS_SAMBA)
- {
- buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32)
- | (__ino64_t) nFileIndexLow;
- break;
- }
- /*FALLTHRU*/
- default:
- /* Either the nFileIndex* fields are unreliable or unavailable. Use the
- next best alternative. */
- buf->st_ino = get_namehash ();
- break;
- }
+ if (pc.hasgood_inode ())
+ buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32)
+ | (__ino64_t) nFileIndexLow;
+ else
+ buf->st_ino = get_namehash ();
buf->st_blksize = S_BLKSIZE;
@@ -1376,7 +1366,7 @@ fhandler_disk_file::opendir ()
set_errno (ENOMEM);
goto free_dirname;
}
- else if (fhaccess (R_OK) != 0)
+ else if (!pc.isspecial () && fhaccess (R_OK) != 0)
goto free_dirent;
else
{
@@ -1391,18 +1381,36 @@ fhandler_disk_file::opendir ()
fd->nohandle (true);
dir->__d_fd = fd;
dir->__fh = this;
- /* FindFirstFile doesn't seem to like duplicate /'s. */
+ /* FindFirstFile doesn't seem to like duplicate /'s.
+ The dirname is generated with trailing backslash here which
+ simplifies later usage of dirname for checking symlinks.
+ Appending a "*" is moved right before calling FindFirstFile.
+ Since FindFirstFile is only called once, this should even be a
+ teeny little bit faster. */
len = strlen (dir->__d_dirname);
- if (len == 0 || isdirsep (dir->__d_dirname[len - 1]))
- strcat (dir->__d_dirname, "*");
- else
- strcat (dir->__d_dirname, "\\*"); /**/
+ if (len && !isdirsep (dir->__d_dirname[len - 1]))
+ strcpy (dir->__d_dirname + len, "\\");
dir->__d_cookie = __DIRENT_COOKIE;
dir->__handle = INVALID_HANDLE_VALUE;
dir->__d_position = 0;
- res = dir;
dir->__flags = (pc.normalized_path[0] == '/' && pc.normalized_path[1] == '\0') ? dirent_isroot : 0;
+ if (!pc.isspecial () && wincap.is_winnt ())
+ {
+ dir->__handle = CreateFile (get_win32_name (), GENERIC_READ,
+ wincap.shared (), NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (dir->__handle == INVALID_HANDLE_VALUE)
+ {
+ __seterrno ();
+ goto free_dirent;
+ }
+ if (wincap.has_fileid_dirinfo ())
+ dir->__flags |= dirent_get_d_ino;
+ if (pc.hasgood_inode ())
+ dir->__flags |= dirent_set_d_ino;
+ }
+ res = dir;
}
syscall_printf ("%p = opendir (%s)", res, get_name ());
@@ -1418,103 +1426,286 @@ free_dir:
}
int
-fhandler_disk_file::readdir (DIR *dir, dirent *de)
+fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
+ DWORD attr, char *fname)
{
- WIN32_FIND_DATA buf;
- HANDLE handle;
- int res;
-
- if (!dir->__handle)
- {
- res = ENMFILE;
- goto out;
- }
- if (dir->__handle == INVALID_HANDLE_VALUE && dir->__d_position == 0)
- {
- handle = FindFirstFileA (dir->__d_dirname, &buf);
- DWORD lasterr = GetLastError ();
- dir->__handle = handle;
- if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES))
- {
- res = geterrno_from_win_error ();
- goto out;
- }
- }
- else if (dir->__handle == INVALID_HANDLE_VALUE)
- {
- res = EBADF;
- goto out;
- }
- else if (!FindNextFileA (dir->__handle, &buf))
+ if (w32_err)
{
bool added = false;
if (!(dir->__flags & dirent_isroot))
/* nothing */;
else if (0 && !(dir->__flags & dirent_saw_dev))
{
- strcpy (buf.cFileName, "dev");
+ strcpy (fname, "dev");
added = true;
}
else if (!(dir->__flags & dirent_saw_proc))
{
- strcpy (buf.cFileName, "proc");
+ strcpy (fname, "proc");
added = true;
}
else if (!(dir->__flags & dirent_saw_cygdrive)
&& mount_table->cygdrive_len > 1)
{
- strcpy (buf.cFileName, mount_table->cygdrive + 1);
- buf.cFileName[mount_table->cygdrive_len - 2] = '\0';
+ strcpy (fname, mount_table->cygdrive + 1);
+ fname[mount_table->cygdrive_len - 2] = '\0';
added = true;
}
if (added)
- buf.dwFileAttributes = 0;
- else
{
- res = geterrno_from_win_error ();
- FindClose (dir->__handle);
- dir->__handle = NULL;
- goto out;
- }
+ attr = 0;
+ dir->__flags &= ~dirent_set_d_ino;
+ }
+ else
+ return geterrno_from_win_error (w32_err);
}
/* Check for Windows shortcut. If it's a Cygwin or U/WIN
symlink, drop the .lnk suffix. */
- if (buf.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ if (attr & FILE_ATTRIBUTE_READONLY)
{
- char *c = buf.cFileName;
+ char *c = fname;
int len = strlen (c);
if (strcasematch (c + len - 4, ".lnk"))
{
char fbuf[CYG_MAX_PATH];
strcpy (fbuf, dir->__d_dirname);
- strcpy (fbuf + strlen (fbuf) - 1, c);
+ strcat (fbuf, c);
path_conv fpath (fbuf, PC_SYM_NOFOLLOW);
if (fpath.issymlink () || fpath.is_fs_special ())
c[len - 4] = '\0';
}
}
- /* We get here if `buf' contains valid data. */
if (pc.isencoded ())
- fnunmunge (de->d_name, buf.cFileName);
+ fnunmunge (de->d_name, fname);
else
- strcpy (de->d_name, buf.cFileName);
+ strcpy (de->d_name, fname);
if (dir->__flags & dirent_isroot)
{
if (strcasematch (de->d_name, "dev"))
- dir->__flags |= dirent_saw_dev;
+ {
+ dir->__flags |= dirent_saw_dev;
+ de->d_ino = hash_path_name (0, "/dev");
+ }
else if (strcasematch (de->d_name, "proc"))
- dir->__flags |= dirent_saw_proc;
+ {
+ dir->__flags |= dirent_saw_proc;
+ de->d_ino = hash_path_name (0, "/proc");
+ }
if (strlen (de->d_name) == mount_table->cygdrive_len - 2
&& strncasematch (de->d_name, mount_table->cygdrive + 1,
mount_table->cygdrive_len - 2))
- dir->__flags |= dirent_saw_cygdrive;
+ {
+ dir->__flags |= dirent_saw_cygdrive;
+ de->d_ino = 0;
+ }
+ }
+ if (dir->__d_position == 0 && !strcmp (fname, "."))
+ dir->__flags |= dirent_saw_dot;
+ else if (dir->__d_position == 1 && !strcmp (fname, ".."))
+ dir->__flags |= dirent_saw_dot_dot;
+ return 0;
+}
+
+static inline __ino64_t
+readdir_get_ino_by_handle (HANDLE hdl)
+{
+ IO_STATUS_BLOCK io;
+ FILE_INTERNAL_INFORMATION pfai;
+
+ if (!NtQueryInformationFile (hdl, &io, &pfai, sizeof pfai,
+ FileInternalInformation))
+ return pfai.FileId.QuadPart;
+ return 0;
+}
+
+__ino64_t __stdcall
+readdir_get_ino (DIR *dir, const char *path, bool dot_dot)
+{
+ char fname[CYG_MAX_PATH];
+ struct __stat64 st;
+ HANDLE hdl;
+ __ino64_t ino = 0;
+
+ if (!(dir->__flags & dirent_isroot))
+ {
+ strcpy (fname, path);
+ if (dot_dot)
+ strcat (fname, (*fname && fname[strlen (fname) - 1] == '/')
+ ? ".." : "/..");
+ path_conv pc (fname);
+ if (pc.isspecial ())
+ {
+ if (!lstat64 (fname, &st))
+ ino = st.st_ino;
+ }
+ else if (!pc.hasgood_inode ())
+ ino = hash_path_name (0, pc);
+ else if ((hdl = CreateFile (pc, GENERIC_READ, wincap.shared (), NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
+ NULL)) != INVALID_HANDLE_VALUE)
+ {
+ ino = readdir_get_ino_by_handle (hdl);
+ CloseHandle (hdl);
+ }
+ }
+ else
+ ino = readdir_get_ino_by_handle (dir->__handle);
+ return ino;
+}
+
+int
+fhandler_disk_file::readdir (DIR *dir, dirent *de)
+{
+ int res = 0;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ if (!dir->__handle)
+ {
+ res = ENMFILE;
+ goto out;
+ }
+
+ if (!wincap.is_winnt ())
+ return readdir_9x (dir, de);
+
+#define DIR_BUF_SIZE (sizeof (FILE_ID_BOTH_DIR_INFORMATION) + 2 * CYG_MAX_PATH)
+ PFILE_ID_BOTH_DIR_INFORMATION buf = (PFILE_ID_BOTH_DIR_INFORMATION)
+ alloca (DIR_BUF_SIZE);
+ IO_STATUS_BLOCK io;
+ wchar_t *FileName = buf->FileName;
+ char fname[CYG_MAX_PATH];
+
+ if ((dir->__flags & dirent_get_d_ino))
+ {
+ status = NtQueryDirectoryFile (dir->__handle, NULL, NULL, 0, &io,
+ buf, DIR_BUF_SIZE,
+ FileIdBothDirectoryInformation,
+ TRUE, NULL, dir->__d_position == 0);
+ /* FileIdBothDirectoryInformation isn't supported for remote drives
+ on NT4 and 2K systems, and it's also not supported on 2K at all,
+ when accessing network drives on any remote OS. We just fall
+ back to using a standard directory query in this case and note
+ this case using the dirent_get_d_ino flag. */
+ if (!status)
+ {
+ if ((dir->__flags & dirent_set_d_ino))
+ de->d_ino = buf->FileId.QuadPart;
+ }
+ else if (status == STATUS_INVALID_LEVEL
+ || status == STATUS_INVALID_PARAMETER)
+ dir->__flags &= ~dirent_get_d_ino;
+ }
+ if (!(dir->__flags & dirent_get_d_ino))
+ {
+ status = NtQueryDirectoryFile (dir->__handle, NULL, NULL, 0, &io, buf,
+ DIR_BUF_SIZE, FileBothDirectoryInformation,
+ TRUE, NULL, dir->__d_position == 0);
+ FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
+ }
+ if (!status && de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
+ {
+ OBJECT_ATTRIBUTES attr;
+
+ if (dir->__d_position == 0 && buf->FileNameLength == 2
+ && FileName[0] == '.')
+ de->d_ino = readdir_get_ino_by_handle (dir->__handle);
+ else if (dir->__d_position == 1 && buf->FileNameLength == 4
+ && FileName[0] == '.' && FileName[1] == '.')
+ de->d_ino = readdir_get_ino (dir, pc.normalized_path, true);
+ else
+ {
+ HANDLE hdl;
+ UNICODE_STRING upath = {buf->FileNameLength, CYG_MAX_PATH * 2,
+ FileName};
+ InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
+ dir->__handle , NULL);
+ if (!NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
+ wincap.shared (), 0))
+ {
+ de->d_ino = readdir_get_ino_by_handle (hdl);
+ CloseHandle (hdl);
+ }
+ }
+ }
+
+ if (!status)
+ {
+ wcstombs (fname, FileName, buf->FileNameLength / 2);
+ fname[buf->FileNameLength / 2] = '\0';
+ }
+
+ if (!(res = readdir_helper (dir, de, RtlNtStatusToDosError (status),
+ buf->FileAttributes, fname)))
+ dir->__d_position++;
+ else if (!(dir->__flags & dirent_saw_dot))
+ {
+ strcpy (de->d_name , ".");
+ de->d_ino = readdir_get_ino_by_handle (dir->__handle);
+ dir->__d_position++;
+ dir->__flags |= dirent_saw_dot;
+ res = 0;
+ }
+ else if (!(dir->__flags & dirent_saw_dot))
+ {
+ strcpy (de->d_name , "..");
+ de->d_ino = readdir_get_ino (dir, pc.normalized_path, true);
+ dir->__d_position++;
+ dir->__flags |= dirent_saw_dot_dot;
+ res = 0;
+ }
+ else
+ {
+ CloseHandle (dir->__handle);
+ dir->__handle = NULL;
+ }
+
+out:
+ syscall_printf ("%d = readdir (%p) (%s)", dir, &de, de->d_name);
+ return res;
+}
+
+int
+fhandler_disk_file::readdir_9x (DIR *dir, dirent *de)
+{
+ WIN32_FIND_DATA buf;
+ HANDLE handle;
+ int res = 0;
+ BOOL ret = TRUE;
+
+ if (dir->__handle == INVALID_HANDLE_VALUE && dir->__d_position == 0)
+ {
+ int len = strlen (dir->__d_dirname);
+ strcpy (dir->__d_dirname + len, "*");
+ handle = FindFirstFileA (dir->__d_dirname, &buf);
+ dir->__d_dirname[len] = '\0';
+ DWORD lasterr = GetLastError ();
+ dir->__handle = handle;
+ if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES))
+ {
+ res = geterrno_from_win_error ();
+ goto out;
+ }
+ }
+ else if (dir->__handle == INVALID_HANDLE_VALUE)
+ {
+ res = EBADF;
+ goto out;
+ }
+ else
+ ret = FindNextFileA (dir->__handle, &buf);
+
+ if (!(res = readdir_helper (dir, de, ret ? 0 : GetLastError (),
+ buf.dwFileAttributes, buf.cFileName)))
+ dir->__d_position++;
+ else
+ {
+ FindClose (dir->__handle);
+ dir->__handle = NULL;
}
- dir->__d_position++;
- res = 0;
out:
syscall_printf ("%d = readdir (%p) (%s)", dir, &de, de->d_name);
return res;
@@ -1538,7 +1729,7 @@ fhandler_disk_file::seekdir (DIR *dir, _off64_t loc)
void
fhandler_disk_file::rewinddir (DIR *dir)
{
- if (dir->__handle != INVALID_HANDLE_VALUE)
+ if (!wincap.is_winnt () && dir->__handle != INVALID_HANDLE_VALUE)
{
if (dir->__handle)
FindClose (dir->__handle);
@@ -1552,7 +1743,8 @@ fhandler_disk_file::closedir (DIR *dir)
{
int res = 0;
if (dir->__handle && dir->__handle != INVALID_HANDLE_VALUE
- && FindClose (dir->__handle) == 0)
+ && ((wincap.is_winnt () && !CloseHandle (dir->__handle))
+ || (!wincap.is_winnt () && !FindClose (dir->__handle))))
{
__seterrno ();
res = -1;
@@ -1580,6 +1772,9 @@ int
fhandler_cygdrive::fstat (struct __stat64 *buf)
{
buf->st_mode = S_IFDIR | 0555;
+ /* Call get_namehash before calling set_drives, otherwise the namehash
+ is broken due to overwriting the win32 path in set_drives. */
+ buf->st_ino = get_namehash ();
if (!ndrives)
set_drives ();
buf->st_nlink = ndrives + 2;
@@ -1592,6 +1787,9 @@ fhandler_cygdrive::opendir ()
DIR *dir;
dir = fhandler_disk_file::opendir ();
+ /* Call get_namehash before calling set_drives, otherwise the namehash
+ is broken due to overwriting the win32 path in set_drives. */
+ get_namehash ();
if (dir && !ndrives)
set_drives ();
@@ -1601,16 +1799,17 @@ fhandler_cygdrive::opendir ()
int
fhandler_cygdrive::readdir (DIR *dir, dirent *de)
{
- if (!pdrive || !*pdrive)
- return ENMFILE;
- if (GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES)
+ while (true)
{
+ if (!pdrive || !*pdrive)
+ return ENMFILE;
+ if (GetFileAttributes (pdrive) != INVALID_FILE_ATTRIBUTES)
+ break;
pdrive = strchr (pdrive, '\0') + 1;
- return readdir (dir, de);
}
-
*de->d_name = cyg_tolower (*pdrive);
de->d_name[1] = '\0';
+ de->d_ino = readdir_get_ino (dir, pdrive, false);
dir->__d_position++;
pdrive = strchr (pdrive, '\0') + 1;
syscall_printf ("%p = readdir (%p) (%s)", &de, dir, de->d_name);
diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc
index 5194c9e82..1eebfe601 100644
--- a/winsup/cygwin/fhandler_proc.cc
+++ b/winsup/cygwin/fhandler_proc.cc
@@ -202,6 +202,7 @@ fhandler_proc::readdir (DIR *dir, dirent *de)
if (dir->__d_position < PROC_LINK_COUNT)
{
strcpy (de->d_name, proc_listing[dir->__d_position++]);
+ dir->__flags |= dirent_saw_dot | dirent_saw_dot_dot;
res = 0;
}
else
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 648ced4ab..cb0b80520 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -1,6 +1,6 @@
/* fhandler_process.cc: fhandler for /proc/<pid> virtual filesystem
- Copyright 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -227,6 +227,7 @@ fhandler_process::readdir (DIR *dir, dirent *de)
}
else
strcpy (de->d_name, process_listing[dir->__d_position++]);
+ dir->__flags |= dirent_saw_dot | dirent_saw_dot_dot;
res = 0;
out:
syscall_printf ("%d = readdir (%p, %p) (%s)", res, dir, de, de->d_name);
diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc
index 7c253e03e..0982755d9 100644
--- a/winsup/cygwin/fhandler_registry.cc
+++ b/winsup/cygwin/fhandler_registry.cc
@@ -1,6 +1,6 @@
/* fhandler_registry.cc: fhandler for /proc/registry virtual filesystem
- Copyright 2002, 2003, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright 2002, 2003, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -283,6 +283,7 @@ fhandler_registry::readdir (DIR *dir, dirent *de)
LONG error;
int res = ENMFILE;
+ dir->__flags |= dirent_saw_dot | dirent_saw_dot_dot;
if (*path == 0)
{
if (dir->__d_position >= ROOT_KEY_COUNT)
diff --git a/winsup/cygwin/include/sys/dirent.h b/winsup/cygwin/include/sys/dirent.h
index 511fbb373..a12fefe36 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, 2002, 2003, 2005 Red Hat, Inc.
+ Copyright 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@@ -20,9 +20,9 @@
struct dirent
{
long __d_version; /* Used internally */
- __ino64_t __dirent_internal;
- __uint32_t __dirent_unused1;
- __uint32_t __dirent_internal1;
+ __ino64_t d_ino;
+ __uint32_t __d_fd;
+ __uint32_t __d_internal1;
char d_name[256]; /* FIXME: use NAME_MAX? */
};
#else
@@ -31,7 +31,7 @@ struct dirent
long d_version;
long d_reserved[2];
long d_fd;
- ino_t __invalid_d_ino; /* DO NOT USE: No longer available since cygwin 1.5.19 */
+ ino_t d_ino;
char d_name[256];
};
#endif
@@ -55,14 +55,7 @@ typedef struct __DIR
} 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 *);
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 2816354e0..1e1bd1145 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -1,6 +1,6 @@
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
- Copyright 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -9,8 +9,10 @@
details. */
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
+#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023)
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1L)
+#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
#define PDI_MODULES 0x01
#define PDI_HEAPS 0x04
@@ -460,7 +462,7 @@ typedef struct _FILE_STANDARD_INFORMATION {
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
typedef struct _FILE_INTERNAL_INFORMATION {
- LARGE_INTEGER IndexNumber;
+ LARGE_INTEGER FileId;
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
typedef struct _FILE_EA_INFORMATION {
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 27c21496f..6bd18742f 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -1,6 +1,7 @@
/* path.h: path data structures
- Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -135,7 +136,7 @@ class path_conv
bool isremote () {return fs.is_remote_drive ();}
int has_acls () const {return fs.has_acls (); }
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
- int hasgood_inode () const {return has_acls ();} // Not strictly correct
+ bool hasgood_inode (); /* Implemented in fhandler_disk_file.cc */
int has_buggy_open () const {return fs.has_buggy_open ();}
bool isencoded () {return path_flags & PATH_ENC;}
int binmode () const
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index bd9fd780d..9ff3c92f1 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -63,7 +63,8 @@ static NO_COPY wincaps wincap_unknown = {
has_null_console_handler_routine:false,
has_disk_ex_ioctls:false,
has_working_virtual_lock:false,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_95 = {
@@ -118,7 +119,8 @@ static NO_COPY wincaps wincap_95 = {
has_null_console_handler_routine:false,
has_disk_ex_ioctls:false,
has_working_virtual_lock:false,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_95osr2 = {
@@ -173,7 +175,8 @@ static NO_COPY wincaps wincap_95osr2 = {
has_null_console_handler_routine:false,
has_disk_ex_ioctls:false,
has_working_virtual_lock:false,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_98 = {
@@ -228,7 +231,8 @@ static NO_COPY wincaps wincap_98 = {
has_null_console_handler_routine:false,
has_disk_ex_ioctls:false,
has_working_virtual_lock:false,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_98se = {
@@ -283,7 +287,8 @@ static NO_COPY wincaps wincap_98se = {
has_null_console_handler_routine:false,
has_disk_ex_ioctls:false,
has_working_virtual_lock:false,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_me = {
@@ -338,7 +343,8 @@ static NO_COPY wincaps wincap_me = {
has_null_console_handler_routine:false,
has_disk_ex_ioctls:false,
has_working_virtual_lock:false,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_nt3 = {
@@ -393,7 +399,8 @@ static NO_COPY wincaps wincap_nt3 = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:false,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_nt4 = {
@@ -448,7 +455,8 @@ static NO_COPY wincaps wincap_nt4 = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:false,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_nt4sp4 = {
@@ -503,7 +511,8 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:false,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:false
+ has_disabled_user_tos_setting:false,
+ has_fileid_dirinfo:false
};
static NO_COPY wincaps wincap_2000 = {
@@ -558,7 +567,8 @@ static NO_COPY wincaps wincap_2000 = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:false,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:true
+ has_disabled_user_tos_setting:true,
+ has_fileid_dirinfo:true
};
static NO_COPY wincaps wincap_xp = {
@@ -613,7 +623,8 @@ static NO_COPY wincaps wincap_xp = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:true,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:true
+ has_disabled_user_tos_setting:true,
+ has_fileid_dirinfo:true
};
static NO_COPY wincaps wincap_2003 = {
@@ -668,7 +679,8 @@ static NO_COPY wincaps wincap_2003 = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:true,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:true
+ has_disabled_user_tos_setting:true,
+ has_fileid_dirinfo:true
};
static NO_COPY wincaps wincap_vista = {
@@ -723,7 +735,8 @@ static NO_COPY wincaps wincap_vista = {
has_null_console_handler_routine:true,
has_disk_ex_ioctls:true,
has_working_virtual_lock:true,
- has_disabled_user_tos_setting:true
+ has_disabled_user_tos_setting:true,
+ has_fileid_dirinfo:true
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index f14b274dd..5738850e0 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -65,6 +65,7 @@ struct wincaps
unsigned has_disk_ex_ioctls : 1;
unsigned has_working_virtual_lock : 1;
unsigned has_disabled_user_tos_setting : 1;
+ unsigned has_fileid_dirinfo : 1;
};
class wincapc
@@ -136,6 +137,7 @@ public:
bool IMPLEMENT (has_disk_ex_ioctls)
bool IMPLEMENT (has_working_virtual_lock)
bool IMPLEMENT (has_disabled_user_tos_setting)
+ bool IMPLEMENT (has_fileid_dirinfo)
#undef IMPLEMENT
};
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 55031f9b9..c0059ed44 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -1,7 +1,7 @@
/* winsup.h: main Cygwin header file.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005 Red Hat, Inc.
+ 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -293,6 +293,8 @@ class path_conv;
int fcntl_worker (int fd, int cmd, void *arg);
+__ino64_t __stdcall readdir_get_ino (struct __DIR *dir, const char *path, bool dot_dot) __attribute__ ((regparm (3)));
+
extern "C" int low_priority_sleep (DWORD) __attribute__ ((regparm (1)));
#define SLEEP_0_STAY_LOW INFINITE