Created
August 3, 2012 14:13
-
-
Save shirosaki/3248001 to your computer and use it in GitHub Desktop.
Winstat patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/win32/win32.c b/win32/win32.c | |
index 458b613..8640ddd 100644 | |
--- a/win32/win32.c | |
+++ b/win32/win32.c | |
@@ -4554,18 +4554,11 @@ check_valid_dir(const WCHAR *path) | |
{ | |
WIN32_FIND_DATAW fd; | |
HANDLE fh; | |
- WCHAR full[MAX_PATH]; | |
- WCHAR *dmy; | |
- | |
- /* if the specified path is the root of a drive and the drive is empty, */ | |
- /* FindFirstFile() returns INVALID_HANDLE_VALUE. */ | |
- if (!GetFullPathNameW(path, sizeof(full) / sizeof(WCHAR), full, &dmy)) { | |
- errno = map_errno(GetLastError()); | |
- return -1; | |
- } | |
- if (full[1] == L':' && !full[3] && GetDriveTypeW(full) != DRIVE_NO_ROOT_DIR) | |
+ /* GetFileAttributes determines "..." as directory. */ | |
+ /* We recheck it by FindFirstFile. */ | |
+ if (wcsstr(path, L"...") == NULL) { | |
return 0; | |
- | |
+ } | |
fh = open_dir_handle(path, &fd); | |
if (fh == INVALID_HANDLE_VALUE) | |
return -1; | |
@@ -4579,6 +4572,7 @@ winnt_stat(const WCHAR *path, struct stati64 *st) | |
{ | |
HANDLE h; | |
WIN32_FIND_DATAW wfd; | |
+ WIN32_FILE_ATTRIBUTE_DATA wfa; | |
const WCHAR *p = path; | |
memset(st, 0, sizeof(*st)); | |
@@ -4589,27 +4583,43 @@ winnt_stat(const WCHAR *path, struct stati64 *st) | |
errno = ENOENT; | |
return -1; | |
} | |
- h = FindFirstFileW(path, &wfd); | |
- if (h != INVALID_HANDLE_VALUE) { | |
- FindClose(h); | |
- st->st_mode = fileattr_to_unixmode(wfd.dwFileAttributes, path); | |
- st->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime); | |
- st->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime); | |
- st->st_ctime = filetime_to_unixtime(&wfd.ftCreationTime); | |
- st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow; | |
+ if (GetFileAttributesExW(path, GetFileExInfoStandard, (void*)&wfa)) { | |
+ if (wfa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { | |
+ if (check_valid_dir(path)) return -1; | |
+ st->st_size = 0; | |
+ } | |
+ else { | |
+ st->st_size = ((__int64)wfa.nFileSizeHigh << 32) | wfa.nFileSizeLow; | |
+ } | |
+ st->st_mode = fileattr_to_unixmode(wfa.dwFileAttributes, path); | |
+ st->st_atime = filetime_to_unixtime(&wfa.ftLastAccessTime); | |
+ st->st_mtime = filetime_to_unixtime(&wfa.ftLastWriteTime); | |
+ st->st_ctime = filetime_to_unixtime(&wfa.ftCreationTime); | |
} | |
else { | |
- // If runtime stat(2) is called for network shares, it fails on WinNT. | |
- // Because GetDriveType returns 1 for network shares. (Win98 returns 4) | |
- DWORD attr = GetFileAttributesW(path); | |
- if (attr == (DWORD)-1L) { | |
- errno = map_errno(GetLastError()); | |
+ /* GetFileAttributesEx failed; check why. */ | |
+ int e = GetLastError(); | |
+ | |
+ if ((e == ERROR_FILE_NOT_FOUND) || (e == ERROR_INVALID_NAME) | |
+ || (e == ERROR_PATH_NOT_FOUND)) { | |
+ errno = map_errno(e); | |
return -1; | |
} | |
- if (attr & FILE_ATTRIBUTE_DIRECTORY) { | |
- if (check_valid_dir(path)) return -1; | |
+ | |
+ /* Fall back to FindFirstFile */ | |
+ h = FindFirstFileW(path, &wfd); | |
+ if (h != INVALID_HANDLE_VALUE) { | |
+ FindClose(h); | |
+ st->st_mode = fileattr_to_unixmode(wfd.dwFileAttributes, path); | |
+ st->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime); | |
+ st->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime); | |
+ st->st_ctime = filetime_to_unixtime(&wfd.ftCreationTime); | |
+ st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow; | |
+ } | |
+ else { | |
+ errno = map_errno(GetLastError()); | |
+ return -1; | |
} | |
- st->st_mode = fileattr_to_unixmode(attr, path); | |
} | |
st->st_dev = st->st_rdev = (iswalpha(path[0]) && path[1] == L':') ? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# without patch | |
V:\mesurements>rci bench core_require_empty | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------ | |
core_require_empty 0.733000 1.934000 2.667000 ( 2.711155) | |
--------------------------------------------- total: 2.667000sec | |
user system total real | |
core_require_empty 1.014000 1.591000 2.605000 ( 2.697154) | |
V:\mesurements>rci bench core_require_empty | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------ | |
core_require_empty 0.717000 1.965000 2.682000 ( 2.714155) | |
--------------------------------------------- total: 2.682000sec | |
user system total real | |
core_require_empty 0.624000 1.966000 2.590000 ( 2.711155) | |
V:\mesurements>rci bench core_require_nested | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------- | |
core_require_nested 0.765000 2.247000 3.012000 ( 3.163181) | |
---------------------------------------------- total: 3.012000sec | |
user system total real | |
core_require_nested 0.842000 2.106000 2.948000 ( 3.157181) | |
V:\mesurements>rci bench core_require_nested | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------- | |
core_require_nested 0.764000 2.215000 2.979000 ( 3.148180) | |
---------------------------------------------- total: 2.979000sec | |
user system total real | |
core_require_nested 0.858000 2.153000 3.011000 ( 3.171182) | |
# patched | |
V:\mesurements>rci bench core_require_empty | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------ | |
core_require_empty 0.593000 1.903000 2.496000 ( 2.547146) | |
--------------------------------------------- total: 2.496000sec | |
user system total real | |
core_require_empty 0.593000 1.872000 2.465000 ( 2.541145) | |
V:\mesurements>rci bench core_require_empty | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------ | |
core_require_empty 0.499000 1.981000 2.480000 ( 2.535145) | |
--------------------------------------------- total: 2.480000sec | |
user system total real | |
core_require_empty 0.718000 1.763000 2.481000 ( 2.522144) | |
V:\mesurements>rci bench core_require_nested | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------- | |
core_require_nested 0.562000 2.106000 2.668000 ( 2.719156) | |
---------------------------------------------- total: 2.668000sec | |
user system total real | |
core_require_nested 0.655000 1.872000 2.527000 ( 2.707155) | |
V:\mesurements>rci bench core_require_nested | |
ruby 2.0.0dev (2012-08-03 trunk 36612) [x64-mswin64_100] | |
Rehearsal ------------------------------------------------------- | |
core_require_nested 0.702000 1.872000 2.574000 ( 2.717155) | |
---------------------------------------------- total: 2.574000sec | |
user system total real | |
core_require_nested 0.733000 1.919000 2.652000 ( 2.722156) |
Author
shirosaki
commented
Aug 3, 2012
Can you submit this to Ruby-Core?
I think this has been well tested already.
Thank you! 😃
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment