aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-01-18 11:09:13 +0000
committerRon Yorston <rmy@pobox.com>2023-01-18 11:09:13 +0000
commit4c92ce9e14703a3100f1aa9fd90bc3864d9e856b (patch)
tree284eb2d1a341af35e10054ddc98fa6bc020fd197
parentdbd187697d1265d345e3e3e8b302a88b04592cc2 (diff)
downloadbusybox-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.c55
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