Skip to content

fix(libkernel): lutimes reports ENOTDIR for a path through a file - #11218

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
Gruzzberry:fix/lutimes-enotdir
Oct 26, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
Gruzzberry:fix/lutimes-enotdir

Conversation

@Gruzzberry

@Gruzzberry Gruzzberry commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

What

lutimes on a path whose parent is a regular file, or a link to a regular file (file/child, file-link/child), failed with ENOENT. FreeBSD 11.4's kern_lutimes does a namei lookup with NOFOLLOW, which fails with ENOTDIR when a non-final component is not a directory (the link is followed because it is not the final component). utimes and sceKernelUtimes already map the Windows "not found" result through NotFoundError_nid_no_patch, which gives ENOTDIR here; lutimes skipped that mapping. It now uses the same one-line mapping.

I also probed truncate, utimes and lutimes through Windows file links, directory links, dangling links and link loops against the same source: truncate follows links (file link truncates the target, directory link EISDIR, dangling ENOENT, loop ELOOP), utimes follows links, and lutimes changes the link itself, including a dangling link and a loop. All of those already matched, so only the ENOTDIR mapping changes.

Known limit: NotFoundError_nid_no_patch treats a dangling Windows link in a non-final position as an existing non-directory (MinGW std::filesystem::status does not see Windows links), so lutimes("dangling-link/child") now gives ENOTDIR where FreeBSD gives ENOENT. utimes, truncate, chmod and lstat already behave this way through the same helper on main; fixing the helper is a separate follow-up PR that changes all of them together.

Tested

Windows 11 (10.0.26200), WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, -DBUILD_TESTING=ON, on main a940685.

  • guest_file_timestamps: new checks for utimes and lutimes on file/child (ENOTDIR), and, where Windows links can be created, utimes through a file link and a directory link, utimes on a dangling link (ENOENT), lutimes on a directory link and a dangling link (changes the link, not the target), and both calls on file-link/child (ENOTDIR). On main the test fails (ENOENT where ENOTDIR is expected); with this change it passes, three runs out of three.
  • Full suite on this branch: the only failures are pr_overlap_encoding, agc_host_import_cut_lifetime and agc_driver_depth_plane_partial_store, which fail on main in this environment too.
  • python tools/check_conventions.py --base upstream/main: passes.
  • Not tested: Linux, a console, a title run.

Overlaps

tools/pr_overlap.py reports no line overlap. It could not compare Stdio.cpp against 11 older pull requests that conflict with main themselves (#5021, #6936, #7121, #7201, #7447, #8520, #9284, #9293, #9297, #9302, #9823). #9374 changes the link creation in the lutimes part of the same test file; the new checks here are in a separate block at the end of main.

Checklist

  • Based on current main; no other open PR implements the same function
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); no silent stubs added
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source: none added
  • Generic behaviour, not specific to one title
  • Depends on: none; merge order: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

AI-assisted (Claude Code).

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Gruzzberry
Gruzzberry marked this pull request as ready for review October 25, 2026 22:07

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 4dc65b0c6f40746db22cd45dcada465ca5801805. The one-line change applies the same ENOENT translation already used by utimes to lutimes; the added tests cover paths through a regular file and Windows file links, plus link-vs-target timestamp behavior. The PR documents the remaining dangling-link limitation.

Current-main conventions and git diff --check pass. The latest hosted conventions, eligibility, intake, labels and report checks pass; product build jobs are skipped by path policy. The Windows timestamp tests and full-suite comparison are author-reported; I could not rerun them in this environment. I found no concrete issue in the reviewed change. I’m leaving this as a COMMENTED review because the PR is still marked draft.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction to my prior review: the PR was marked ready at 22:07:39, before I submitted my 22:08:16 COMMENTED review. My statement that it was still a draft was stale.

I reviewed exact head 4dc65b0c6f8.... The change applies the same ENOENT translation already used by utimes to lutimes; the new tests exercise paths through files and Windows links, and the PR documents the remaining dangling-link limitation. Current-main conventions and git diff --check pass. Hosted eligibility, conventions, intake, labels and report checks pass; product build jobs are skipped by path policy. The Windows tests and full-suite comparison are author-reported and I could not rerun them here. I found no concrete issue in the changed behavior.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

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.

Pull request Shared files not compared
PR 5021 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 6936 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 7121 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 7201 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 7447 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 9161 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 9284 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 9293 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 9297 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 9302 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 9473 core/libs/prx/libkernel/File/src/Stdio.cpp
PR 11341 core/libs/prx/libkernel/File/src/Stdio.cpp

@wachi35676

Copy link
Copy Markdown
Contributor

Windows and Linux runs of head 4dc65b0c6f40 merged onto main 0f34ebb85. Windows used WinLibs GCC 15.2.0 (links can be created, so the link block runs), Linux used WSL with GCC 13; both Release.

AI-assisted: yes (Claude Code); results above were run on this machine.

@oneandonlydean oneandonlydean self-assigned this Oct 26, 2026
@oneandonlydean
oneandonlydean merged commit 0bad0fc into boykopovar:main Oct 26, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants