diff options
author | NAKAMURA Usaku <usa@ruby-lang.org> | 2022-06-18 22:54:12 +0900 |
---|---|---|
committer | NAKAMURA Usaku <usa@ruby-lang.org> | 2022-06-18 22:54:12 +0900 |
commit | 28b238f2cbcbf9993c4ce8031cbe19bd2accbfbf (patch) | |
tree | 09a955ab45eb577843497641a14a4c4d27f8d9ee /win32 | |
parent | 3fa771ddedac25560be57f4055f1767e6c810f58 (diff) | |
download | ruby-28b238f2cbcbf9993c4ce8031cbe19bd2accbfbf.tar.gz |
merge revision(s): a0040af6715d85f416f1282588974e151a8164eb
[Win32] Fix mode of character/pipe device stat [Bug #18732]
Diffstat (limited to 'win32')
-rw-r--r-- | win32/win32.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/win32/win32.c b/win32/win32.c index cad2784f69..5fd7595414 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -5569,10 +5569,8 @@ filetime_to_nsec(const FILETIME *ft) /* License: Ruby's */ static unsigned -fileattr_to_unixmode(DWORD attr, const WCHAR *path) +fileattr_to_unixmode(DWORD attr, const WCHAR *path, unsigned mode) { - unsigned mode = 0; - if (attr & FILE_ATTRIBUTE_READONLY) { mode |= S_IREAD; } @@ -5580,7 +5578,10 @@ fileattr_to_unixmode(DWORD attr, const WCHAR *path) mode |= S_IREAD | S_IWRITE | S_IWUSR; } - if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { + if (mode & S_IFMT) { + /* format is already set */ + } + else if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { if (rb_w32_reparse_symlink_p(path)) mode |= S_IFLNK | S_IEXEC; else @@ -5675,7 +5676,7 @@ stat_by_find(const WCHAR *path, struct stati128 *st) return -1; } FindClose(h); - st->st_mode = fileattr_to_unixmode(wfd.dwFileAttributes, path); + st->st_mode = fileattr_to_unixmode(wfd.dwFileAttributes, path, 0); st->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime); st->st_atimensec = filetime_to_nsec(&wfd.ftLastAccessTime); st->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime); @@ -5710,6 +5711,15 @@ winnt_stat(const WCHAR *path, struct stati128 *st, BOOL lstat) if (f != INVALID_HANDLE_VALUE) { DWORD attr = stati128_handle(f, st); const DWORD len = get_final_path(f, finalname, numberof(finalname), 0); + unsigned mode = 0; + switch (GetFileType(f)) { + case FILE_TYPE_CHAR: + mode = S_IFCHR; + break; + case FILE_TYPE_PIPE: + mode = S_IFIFO; + break; + } CloseHandle(f); if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { /* TODO: size in which encoding? */ @@ -5721,7 +5731,7 @@ winnt_stat(const WCHAR *path, struct stati128 *st, BOOL lstat) if (attr & FILE_ATTRIBUTE_DIRECTORY) { if (check_valid_dir(path)) return -1; } - st->st_mode = fileattr_to_unixmode(attr, path); + st->st_mode = fileattr_to_unixmode(attr, path, mode); if (len) { finalname[min(len, numberof(finalname)-1)] = L'\0'; path = finalname; |