aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-02-19 13:28:49 +0000
committerCorinna Vinschen <corinna@vinschen.de>2010-02-19 13:28:49 +0000
commit1929fc8ece9cfce99449110b2c78d11473aeebae (patch)
tree1397aa25fbc93fd2955c33c61f3e8e2f3f57311b /winsup
parenteb67604071632869f20038ee56df0980ca575843 (diff)
downloadnewlib-1929fc8ece9cfce99449110b2c78d11473aeebae.zip
newlib-1929fc8ece9cfce99449110b2c78d11473aeebae.tar.gz
newlib-1929fc8ece9cfce99449110b2c78d11473aeebae.tar.bz2
* fhandler_disk_file.cc (fhandler_disk_file::opendir): Try to open
directory with stat()-friendly access mask first. Explain why.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc44
2 files changed, 38 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 70e5d6a..9d3743d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,10 @@
2010-02-19 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler_disk_file.cc (fhandler_disk_file::opendir): Try to open
+ directory with stat()-friendly access mask first. Explain why.
+
+2010-02-19 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler_disk_file.cc (fhandler_base::fstat_helper): Set st_rdev
to same value as st_dev. Avoid useless debug output in executable
check. Add filename to debug output.
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 2d0dad2..04eceaf 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1660,19 +1660,41 @@ fhandler_disk_file::opendir (int fd)
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
IO_STATUS_BLOCK io;
-
- status = NtOpenFile (&get_handle (),
- SYNCHRONIZE | FILE_LIST_DIRECTORY,
- pc.get_object_attr (attr, sec_none_nih),
- &io, FILE_SHARE_VALID_FLAGS,
- FILE_SYNCHRONOUS_IO_NONALERT
- | FILE_OPEN_FOR_BACKUP_INTENT
- | FILE_DIRECTORY_FILE);
- if (!NT_SUCCESS (status))
+ /* Tools like ls(1) call dirfd() to fetch the directory
+ descriptor for calls to facl or fstat. The tight access mask
+ used so far is not sufficient to reuse the handle for these
+ calls, instead the facl/fstat calls find the handle to be
+ unusable and have to re-open the file for reading attributes
+ and control data. So, what we do here is to try to open the
+ directory with more relaxed access mask which enables to use
+ the handle for the aforementioned purpose. This should work
+ in almost all cases. Only if it doesn't work due to
+ permission problems, we drop the additional access bits and
+ try again. */
+ ACCESS_MASK fstat_mask = READ_CONTROL | FILE_READ_ATTRIBUTES;
+
+ do
{
- __seterrno_from_nt_status (status);
- goto free_mounts;
+ status = NtOpenFile (&get_handle (),
+ SYNCHRONIZE | FILE_LIST_DIRECTORY
+ | fstat_mask,
+ pc.get_object_attr (attr, sec_none_nih),
+ &io, FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_FOR_BACKUP_INTENT
+ | FILE_DIRECTORY_FILE);
+ if (!NT_SUCCESS (status))
+ {
+ if (status == STATUS_ACCESS_DENIED && fstat_mask)
+ fstat_mask = 0;
+ else
+ {
+ __seterrno_from_nt_status (status);
+ goto free_mounts;
+ }
+ }
}
+ while (!NT_SUCCESS (status));
}
/* FileIdBothDirectoryInformation is apparently unsupported on