summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Lowe <joe@pismotec.com>2017-06-13 11:12:50 -0700
committerCorinna Vinschen <corinna@vinschen.de>2017-06-14 10:57:02 +0200
commit0a9edd73e3abb85162f9d79bc57cf4df1f9d8f1e (patch)
tree3dd39e213dda7b95e28a4766e194a7f596c6285e
parent35cd6863fb3a970507b5eaf587eda59abcefb241 (diff)
downloadcygnal-0a9edd73e3abb85162f9d79bc57cf4df1f9d8f1e.tar.gz
cygnal-0a9edd73e3abb85162f9d79bc57cf4df1f9d8f1e.tar.bz2
cygnal-0a9edd73e3abb85162f9d79bc57cf4df1f9d8f1e.zip
readdir() with mount point dentry, return mount point INO
This patch fixes a minor compatibility issue w/ cygwin mount point handling in readdir(), compared to equivalent behavior of Linux and MacOS. dentry.d_ino should indicate the INO of the mount point itself, not the target volume root folder. Changed return type from readdir_check_reparse_point to uint8_t, to avoid unnecessarily being implicitly cast to and from a signed int. Renamed a related local variable "attr" to "oattr" that was eclipsing a member variable with the same name. Joe L.
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc33
1 files changed, 10 insertions, 23 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index bf5f988c2..f36030444 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -178,10 +178,10 @@ path_conv::isgood_inode (ino_t ino) const
are directory mount points, which are treated as symlinks.
IO_REPARSE_TAG_SYMLINK types are always symlinks. We don't know
anything about other reparse points, so they are treated as unknown. */
-static inline int
+static inline uint8_t
readdir_check_reparse_point (POBJECT_ATTRIBUTES attr)
{
- DWORD ret = DT_UNKNOWN;
+ uint8_t ret = DT_UNKNOWN;
IO_STATUS_BLOCK io;
HANDLE reph;
UNICODE_STRING subst;
@@ -2016,32 +2016,19 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
de->d_type = DT_REG;
}
- /* Check for directory reparse point. These are potential volume mount
- points which have another inode than the underlying directory. */
+ /* Check for directory reparse point. These may be treated as a posix
+ symlink, or as mount point, so need to figure out whether to return
+ a directory or link type. In all cases, returning the INO of the
+ reparse point (not of the target) matches behavior of posix systems.
+ */
if ((attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
== (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
{
- HANDLE reph;
- OBJECT_ATTRIBUTES attr;
- IO_STATUS_BLOCK io;
+ OBJECT_ATTRIBUTES oattr;
- InitializeObjectAttributes (&attr, fname, pc.objcaseinsensitive (),
+ InitializeObjectAttributes (&oattr, fname, pc.objcaseinsensitive (),
get_handle (), NULL);
- de->d_type = readdir_check_reparse_point (&attr);
- if (de->d_type == DT_DIR)
- {
- /* Volume mountpoints are treated as directories. We have to fix
- the inode number, otherwise we have the inode number of the
- mount point, rather than the inode number of the toplevel
- directory of the mounted drive. */
- if (NT_SUCCESS (NtOpenFile (&reph, READ_CONTROL, &attr, &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT)))
- {
- de->d_ino = pc.get_ino_by_handle (reph);
- NtClose (reph);
- }
- }
+ de->d_type = readdir_check_reparse_point (&oattr);
}
/* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the