Skip to content

fix(libkernel): translate scalar POSIX I/O errors - #1307

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
ebarr24:codex/luna-posix-file-errors
Oct 11, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
ebarr24:codex/luna-posix-file-errors

Conversation

@ebarr24

@ebarr24 ebarr24 commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

What

AnyPS5 relinks guest executables into native Windows/Linux user-space programs. Its libkernel POSIX imports read, _read, write, _write, and lseek currently let ordinary file failures escape as host exceptions. Translate recognized failures to -1 and guest errno, including Linux EAGAIN 11 to FreeBSD guest 35. Preserve successful values, 64-bit seek offsets, previous errno on success, direct sceKernel behaviour, and unsupported-operation diagnostics.

The public synthetic VABI regression exercises file and pipe I/O, invalid descriptors/access modes/buffers/whence, zero-length null buffers, sparse seeking beyond 4 GiB, and Linux nonblocking-pipe EAGAIN. This corrects an existing Status file capability, with no measured title progress or library/shader badge increase.

Tested

  • Windows 11 build 26200 x64, GCC 15.2.0, CMake 4.4.4, Ninja 1.13.2, Full profile, 4 compile jobs.
  • Matching upstream base df16c4c256be3c44e03eb9149a6ce5f8e8a038b2: Full build passed. The identical guest_posix_scalar_io fixture ran successful I/O controls, then deliberately aborted at its contract assertion because read(-1, buffer, 1) threw sceKernelRead: read failed, fd=-1, errno=9 instead of returning -1 with guest EBADF. Zero skipped.
  • Clean committed head 2799d71161978bd4e2f1a548451f50ce3b422942: Full build/focused regression passed; complete Windows CTest 405 passed, 0 failed, 0 skipped. Conventions and diff checks passed.
  • Exact-commit Ubuntu 24.04 Build: 387 passed, 22 skipped, 0 failed, with --repeat until-fail:3. The scalar regression, including unconditional Linux nonblocking-pipe EAGAIN mapping, passed every repetition. Each skipped GPU execution test has an individually checked 32-lane subgroup capability guard and is unrelated to scalar I/O. Exact runner subgroup width is unmeasured. The Windows job in this workflow passed separately.
  • Public synthetic native guest ABI fixture only; no title, relinked guest ELF or console firmware tested.

Checklist

  • Based on current main; no other open PR implements the same fix (complete inventory and shared-file review)
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw; no silent stubs added
  • No notes, investigation files or images added to the repository
  • No new third-party code
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Please have sceKernelRead/sceKernelWrite/sceKernelLseek (Open.cpp:141-163) return the SCE error and route the POSIX wrappers through PosixResult, as open/stat/unlink already do, instead of matching the exception text in PosixScalarResult (Stdio.cpp:287).

@hikazey

hikazey commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Linux data point from a real title: DOOM Shareware PPSA99666 v1.1.1 (lowbit/ps5-doom) needs this on Linux. While it scans /download0 for WADs, it opens the directory itself with O_RDONLY and reads a 12-byte header from it. On main (0e173a46, with #1278 and #1279 merged locally) that aborts the process:

terminate called after throwing an instance of 'std::runtime_error'
  what():  sceKernelRead: read failed, fd=7, errno=21

strace shows the host call is read(7, …, 12) = -1 EISDIR. With this PR merged locally the read returns an error to the title, and it continues to its launcher and E1M1 (Ubuntu 24.04 container, GCC 14.2, Mesa llvmpipe). The bundled libc.prx also has to be excluded (#1497).

AI-assisted: yes (Claude Code).

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, and thanks @hikazey for the DOOM data point (a read on a directory aborting on EISDIR is a good reason for this fix).

Still open from @oneandonlydean's review, which isn't addressed yet:

  • PosixScalarResult (Stdio.cpp:287-309) matches the exception text prefix and reads the host errno after the throw. Please make sceKernelRead/sceKernelWrite/sceKernelLseek (Open.cpp:141-163) return the SCE error and have the POSIX wrappers go through PosixResult, like open/stat/unlink do. That removes the string match and most of GuestScalarIoErrno's duplicated table.
  • The windows job is red on the current head; please check it.
  • The branch now conflicts with main in core/libs/CMakeLists.txt (test block adjacency); please rebase.

The regression test itself looks good and covers the right cases; it should keep working after the rework. Happy to re-review once updated.

@adriadam10
adriadam10 force-pushed the codex/luna-posix-file-errors branch from 2799d71 to ba46784 Compare October 11, 2026 08:59

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Took over the three open points, pushed on top of your commit:

  • sceKernelRead/sceKernelWrite/sceKernelLseek (Open.cpp) now return the SCE error instead of throwing on a native failure (SceIoErrorFromErrno: host EAGAIN -> 35, EDEADLK -> 11, EDQUOT/EOVERFLOW -> FreeBSD values; 1..34 are identical on FreeBSD). The POSIX wrappers go through PosixResult like open/stat/unlink; PosixScalarResult, the exception-text match and the duplicated errno table are gone.
  • Rebased on main (conflicts in core/libs/CMakeLists.txt and Stdio.cpp).
  • Kept your regression test and added: direct sceKernelRead/Write/Lseek on fd -1, the direct nonblocking-pipe EAGAIN, and read on a directory returning EISDIR (the DOOM case, non-Windows).

Checked on Linux: guest_posix_scalar_io, guest_directory_entries, guest_file_vector, guest_parent_process pass; the new test fails without the code changes. Merging once CI is green on the new head.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 11, 2026
@adriadam10
adriadam10 merged commit a0165d6 into boykopovar:main Oct 11, 2026
14 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