Skip to content

feat(libkernel): report no child processes from waitpid - #2123

Merged
adriadam10 merged 4 commits into
boykopovar:mainfrom
LuisBiceps:feat/libkernel-waitpid-no-children
Oct 10, 2026
Merged

adriadam10 merged 4 commits into
boykopovar:mainfrom
LuisBiceps:feat/libkernel-waitpid-no-children

Conversation

@LuisBiceps

@LuisBiceps LuisBiceps commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

What

Exports waitpid (NID dTnYqqLIQ6c) from libkernel. AnyPS5 runs the title as one host process and exports nothing that creates a child (fork, vfork, rfork, posix_spawn), so waitpid answers the way FreeBSD 11's kernel does for a process without children:

  • Option bits outside WNOHANG, WUNTRACED, WCONTINUED, WNOWAIT, WEXITED, WTRAPPED and WLINUXCLONE return -1 with errno EINVAL (kern_wait6, L1206-L1209).
  • Any other call returns -1 with ECHILD, whatever the pid and with or without WNOHANG. The kernel finds no child or orphan before it looks at WNOHANG (L1307-L1314). waitpid adds WEXITED | WTRAPPED (L1146), so the "no events to wait for" EINVAL cannot happen.
  • The status is not written: wait4 copies it out only when a child was reaped (L771-L772).
  • libthr makes wait4 a cancellation point. No cancel request is ever pending here (Thread cancellation in TechnicalDebt), so returning at once matches.
  • Recorded in TechnicalDebt (Functional): a way to create child processes would need a real waitpid.

VLC (PPSA85300) is a port of VLC 3.0.24 and never has a child on the console either. Its compat layer makes fork and vfork fail with ENOSYS as "Features the PS5 doesn't have" (libc_missing.c L290-L292). Its netconf patch drops VLC's libproxy helper because "a title can't start programs (posix_spawnp crashed the app ...)" (0006-netconf-ps5-no-proxy-helper.patch L8-L11).

Other titles that import waitpid:

VLC 0.2, from its GitHub release (its listing in the homebrew catalog is pending), relinked with --windows and run on Windows 10:

  • main d70b899: FAIL: unresolved ELF import dTnYqqLIQ6c from libkernel.prx (waitpid)
  • main + this PR: FAIL: unresolved ELF import 0NJDcQ2B8vE from libkernel.prx (execvp, left for its own PR)

VLC 0.1 stops at the same two imports.

Tested

  • New guest_waitpid test, registered in ctest with a 20 s timeout. Every case is run twice, once with a status pointer and once with a null one. errno is cleared before each call, and every call must return -1 and leave the status untouched.
    • Pids: -1, 0, 1, its own pid, its pid + 1, and its own process group (minus its pid).
    • Valid options: each pid is tried with 0, each known bit alone, combinations such as WNOHANG | WUNTRACED and WNOHANG | WLINUXCLONE, and all known bits. Every call must give errno 10 (ECHILD).
    • Unknown options: each pid is tried with 0x40, 0x41, 0x80, 0x100, 0x40000000, 0x80000040 and all bits. Every call must give 22 (EINVAL).
  • Windows 10, MinGW-w64 GCC 15.2.0 (WinLibs 15.2.0posix-14.0.0-ucrt-r7), Release, merged with main d70b899: passes (--repeat until-fail:3), and so does the full suite. The NID-patched libkernel.prx exports the NID.
  • Ubuntu 26.04.1 (WSL2), GCC 15.2.0, Release, ANYPS5_ENABLE_SPIRV_TOOLS=ON, merged with main d70b899: passes (--repeat until-fail:3), and so does the full suite. The NID-patched libkernel.prx exports the NID.
  • The test fails against 24 deliberate breakages:
    • returning 0 or the pid, throwing, or blocking without WNOHANG;
    • ignoring the options, or always EINVAL;
    • an option mask missing WNOHANG, WNOWAIT, WTRAPPED or WLINUXCLONE, or accepting 0x40, 0x80 or 0x40000000;
    • EINVAL checked only for pid -1, or WNOHANG | WUNTRACED rejected;
    • writing the status, faulting on or rejecting a null status, leaving errno alone, or returning 0 for WNOHANG;
    • ESRCH for a positive pid, or EINVAL for a process group;
    • errno values off by one.
  • tools/check_conventions.py and tools/check_test_registration.py pass.

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

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Progress report (ddcb251 → 8de5e70)

➖ System libraries: 85.77% (+0.0%, +1 implemented functions)

✅ 1 implemented
Library Name
libkernel waitpid_nid_postfix

@MarcZX10

MarcZX10 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

I reviewed the full diff and checked the behavior against the cited FreeBSD implementation. waitpid adds WEXITED | WTRAPPED before calling kern_wait6; that path rejects unknown options and option sets with no wait events before scanning children, then returns ECHILD when no child matches. sys_wait4 copies status only after a successful nonzero child result. Those paths support this implementation’s option check, ECHILD result and untouched status when the title has no children (kern_exit.c, option validation and child scan, status copyout).

