Skip to content

fix(libc): report POSIX rename errors like the console - #2784

Closed
HyperDarkmoon wants to merge 1 commit into
boykopovar:mainfrom
HyperDarkmoon:fix/libc-rename-errors
Closed

HyperDarkmoon wants to merge 1 commit into
boykopovar:mainfrom
HyperDarkmoon:fix/libc-rename-errors

Conversation

@HyperDarkmoon

Copy link
Copy Markdown

What

Fixes #2403. rename(2) now reports the errors the console (FreeBSD) does instead of collapsing host failures into EIO:

  • missing source, or missing destination parent → ENOENT (2)
  • destination parent is a file, or a directory moved onto a file → ENOTDIR (20)
  • a file moved onto a directory → EISDIR (21)
  • a directory moved onto a non-empty directory → ENOTEMPTY (66)
  • a directory moved into its own subtree → EINVAL (22)
  • null/empty paths keep the existing EFAULT (14) / ENOENT (2) behaviour

On Windows, replacing an existing empty directory now succeeds (the empty target is removed first) instead of failing with EACCES, matching the console's rename(dir, empty_dir) == 0.

Inspection failures are mapped before being read as "absent": not_a_directory → ENOTDIR, a genuine not_found → ENOENT, permission_denied → EACCES, anything else → the EIO fallback.

rename_nid_postfix lives in core/libs/prx/libc/src/Rename.cpp, compiled into both libc and libkernel (from #1192), so the fix applies to both. Reopens and replaces the closed #2485.

Tested

  • Windows 11, WinLibs GCC 15.2.0. Built guest_filesystem_tests and guest_kernel_rename_tests; ctest -R "guest_filesystem|guest_kernel_rename" passes.
  • New cases in GuestFilesystem.cpp cover the matrix above, including directory replacement on Windows.
  • The permission-denied inspection regression is only exercised on Linux (skipped when running as root).
  • tools/check_conventions.py --base origin/main passes.

Checklist

  • Based on current main; no other open PR implements the same functions
  • 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); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

Matches the FreeBSD error matrix from boykopovar#2403: a missing destination parent, a directory replaced with a file or a directory moved into its own subtree report ENOTDIR, EINVAL and other errors instead of the raw host error. Windows now replaces an existing empty directory instead of failing with EACCES, and inspection failures map to the console's errno rather than EIO.
@github-actions github-actions Bot added the intake paused Closed while PR intake is limited to authors with at least 10 PRs merged into main label Oct 10, 2026
@github-actions

Copy link
Copy Markdown

Thank you for your interest in the project! We are sorry, but we cannot accept more PRs while we work through the existing backlog. This PR has been automatically closed and labeled "intake paused". This is not a judgment of the quality of your changes.

@github-actions github-actions Bot closed this Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

intake paused Closed while PR intake is limited to authors with at least 10 PRs merged into main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

libc rename reports wrong errno values on Windows and fails to replace an empty directory

1 participant