aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-12-22 11:16:57 +0000
committerRon Yorston <rmy@pobox.com>2022-12-22 11:16:57 +0000
commitb11352dcbdd94e23224057056594ddc165883c19 (patch)
tree49ec413787f5cf886815408a1f40fbd86d679694
parentaeef07a0752ffdc98e1d5a32c508794b93c9f79d (diff)
downloadbusybox-w32-b11352dcbdd94e23224057056594ddc165883c19.tar.gz
busybox-w32-b11352dcbdd94e23224057056594ddc165883c19.tar.bz2
busybox-w32-b11352dcbdd94e23224057056594ddc165883c19.zip
win32: prevent stat(2) from updating access times
The WIN32 implementation of stat(2) reads the contents of some files to see if they're executable. This may update the file access time. Avoid this by a special call to SetFileTime() after opening the file. For details see: https://devblogs.microsoft.com/oldnewthing/20111010-00/?p=9433 https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfiletime File access times aren't updated by default in recent versions of Windows. This commit is only necessary if updating of file access times is explicitly enabled: fsutil behavior set DisableLastAccess 0
-rw-r--r--win32/mingw.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index 606a48319..8216f2e53 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -432,7 +432,10 @@ mode_t mingw_umask(mode_t new_mode)
432 */ 432 */
433static int has_exec_format(const char *name) 433static int has_exec_format(const char *name)
434{ 434{
435 int n, sig; 435 HANDLE fh;
436 int fd = -1;
437 ssize_t n;
438 int sig;
436 unsigned int offset; 439 unsigned int offset;
437 unsigned char buf[1024]; 440 unsigned char buf[1024];
438 441
@@ -440,8 +443,20 @@ static int has_exec_format(const char *name)
440 if (is_suffixed_with_case(name, ".dll")) 443 if (is_suffixed_with_case(name, ".dll"))
441 return 0; 444 return 0;
442 445
443 n = open_read_close(name, buf, sizeof(buf)); 446 /* Open file and try to avoid updating access time */
444 if (n < 4) /* at least '#!/x' and not error */ 447 fh = CreateFileA(name, GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL);
448 if (fh != INVALID_HANDLE_VALUE) {
449 FILETIME last_access = { 0xffffffff, 0xffffffff };
450
451 SetFileTime(fh, NULL, &last_access, NULL);
452 fd = _open_osfhandle((intptr_t)fh, O_RDONLY);
453 }
454
455 if (fd < 0)
456 return 0;
457
458 n = read_close(fd, buf, sizeof(buf));
459 if (n < 4) /* Need at least a few bytes and no error */
445 return 0; 460 return 0;
446 461
447 /* shell script */ 462 /* shell script */
@@ -453,7 +468,7 @@ static int has_exec_format(const char *name)
453 * Poke about in file to see if it's a PE binary. I've just copied 468 * Poke about in file to see if it's a PE binary. I've just copied
454 * the magic from the file command. 469 * the magic from the file command.
455 */ 470 */
456 if (buf[0] == 'M' && buf[1] == 'Z') { 471 if (buf[0] == 'M' && buf[1] == 'Z' && n > 0x3f) {
457 offset = (buf[0x19] << 8) + buf[0x18]; 472 offset = (buf[0x19] << 8) + buf[0x18];
458 if (offset > 0x3f) { 473 if (offset > 0x3f) {
459 offset = (buf[0x3f] << 24) + (buf[0x3e] << 16) + 474 offset = (buf[0x3f] << 24) + (buf[0x3e] << 16) +