The full diff has useful option, pid-form and untouched-status coverage, and no duplicate open PR implements waitpid. The current PR base is still d9484c71 while current main is 3bd74c15; please rebase and refresh the tested-base note before approval. The latest Actions run skips full Linux/Windows builds under the manual Build policy; the targeted runs in the description provide the available runtime evidence.

@LuisBiceps
LuisBiceps marked this pull request as ready for review October 9, 2026 12:26
@LuisBiceps

Copy link
Copy Markdown
Contributor Author

Thanks for checking it against kern_wait6. I brought the branch up to main d70b899 with a merge rather than a rebase, so the commits you reviewed are unchanged; it had no conflicts and the diff is the same four files. The description now uses that base:

  • VLC 0.1 and 0.2 still stop at waitpid on main d70b899 and reach execvp with this PR (Windows 10).
  • guest_waitpid passes --repeat until-fail:3 on the merged head on Windows 10 and Ubuntu 26.04, and so do the full suites.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Two things before this can go in:

  • Rebase onto main and force-push instead of the merge commit (72a9ca4); branches here don't take merge commits.
  • Cut the TechnicalDebt entry to a sentence or two, e.g. "waitpid returns -1 with ECHILD (EINVAL for unknown options): nothing here creates a child process; child processes would need a real waitpid." The FreeBSD links can stay in the description.

@babyhuey

Copy link
Copy Markdown
Contributor

Checked on current main ee50132 with this PR (72a9ca4) merged (clean), Linux (Ubuntu 24.04, GCC 13) and Windows 11 (MinGW-w64 GCC from WinLibs), Release.

  • guest_waitpid passes 5/5 on both (--repeat until-fail:5); no CRT assertion dialog on Windows.
  • VLC (PPSA85300) stops at waitpid on main and gets past it on both:
    • Linux: app.elf: symbol lookup error: app.elf: undefined symbol: 0NJDcQ2B8vE (execvp)
    • Windows: FAIL: unresolved ELF import 0NJDcQ2B8vE (execvp) from libkernel.prx

@SCD28

SCD28 commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

I rebuilt the PR changes on current upstream main without the merge commit requested in review.

I also shortened the TechnicalDebt.md entry to one sentence and moved the guest_waitpid CMake registration away from #1908's insertion point. The overlap is textual only; no #1908 code is included and there is no functional dependency between the two PRs.

Tested on Linux / WSL2 Ubuntu 24.04:

  • libkernel build: pass
  • guest_waitpid_tests build: pass
  • guest_waitpid --repeat until-fail:5: 5/5 pass
  • guest_kernel_errors: pass
  • tools/check_conventions.py --base upstream/main: pass
  • tools/check_test_registration.py: pass
  • git diff --check: pass

AI-assisted: yes. (Codex)

Clean branch:
SCD28/AnyPS5:assist/pr-2123-waitpid

Feel free to cherry-pick or reuse the branch if useful. I can keep it rebased on current main if needed.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 10, 2026
@adriadam10

Copy link
Copy Markdown
Collaborator

Rebased onto main (merge commit dropped) and shortened the TechnicalDebt entry to one sentence, as requested. Two trivial conflicts in Process.cpp (next to system/_exit) resolved by keeping both.

Checked on the rebased head: build + ctest of libkernel/libs green, including guest_waitpid; without the change the test does not link (waitpid undefined); behaviour matches kern_wait6 as described. Merging once CI is green.

@adriadam10
adriadam10 force-pushed the feat/libkernel-waitpid-no-children branch from 72a9ca4 to de10146 Compare October 10, 2026 08:09
LuisBiceps and others added 4 commits October 10, 2026 10:11
waitpid returns -1 with ECHILD, or EINVAL for an option FreeBSD does not know, and leaves the status unwritten: AnyPS5 runs the title as one process and exports nothing that creates a child. VLC PPSA85300 stops on main at this import.
…d without a status

Unknown options are now checked for every pid, with 0x80 and 0x80000040 added, and so are valid combinations such as WNOHANG | WUNTRACED. Each call is repeated with a null status. The TechnicalDebt entry cites kern_wait, which adds WEXITED and WTRAPPED, and lists pdfork.
…om lines open pull requests change

waitpid now sits between exit and _exit, and its TechnicalDebt entry follows the packed horizontal gathers entry, so the open system and getuid pull requests and the thread cancellation test pull request no longer touch the same lines.
@adriadam10
adriadam10 force-pushed the feat/libkernel-waitpid-no-children branch from de10146 to 8de5e70 Compare October 10, 2026 08:13
@github-actions github-actions Bot removed needs rebase Conflicts with main, rebase needed labels Oct 10, 2026
@adriadam10
adriadam10 merged commit f6af6d1 into boykopovar:main Oct 10, 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.

6 participants