Repository navigation
fix(libkernel): report POSIX rename errors from sceKernelRename - #2260
AchrafReyani wants to merge 2 commits into
Conversation
sceKernelRename turned every failure after the source check into EIO, and on Windows std::filesystem::rename itself reports a missing target directory or a directory moved into itself as EIO and refuses to replace an empty directory. Check the rename(2) error conditions before renaming: ENOENT, ENOTDIR, EISDIR, ENOTEMPTY and EINVAL, and on Windows remove the empty target directory first so it is replaced as on the console. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I found one error-mapping case to resolve before approval. |
|
Full Linux and Windows builds and tests for this head (
Run: https://github.com/AchrafReyani/AnyPS5/actions/runs/37937885788 |
|
Thanks for the exact-head fork Build report. The Linux 516/516 and Windows 507/507 suites plus the relinker matrix are useful evidence and close the general build/test gap. The specific status-inspection case I raised remains untested by the listed |
| namespace fs = std::filesystem; | ||
| std::error_code error; | ||
| const auto sourceStatus = fs::symlink_status(source, error); | ||
| if (!fs::exists(sourceStatus)) return GUEST_ENOENT; |
There was a problem hiding this comment.
Could check error before treating !exists(sourceStatus) as ENOENT? symlink_status can set permission_denied while the returned status is not_found, so this branch conflates an inspection failure with a genuinely missing source. The destination-parent and destination status checks below have the same pattern. Please preserve the applicable guest error (or the documented EIO fallback) when inspection fails.
symlink_status and status report a path that cannot be inspected with an error and an unknown type, which the rename checks read as a missing file. Return ENOTDIR and ENOENT only for a path that is not found, EACCES when the inspection is denied and EIO otherwise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Good catch, thanks. Fixed in
To show the test fails without the fix, I'm running it two ways on the fork's Build workflow: this head, and a control branch with only the new test on the previous head ( |
|
Results for
Line 148 is the new |
|
Closing: no title is shown stopping on |
What
sceKernelRenamereturnedENOENTfor a missing source andEIOfor every other failure. On Windows the rename itself also went wrong: MinGW'sstd::filesystem::renamereports some missing paths asEIOand refuses to replace an existing empty directory, which FreeBSD'srename(2)does. Measured onmain(d70b8998) with libstdc++'sstd::filesystem::rename(generic category):std::filesystem::renamesceKernelRenameonmainrename(2)EIOENOENTENOENTEIOEIOENOENTEIOENOTDIREIOENOTDIREIOEISDIREACCESEIOENOTEMPTYEIOEIOEINVALEACCESEIORenameError_nid_no_patchchecks theserename(2)conditions before renaming and returns the guest error, the waysceKernelRmdiralready checks its own. On Windows it removes the empty target directory first, so the replace succeeds as on the console. A rename onto the same file, including a case-only rename on Windows, still goes straight tostd::filesystem::rename. Any other host failure is stillEIO.libc's
renamehas the same Windows behaviour (it callsstd::filesystem::renametoo). I left it alone because #1192 is moving that function into a new file; I can send the same fix for it afterwards.Tested
Windows 11, WinLibs GCC 15.2.0 r7, Release,
-DBUILD_TESTING=ON:New
sceKernelRenamechecks inguest_filesystem_tests, next to the libcrenamechecks:0x8002xxxxcodes;On
mainthe test fails on the first new check (guest errno 5).Mutation check: dropping the Windows empty-directory removal, or the subtree
EINVALcheck, each makeguest_filesystemfail.ctest -E "^agc_|video_out": 249/249 passed, includingguest_kernel_sync, which renames throughsceKernelRename.tools/check_conventions.pypasses, andtools/pr_overlap.py --branchreports no overlap. It also merges cleanly with feat(libkernel): export the POSIX rename #1192, fix(files): isolate guest descriptors from host resources #2170, fix(libkernel): report Linux file birth times accurately #2115, feat(libkernel): implement fdatasync #1620, feat(libkernel): implement sceKernelFdatasync #2129 and fix(libkernel): report EISDIR for path truncation #2086, which touch the same files (git merge-tree).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code