Skip to content

fix(libkernel): return EPERM when unlinking a directory - #2289

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
reyani-dev:fix/libkernel-unlink-directory-eperm
Oct 10, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
reyani-dev:fix/libkernel-unlink-directory-eperm

Conversation

@reyani-dev

Copy link
Copy Markdown
Contributor

What

FreeBSD's unlink(2) fails with EPERM when the path is a directory. sceKernelUnlink passed the host error through, so the guest got a different code on each host:

Host unlink("dir") on main FreeBSD
Windows (_wunlink) EACCES (13), measured EPERM (1)
Linux (unlink) EISDIR (21), per unlink(2) EPERM (1)

sceKernelUnlink now checks the path with symlink_status before unlinking and returns EPERM for a directory. A symbolic link to a directory is still unlinked, as on FreeBSD. If the path can't be inspected, the check doesn't match and the native unlink reports its own error as before. unlink (the POSIX wrapper) goes through sceKernelUnlink, so both are covered.

Tested

Windows 11, WinLibs GCC 15.2.0 r7, Release, -DBUILD_TESTING=ON:

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

🤖 Generated with Claude Code

FreeBSD's unlink(2) reports EPERM for a directory, but the host call
returns EACCES on Windows and EISDIR on Linux, so the guest saw a
different error on each host. Check for a directory, not following a
symbolic link, before unlinking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@reyani-dev

Copy link
Copy Markdown
Contributor Author

Full Linux and Windows builds and tests for this head (27516327), using the project's Build workflow. I can't start the upstream manual run, so I ran the same build.yml in my fork through a mirror PR. Like the upstream run, the jobs check out the PR head merged into current main (d70b8998):

Job Result
linux success; full build, ctest: 516/516 passed
windows success; full build, ctest: 507/507 passed
relinker (Linux, Windows, macOS) success

Run: https://github.com/AchrafReyani/AnyPS5/actions/runs/37946468349

oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 10, 2026
oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 10, 2026
@oneandonlydean
oneandonlydean merged commit 65bd2f7 into boykopovar:main Oct 10, 2026
8 checks passed
SleglJan pushed a commit to SleglJan/AnyPS5 that referenced this pull request Oct 10, 2026
…link-directory-eperm

fix(libkernel): return EPERM when unlinking a directory
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.

2 participants