Repository navigation
fix(libkernel): leave a file's times untouched when Windows utimes refuses them - #8594
Merged
oneandonlydean merged 1 commit intoOct 20, 2026
Conversation
…fuses them On Windows, utimes, lutimes, sceKernelUtimes and futimes open a FILE_WRITE_ATTRIBUTES handle and only then encode the times. A time the host cannot represent returned EINVAL without calling SetFileTime, and with NTFS last-access updates enabled closing that handle set the file's access time to the current time, so a rejected call still changed the file and guest_file_timestamps failed on "access time preserves microseconds". A rejected time now marks the handle with 0xFFFFFFFF, which SetFileTime documents as preventing operations on the handle from updating the times, before the handle is closed. Error order is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
On Windows, a
utimes,lutimes,sceKernelUtimesorfutimescall that is refused because the host cannot represent a time still changes the file: it sets the file's access time to the current time.guest_file_timestampsfails on it wherever NTFS last-access updates are enabled, at the first check after the rejected calls:NativeUtimesandNativeFutimesopen aFILE_WRITE_ATTRIBUTEShandle and thenSetTimesencodes the times. For a timeWindowsFileTime::Encoderejects (here a modification time ofINT64_MIN,INT64_MAX,-11644473601or-11644473600seconds),SetTimesreturnsEINVALwithout callingSetFileTime, and the handle is closed. On this machine, with last-access updates enabled, opening and closing such a handle in the test process sets the access time to the current time. Whether NTFS itself or a file system filter (such as the antivirus) performs that update was not isolated; a standalone program making the same calls did not reproduce it. A successful call hides it because itsSetFileTimewrites the requested time last.SetFileTimedocuments the remedy: "To prevent file operations using the given handle from modifying the last access time, call SetFileTime immediately after opening the file handle and pass a FILETIME structure that has both the dwLowDateTime and dwHighDateTime members set to0xFFFFFFFF", and the same for the last write time.SetTimesnow does that for both times before returningEINVAL. Nothing else uses the handle in between. The handle is still opened before the times are encoded, so the error order (ENOENTand the other path errors beforeEINVAL) is unchanged, and the accepted path is untouched.Tested
Windows 11 Pro 23H2 (10.0.22631), Intel Core i5-13600K, NTFS volume with
fsutil behavior query disablelastaccessreporting2 (System Managed, Last Access Time Updates ENABLED), WinLibs GCC 15.2.0 r7, Release,BUILD_TESTING=ON.main77e31219c:guest_file_timestampsfails 5 of 5 runs with the message above. With the test instrumented (locally, not part of this PR), the access time is still the requested 1000000000 afterrestore valid timesand reads the current time right after the first rejectedutimes. In the same process, a bareCreateFileW(FILE_WRITE_ATTRIBUTES, FILE_FLAG_BACKUP_SEMANTICS)andCloseHandleon the fixture also sets the access time to the current time, and withSetFileTime(handle, nullptr, {0xFFFFFFFF, 0xFFFFFFFF}, {0xFFFFFFFF, 0xFFFFFFFF})before the close it does not.utimesand four rejectedfutimescalls, and the unmodifiedguest_file_timestampspasses 10 of 10 (ctest --repeat until-fail:10).libstarget onmainae12a951fwith this change (plus test(agc): align the array window test's texels at run time #8310's change, uncommitted, so that the default Windows build completes):ctest --parallel 8 --timeout 120passes 1757 of 1763. The six failures (windows_fixed_base,optional_plt,empty_tls,windows_address_space,windows_bss,windows_icon) also fail without this change: the executables these relinker tests create are blocked by the antivirus on this machine, as BUILD.md describes for four of them.python3 tools/check_conventions.py --base origin/mainpasses. GitHub's Windows runners passguest_file_timestampsonmain; their last-access setting is not known to me, and this change does not alter the accepted path they take.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)