Skip to content

Conversation

@ryanbreen
Copy link
Owner

Summary

This PR completes POSIX signal handling and implements the waitpid syscall with comprehensive test coverage.

Key Changes

waitpid syscall (#61/Wait4)

  • Blocking wait for child process termination
  • WNOHANG support for non-blocking checks
  • Proper wstatus encoding: (exit_code & 0xff) << 8
  • Returns ECHILD (-10) when no children exist

Signal inheritance (fork/exec)

  • Fork: Signal handlers copied to child, pending signals cleared
  • Exec: User-defined handlers reset to SIG_DFL, SIG_IGN preserved
  • Matches POSIX semantics for signal disposition inheritance

SIGCHLD delivery

  • Parent receives SIGCHLD when child terminates
  • Delivered during handle_thread_exit() in process cleanup

Critical bug fix: sigreturn RAX corruption

  • After signal handler returned via sigreturn, parent executed child code path
  • Root cause: sigreturn correctly restored RAX from signal frame, but syscall dispatcher then overwrote it with return value 0
  • Fixed by returning early from sigreturn case in handler.rs to preserve restored registers

New Tests

  • sigchld_test.rs - SIGCHLD delivery and handler execution
  • signal_fork_test.rs - Signal handler inheritance across fork
  • signal_exec_test.rs - Signal reset on exec (with signal_exec_check helper)
  • waitpid_test.rs - Blocking waitpid and WNOHANG behavior
  • wnohang_timing_test.rs - Non-blocking wait timing verification

libbreenix Additions

  • waitpid() wrapper function
  • POSIX macros: wifexited(), wexitstatus(), wifsignaled(), wtermsig()
  • WNOHANG constant (0x1)

Test Results

All 84/84 boot stages pass, including the new signal and waitpid tests.

Test plan

  • All boot stages pass (84/84)
  • sigchld_test verifies SIGCHLD delivery
  • signal_fork_test verifies handler inheritance
  • signal_exec_test verifies handler reset on exec
  • waitpid_test verifies blocking and WNOHANG behavior
  • Existing signal tests continue to pass

🤖 Generated with Claude Code

ryanbreen and others added 2 commits December 31, 2025 05:23
This commit adds full waitpid support and fixes critical signal handling bugs:

## waitpid syscall (#61 Wait4)
- Blocking wait for specific child or any child (pid=-1)
- WNOHANG support for non-blocking poll
- Proper wstatus encoding: (exit_code & 0xff) << 8
- ECHILD error when no children exist

## Signal inheritance
- Fork copies signal handlers to child (signals.fork())
- Exec resets user handlers to SIG_DFL (signals.exec_reset())
- SIGCHLD delivered to parent when child exits

## Critical bug fix: sigreturn RAX corruption
- sigreturn was correctly restoring RAX from signal frame
- But syscall dispatcher then overwrote it with return value (0)
- This caused fork_result=0 in parent after signal handler return
- Fixed by returning early from sigreturn to skip set_return_value()

## New tests (all passing, 84/84 boot stages)
- sigchld_test: SIGCHLD delivery on child exit
- signal_fork_test: Handler inheritance across fork
- signal_exec_test: Handler reset on exec
- waitpid_test: Blocking wait and status verification
- wnohang_timing_test: Non-blocking poll behavior

## libbreenix additions
- waitpid() wrapper function
- POSIX macros: wifexited, wexitstatus, wifsignaled, wtermsig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The exec syscall in fork_test was using the old string API signature.
Updated to use the correct null-terminated byte string format that
matches the current libbreenix exec() function signature.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@ryanbreen ryanbreen merged commit 66684b2 into main Dec 31, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants