Skip to content

kernel+libc: SIGINT SIG_IGN opt-out (PR 2/3)#333

Merged
bboe merged 1 commit intomainfrom
sigint-2-sig-ign
May 8, 2026
Merged

kernel+libc: SIGINT SIG_IGN opt-out (PR 2/3)#333
bboe merged 1 commit intomainfrom
sigint-2-sig-ign

Conversation

@bboe
Copy link
Copy Markdown
Owner

@bboe bboe commented May 7, 2026

Summary

Stacks on #332 (SIGINT default-kill). Adds the next layer of the SIGINT design:

  • SYS_SYS_SIGNAL (0xF5) — userland can register a SIGINT disposition. Currently accepts only SIG_DFL (0) and SIG_IGN (1); user-virt handler addresses are rejected with ERROR_INVALID (maps to EINVAL) until PR 3.
  • signal() libc wrapper in tools/libc/signal.c + tools/libc/include/signal.h — POSIX-shape API that returns the previous handler or SIG_ERR on failure.
  • Shell installs SIG_IGN at startup so a user typing Ctrl+C at the prompt no longer kills + reloads the shell. The cooked 0x03 byte still lands in the line editor, which already cancels the current input line.
  • Children inherit SIG_DFLprogram_enter zeroes sigint_handler on every load, so each new program starts killable. The opt-out is per-program and ephemeral.

The SIGINT_TAIL_CHECK macro in irq_tail.inc now reads sigint_handler and routes to signal_dispatch_kill for SIG_DFL, falls through (after clearing pending_sigint) for SIG_IGN, and treats the not-yet-implemented user-virt case as SIG_DFL.

What's deferred to PR 3

  • User-handler delivery (signal(SIGINT, fn) for arbitrary fn). Needs the sigcontext frame on the user stack, a vDSO __kernel_sigreturn trampoline, SYS_SYS_SIGRETURN (0xF6), and the IRQ-handler restructure that keeps pushad on the stack at dispatch.

Test plan

  • ./make_os.sh clean build
  • ./tests/test_programs.py — 29/29 pass (existing programs unaffected; shell still loads + runs)
  • ./tests/test_asm.py — 20/20 pass (self-hosting NASM byte-equality)
  • ./tests/test_bboefs.py — 6/6 pass

Manual verification of the opt-out behaviour comes in PR 3 alongside the user-handler smoke test (tests/programs/sigint_test.c).

🤖 Generated with Claude Code

@bboe bboe force-pushed the sigint-2-sig-ign branch from 57e497b to 5dab05d Compare May 8, 2026 00:41
@bboe bboe force-pushed the sigint-1-default-kill branch from 6682d75 to d3e41c1 Compare May 8, 2026 01:00
@bboe bboe force-pushed the sigint-2-sig-ign branch from 55a0edb to ae284d2 Compare May 8, 2026 01:10
Base automatically changed from sigint-1-default-kill to main May 8, 2026 01:46
@bboe bboe force-pushed the sigint-2-sig-ign branch 6 times, most recently from 904c56d to e7b7593 Compare May 8, 2026 03:35
Adds SYS_SYS_SIGNAL (0xF5) accepting SIG_DFL or SIG_IGN; user-virt
handlers are rejected with EINVAL until the follow-up PR.  Adds a
libc signal() wrapper.  Shell installs SIG_IGN at startup so its
own Ctrl+C is benign; children inherit SIG_DFL from program_enter.

ERROR_INVALID gets the next free numeric slot (09h, appended after
PR 1's renumber) rather than being inserted alphabetically — that
would have shifted the already-merged ERROR_NOT_EMPTY / NOT_EXECUTE
/ NOT_FOUND / PROTECTED values which are now ABI-stable.  Source
order keeps the new code at the bottom of the block; future
additions follow the same append-at-next-free convention.

Builds on PR 1 (SIGINT default-kill) and PR 336 (CR3 swap fix).
PR 3 (next) adds full user-handler delivery via sigcontext +
sigreturn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bboe bboe force-pushed the sigint-2-sig-ign branch from e7b7593 to e13de04 Compare May 8, 2026 03:49
@bboe bboe merged commit 5142a9d into main May 8, 2026
17 checks passed
@bboe bboe deleted the sigint-2-sig-ign branch May 8, 2026 04:05
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.

1 participant