diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/mingw.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index a65a0a6d1..82316e69d 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -328,11 +328,11 @@ static inline mode_t file_attr_to_st_mode(DWORD attr) | |||
328 | { | 328 | { |
329 | mode_t fMode = S_IRUSR|S_IRGRP|S_IROTH; | 329 | mode_t fMode = S_IRUSR|S_IRGRP|S_IROTH; |
330 | if (attr & FILE_ATTRIBUTE_DIRECTORY) | 330 | if (attr & FILE_ATTRIBUTE_DIRECTORY) |
331 | fMode |= S_IFDIR|S_IWUSR|S_IWGRP|S_IXUSR|S_IXGRP|S_IXOTH; | 331 | fMode |= S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH; |
332 | else | 332 | else |
333 | fMode |= S_IFREG; | 333 | fMode |= S_IFREG; |
334 | if (!(attr & FILE_ATTRIBUTE_READONLY)) | 334 | if (!(attr & FILE_ATTRIBUTE_READONLY)) |
335 | fMode |= S_IWUSR|S_IWGRP; | 335 | fMode |= S_IWUSR|S_IWGRP|(attr & FILE_ATTRIBUTE_DEVICE ? S_IWOTH : 0); |
336 | return fMode; | 336 | return fMode; |
337 | } | 337 | } |
338 | 338 | ||
@@ -340,15 +340,28 @@ static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fd | |||
340 | { | 340 | { |
341 | size_t len; | 341 | size_t len; |
342 | 342 | ||
343 | if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata)) | 343 | if (get_dev_type(fname) != NOT_DEVICE || get_dev_fd(fname) >= 0) { |
344 | /* Fake attributes for special devices */ | ||
345 | FILETIME epoch = {0xd53e8000, 0x019db1de}; // Unix epoch as FILETIME | ||
346 | fdata->dwFileAttributes = FILE_ATTRIBUTE_DEVICE; | ||
347 | fdata->ftCreationTime = fdata->ftLastAccessTime = | ||
348 | fdata->ftLastWriteTime = epoch; | ||
349 | fdata->nFileSizeHigh = fdata->nFileSizeLow = 0; | ||
344 | return 0; | 350 | return 0; |
351 | } | ||
352 | |||
353 | if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata)) { | ||
354 | fdata->dwFileAttributes &= ~FILE_ATTRIBUTE_DEVICE; | ||
355 | return 0; | ||
356 | } | ||
345 | 357 | ||
346 | if (GetLastError() == ERROR_SHARING_VIOLATION) { | 358 | if (GetLastError() == ERROR_SHARING_VIOLATION) { |
347 | HANDLE hnd; | 359 | HANDLE hnd; |
348 | WIN32_FIND_DATA fd; | 360 | WIN32_FIND_DATA fd; |
349 | 361 | ||
350 | if ((hnd=FindFirstFile(fname, &fd)) != INVALID_HANDLE_VALUE) { | 362 | if ((hnd=FindFirstFile(fname, &fd)) != INVALID_HANDLE_VALUE) { |
351 | fdata->dwFileAttributes = fd.dwFileAttributes; | 363 | fdata->dwFileAttributes = |
364 | fd.dwFileAttributes & ~FILE_ATTRIBUTE_DEVICE; | ||
352 | fdata->ftCreationTime = fd.ftCreationTime; | 365 | fdata->ftCreationTime = fd.ftCreationTime; |
353 | fdata->ftLastAccessTime = fd.ftLastAccessTime; | 366 | fdata->ftLastAccessTime = fd.ftLastAccessTime; |
354 | fdata->ftLastWriteTime = fd.ftLastWriteTime; | 367 | fdata->ftLastWriteTime = fd.ftLastWriteTime; |
@@ -586,6 +599,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
586 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); | 599 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); |
587 | buf->st_attr = fdata.dwFileAttributes; | 600 | buf->st_attr = fdata.dwFileAttributes; |
588 | if (S_ISREG(buf->st_mode) && | 601 | if (S_ISREG(buf->st_mode) && |
602 | !(buf->st_attr & FILE_ATTRIBUTE_DEVICE) && | ||
589 | (has_exe_suffix(file_name) || has_exec_format(file_name))) | 603 | (has_exe_suffix(file_name) || has_exec_format(file_name))) |
590 | buf->st_mode |= S_IXUSR|S_IXGRP|S_IXOTH; | 604 | buf->st_mode |= S_IXUSR|S_IXGRP|S_IXOTH; |
591 | buf->st_size = fdata.nFileSizeLow | | 605 | buf->st_size = fdata.nFileSizeLow | |
@@ -616,7 +630,8 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
616 | else { | 630 | else { |
617 | buf->st_uid = 0; | 631 | buf->st_uid = 0; |
618 | buf->st_gid = 0; | 632 | buf->st_gid = 0; |
619 | buf->st_mode &= ~(S_IROTH|S_IWOTH|S_IXOTH); | 633 | if (!(buf->st_attr & FILE_ATTRIBUTE_DEVICE)) |
634 | buf->st_mode &= ~(S_IROTH|S_IWOTH|S_IXOTH); | ||
620 | } | 635 | } |
621 | #endif | 636 | #endif |
622 | 637 | ||