diff options
author | Ron Yorston <rmy@pobox.com> | 2023-01-18 11:09:13 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-01-18 11:09:13 +0000 |
commit | 4c92ce9e14703a3100f1aa9fd90bc3864d9e856b (patch) | |
tree | 284eb2d1a341af35e10054ddc98fa6bc020fd197 | |
parent | dbd187697d1265d345e3e3e8b302a88b04592cc2 (diff) | |
download | busybox-w32-4c92ce9e14703a3100f1aa9fd90bc3864d9e856b.tar.gz busybox-w32-4c92ce9e14703a3100f1aa9fd90bc3864d9e856b.tar.bz2 busybox-w32-4c92ce9e14703a3100f1aa9fd90bc3864d9e856b.zip |
win32: more minor improvements to stat(2)
The previous commit incorrectly stated that preventing the access
time of a file from being updated only required it to be opened
with GENERIC_READ access. In fact, even though we don't want to
update the access time, SetFileTime() also requires the file to
have been opened with FILE_WRITE_ATTRIBUTES access.
There's no need to explicitly avoid device files when checking
for execute mode: since device files are now 'character special'
they are excluded by the test that the file is 'regular'.
Device files should be excluded when trying to obtain extra file
data using GetFileInformationByHandle(). It shouldn't be possible
for CreateFile() to open then, so there's no point in trying.
-rw-r--r-- | win32/mingw.c | 55 |
1 files changed, 26 insertions, 29 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index 847e7f6a5..04908ba56 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -444,7 +444,8 @@ static int has_exec_format(const char *name) | |||
444 | return 0; | 444 | return 0; |
445 | 445 | ||
446 | /* Open file and try to avoid updating access time */ | 446 | /* Open file and try to avoid updating access time */ |
447 | fh = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); | 447 | fh = CreateFileA(name, GENERIC_READ | FILE_WRITE_ATTRIBUTES, |
448 | 0, NULL, OPEN_EXISTING, 0, NULL); | ||
448 | if (fh != INVALID_HANDLE_VALUE) { | 449 | if (fh != INVALID_HANDLE_VALUE) { |
449 | FILETIME last_access = { 0xffffffff, 0xffffffff }; | 450 | FILETIME last_access = { 0xffffffff, 0xffffffff }; |
450 | 451 | ||
@@ -648,11 +649,6 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
648 | DWORD low, high; | 649 | DWORD low, high; |
649 | off64_t size; | 650 | off64_t size; |
650 | char *lname = NULL; | 651 | char *lname = NULL; |
651 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | ||
652 | DWORD flags; | ||
653 | BY_HANDLE_FILE_INFORMATION hdata; | ||
654 | HANDLE fh; | ||
655 | #endif | ||
656 | 652 | ||
657 | while (!(err=get_file_attr(file_name, &fdata))) { | 653 | while (!(err=get_file_attr(file_name, &fdata))) { |
658 | buf->st_ino = 0; | 654 | buf->st_ino = 0; |
@@ -687,7 +683,6 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
687 | /* The file is not a symlink. */ | 683 | /* The file is not a symlink. */ |
688 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); | 684 | buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); |
689 | if (S_ISREG(buf->st_mode) && | 685 | if (S_ISREG(buf->st_mode) && |
690 | !(buf->st_attr & FILE_ATTRIBUTE_DEVICE) && | ||
691 | (has_exe_suffix(file_name) || has_exec_format(file_name))) | 686 | (has_exe_suffix(file_name) || has_exec_format(file_name))) |
692 | buf->st_mode |= S_IXUSR|S_IXGRP|S_IXOTH; | 687 | buf->st_mode |= S_IXUSR|S_IXGRP|S_IXOTH; |
693 | buf->st_size = fdata.nFileSizeLow | | 688 | buf->st_size = fdata.nFileSizeLow | |
@@ -699,29 +694,31 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
699 | buf->st_nlink = (buf->st_attr & FILE_ATTRIBUTE_DIRECTORY) ? 2 : 1; | 694 | buf->st_nlink = (buf->st_attr & FILE_ATTRIBUTE_DIRECTORY) ? 2 : 1; |
700 | 695 | ||
701 | #if ENABLE_FEATURE_EXTRA_FILE_DATA | 696 | #if ENABLE_FEATURE_EXTRA_FILE_DATA |
702 | flags = FILE_FLAG_BACKUP_SEMANTICS; | 697 | if (!(buf->st_attr & FILE_ATTRIBUTE_DEVICE)) { |
703 | if (S_ISLNK(buf->st_mode)) | 698 | DWORD flags; |
704 | flags |= FILE_FLAG_OPEN_REPARSE_POINT; | 699 | HANDLE fh; |
705 | fh = CreateFile(file_name, READ_CONTROL, 0, NULL, | 700 | BY_HANDLE_FILE_INFORMATION hdata; |
706 | OPEN_EXISTING, flags, NULL); | 701 | |
707 | if (fh != INVALID_HANDLE_VALUE) { | 702 | flags = FILE_FLAG_BACKUP_SEMANTICS; |
708 | if (GetFileInformationByHandle(fh, &hdata)) { | 703 | if (S_ISLNK(buf->st_mode)) |
709 | buf->st_dev = hdata.dwVolumeSerialNumber; | 704 | flags |= FILE_FLAG_OPEN_REPARSE_POINT; |
710 | buf->st_ino = hdata.nFileIndexLow | | 705 | fh = CreateFile(file_name, READ_CONTROL, 0, NULL, |
711 | (((ino_t)hdata.nFileIndexHigh)<<32); | 706 | OPEN_EXISTING, flags, NULL); |
712 | buf->st_nlink = (buf->st_attr & FILE_ATTRIBUTE_DIRECTORY) ? | 707 | if (fh != INVALID_HANDLE_VALUE) { |
713 | count_subdirs(file_name) : | 708 | if (GetFileInformationByHandle(fh, &hdata)) { |
714 | hdata.nNumberOfLinks; | 709 | buf->st_dev = hdata.dwVolumeSerialNumber; |
710 | buf->st_ino = hdata.nFileIndexLow | | ||
711 | (((ino_t)hdata.nFileIndexHigh)<<32); | ||
712 | buf->st_nlink = (buf->st_attr & FILE_ATTRIBUTE_DIRECTORY) ? | ||
713 | count_subdirs(file_name) : | ||
714 | hdata.nNumberOfLinks; | ||
715 | } | ||
716 | buf->st_uid = buf->st_gid = file_owner(fh, buf); | ||
717 | CloseHandle(fh); | ||
718 | } else { | ||
719 | buf->st_uid = buf->st_gid = 0; | ||
720 | buf->st_mode &= ~S_IRWXO; | ||
715 | } | 721 | } |
716 | |||
717 | buf->st_uid = buf->st_gid = file_owner(fh, buf); | ||
718 | CloseHandle(fh); | ||
719 | } | ||
720 | else { | ||
721 | buf->st_uid = 0; | ||
722 | buf->st_gid = 0; | ||
723 | if (!(buf->st_attr & FILE_ATTRIBUTE_DEVICE)) | ||
724 | buf->st_mode &= ~(S_IROTH|S_IWOTH|S_IXOTH); | ||
725 | } | 722 | } |
726 | #endif | 723 | #endif |
727 | 724 | ||