Skip to content

fix(libkernel): translate host errno in the file functions' SCE errors - #3681

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
zmeizy:claude/kernel-file-errno-translation
Oct 11, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
zmeizy:claude/kernel-file-errno-translation

Conversation

@zmeizy

@zmeizy zmeizy commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

What

SceErrorFromErrno in libkernel/File/src/Stdio.cpp builds 0x80020000 | errno from the host errno. It passes values up to 34 through unchanged and turns everything else into EIO. Up to 34, Linux and FreeBSD numbering agree except for 11: Linux EAGAIN is 11, which is FreeBSD EDEADLK. Above 34 the two differ, so real errors were reported as EIO. For example, a non-blocking sceKernelReadv on an empty pipe returned 0x8002000b (EDEADLK) instead of 0x80020023 (EAGAIN). sceKernelMkdir with a too-long name returned EIO instead of ENAMETOOLONG (0x8002003f). The POSIX wrappers derive the guest errno from these codes, so readv and mkdir reported the wrong errno as well.

This maps the host values that differ to their FreeBSD numbers, using the host's own macros, so the mapping is the same on Linux and Windows:

  • EAGAIN → 35
  • EDEADLK → 11
  • ENAMETOOLONG → 63
  • ENOTEMPTY → 66
  • ELOOP → 62
  • EDQUOT → 69
  • EOVERFLOW → 84

Values up to 34 still pass through, and anything else still becomes EIO. The guest constants the file passes in itself are unchanged.

Sources: FreeBSD sys/sys/errno.h for the guest numbers. Open.cpp's SceIoErrorFromErrno already applies the same values for EAGAIN, EDEADLK, EDQUOT and EOVERFLOW.

Related: #2144 rewrites the separate mapping in Open.cpp; this PR changes only Stdio.cpp's. Both add an ErrorEagain constant and #include <fcntl.h> to GuestFileVector.cpp (#2144 for sceKernelRead, this PR for sceKernelReadv), so whichever merges second drops the duplicate constant.

Tested

Ubuntu 24.04, GCC 13.3, on main a11c8f7f.

  • guest_file_vector: new check that a non-blocking sceKernelReadv on an empty pipe returns 0x80020023 and readv sets errno 35 (skipped on Windows, which has no O_NONBLOCK pipes).
  • guest_filesystem: new check that sceKernelMkdir with a 300-character name returns 0x8002003f and mkdir sets errno 63.
  • Both tests abort on main without the change and pass with it.
  • Full ctest --timeout 120 --parallel 4 with the change: 832 tests. 4 fail, none related to this change:

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 (n/a)
  • 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 (n/a)
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA

SceErrorFromErrno in the libkernel file functions passed host errno
values 1-34 through and turned every other value into EIO. Linux numbers
EAGAIN 11, which is FreeBSD's EDEADLK, so a read from an empty
non-blocking pipe returned SCE_KERNEL_ERROR_EDEADLK, and ENAMETOOLONG,
ELOOP, ENOTEMPTY, EDQUOT and EOVERFLOW, whose host values differ from
FreeBSD's, all became EIO.

Map those host values to the guest's FreeBSD numbers, as
SceIoErrorFromErrno in Open.cpp already does for EAGAIN, EDEADLK,
EDQUOT and EOVERFLOW. The guest constants the callers pass are all at
most 34 and never 11, or GUEST_ENOTEMPTY, so they are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ha6Tsy62AFUyp9a5Mf7vjA
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the errno mapping against FreeBSD sys/sys/errno.h (EAGAIN 35, EDEADLK 11, ENAMETOOLONG 63, ELOOP 62, ENOTEMPTY 66, EDQUOT 69, EOVERFLOW 84) and against Open.cpp's existing mapping; build and ctest of core/libs pass, and both new checks fail when the Stdio.cpp change is reverted. Merging.

@adriadam10
adriadam10 merged commit 4658391 into boykopovar:main Oct 11, 2026
15 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.

3 participants