diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-10-09 17:45:27 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-10-09 17:45:27 +0000 |
commit | f49469bb1efd493811e7d475daa89743623ce424 (patch) | |
tree | 4ca4c1156c6c059b95a6cea28ba605583b8140e2 | |
parent | 50f799240ec354800dd4fe9410807d58f124103a (diff) | |
download | newlib-f49469bb1efd493811e7d475daa89743623ce424.zip newlib-f49469bb1efd493811e7d475daa89743623ce424.tar.gz newlib-f49469bb1efd493811e7d475daa89743623ce424.tar.bz2 |
* fhandler_procsys.cc (fhandler_procsys::readdir): Just test
ObjectTypeName for object types rather than calling lstat to avoid
performance hit.
* globals.cc (ro_u_natdir): Define.
(ro_u_natsyml): Define.
(ro_u_natdev): Define.
-rw-r--r-- | winsup/cygwin/ChangeLog | 9 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_procsys.cc | 60 | ||||
-rw-r--r-- | winsup/cygwin/globals.cc | 3 |
3 files changed, 42 insertions, 30 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 76002fb..f970d8a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,14 @@ 2014-10-09 Corinna Vinschen <corinna@vinschen.de> + * fhandler_procsys.cc (fhandler_procsys::readdir): Just test + ObjectTypeName for object types rather than calling lstat to avoid + performance hit. + * globals.cc (ro_u_natdir): Define. + (ro_u_natsyml): Define. + (ro_u_natdev): Define. + +2014-10-09 Corinna Vinschen <corinna@vinschen.de> + * fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Set d_type for virtual directories. diff --git a/winsup/cygwin/fhandler_procsys.cc b/winsup/cygwin/fhandler_procsys.cc index 98fa9e2..1e937c8 100644 --- a/winsup/cygwin/fhandler_procsys.cc +++ b/winsup/cygwin/fhandler_procsys.cc @@ -177,30 +177,28 @@ fhandler_procsys::exists (struct stat *buf) /* Don't call NtQueryInformationFile unless we know it's a safe type. The call is known to crash machines, if the underlying driver is badly written. */ - if (!NT_SUCCESS (status)) - { - NtClose (h); - return file_type; - } - if (ffdi.DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) - file_type = virt_blk; - else if (ffdi.DeviceType == FILE_DEVICE_NAMED_PIPE) - file_type = internal ? virt_blk : virt_pipe; - else if (ffdi.DeviceType == FILE_DEVICE_DISK - || ffdi.DeviceType == FILE_DEVICE_CD_ROM - || ffdi.DeviceType == FILE_DEVICE_DFS - || ffdi.DeviceType == FILE_DEVICE_VIRTUAL_DISK) + if (NT_SUCCESS (status)) { - /* Check for file attributes. If we get them, we peeked - into a real FS through /proc/sys. */ - status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, - FileBasicInformation); - debug_printf ("NtQueryInformationFile: %y", status); - if (!NT_SUCCESS (status)) + if (ffdi.DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) file_type = virt_blk; - else - file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ? virt_fsdir : virt_fsfile; + else if (ffdi.DeviceType == FILE_DEVICE_NAMED_PIPE) + file_type = internal ? virt_blk : virt_pipe; + else if (ffdi.DeviceType == FILE_DEVICE_DISK + || ffdi.DeviceType == FILE_DEVICE_CD_ROM + || ffdi.DeviceType == FILE_DEVICE_DFS + || ffdi.DeviceType == FILE_DEVICE_VIRTUAL_DISK) + { + /* Check for file attributes. If we get them, we peeked + into a real FS through /proc/sys. */ + status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, + FileBasicInformation); + debug_printf ("NtQueryInformationFile: %y", status); + if (!NT_SUCCESS (status)) + file_type = virt_blk; + else + file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + ? virt_fsdir : virt_fsfile; + } } NtClose (h); } @@ -346,7 +344,6 @@ fhandler_procsys::readdir (DIR *dir, dirent *de) WCHAR buf[2][NAME_MAX + 1]; } f; int res = EBADF; - tmp_pathbuf tp; if (dir->__handle != INVALID_HANDLE_VALUE) { @@ -358,16 +355,19 @@ fhandler_procsys::readdir (DIR *dir, dirent *de) res = ENMFILE; else { - struct stat st; - char *file = tp.c_get (); - sys_wcstombs (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer, f.dbi.ObjectName.Length / sizeof (WCHAR)); de->d_ino = hash_path_name (get_ino (), de->d_name); - stpcpy (stpcpy (stpcpy (file, get_name ()), "/"), de->d_name); - if (!lstat64 (file, &st)) - de->d_type = IFTODT (st.st_mode); - else + if (RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natdir, + FALSE)) + de->d_type = DT_DIR; + else if (RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natsyml, + FALSE)) + de->d_type = DT_LNK; + else if (!RtlEqualUnicodeString (&f.dbi.ObjectTypeName, &ro_u_natdev, + FALSE)) + de->d_type = DT_CHR; + else /* Can't nail down "Device" objects without further testing. */ de->d_type = DT_UNKNOWN; res = 0; } diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index a004276..ff80a4b 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -148,6 +148,9 @@ extern "C" { extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\"); extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT"); extern UNICODE_STRING _RDATA ro_u_null = _ROU (L"\\Device\\Null"); + extern UNICODE_STRING _RDATA ro_u_natdir = _ROU (L"Directory"); + extern UNICODE_STRING _RDATA ro_u_natsyml = _ROU (L"SymbolicLink"); + extern UNICODE_STRING _RDATA ro_u_natdev = _ROU (L"Device"); #undef _ROU /* Cygwin properties are meant to be readonly data placed in the DLL, but |