aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/mingw.c25
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