These docs are under active development and cover the v0.20 Kobicha security model.
On this page
reference 10 min read

Standard Signals Catalogue

This page catalogues the 31 standard POSIX signals (numbers 1 through 31). Each entry gives the signal's default action, the process access mask required to send it from userspace, and any notes specific to its use on Peios.

For real-time signals (numbers 32–64), see Real-Time Signals.

For the security model and the rationale behind the access-mask split, see Signals on Peios.

Quick-reference table

The default action determines which access mask gates the signal:

# Name Default action Required mask
1 SIGHUP Terminate PROCESS_TERMINATE
2 SIGINT Terminate PROCESS_TERMINATE
3 SIGQUIT Terminate + core PROCESS_TERMINATE
4 SIGILL Terminate + core (kernel-generated)
5 SIGTRAP Terminate + core (kernel-generated)
6 SIGABRT Terminate + core PROCESS_TERMINATE
7 SIGBUS Terminate + core (kernel-generated)
8 SIGFPE Terminate + core (kernel-generated)
9 SIGKILL Terminate (uncatchable) PROCESS_TERMINATE
10 SIGUSR1 Terminate PROCESS_TERMINATE
11 SIGSEGV Terminate + core (kernel-generated)
12 SIGUSR2 Terminate PROCESS_TERMINATE
13 SIGPIPE Terminate (kernel-generated)
14 SIGALRM Terminate (kernel-generated for own timer)
15 SIGTERM Terminate PROCESS_TERMINATE
16 SIGSTKFLT Terminate PROCESS_TERMINATE
17 SIGCHLD Ignore (kernel-generated)
18 SIGCONT Continue PROCESS_SUSPEND_RESUME
19 SIGSTOP Stop (uncatchable) PROCESS_SUSPEND_RESUME
20 SIGTSTP Stop PROCESS_SUSPEND_RESUME
21 SIGTTIN Stop PROCESS_SUSPEND_RESUME
22 SIGTTOU Stop PROCESS_SUSPEND_RESUME
23 SIGURG Ignore PROCESS_SIGNAL
24 SIGXCPU Terminate + core (kernel-generated for own limit)
25 SIGXFSZ Terminate + core (kernel-generated for own limit)
26 SIGVTALRM Terminate (kernel-generated for own timer)
27 SIGPROF Terminate (kernel-generated for own timer)
28 SIGWINCH Ignore PROCESS_SIGNAL
29 SIGIO / SIGPOLL Terminate (kernel-generated)
30 SIGPWR Terminate PROCESS_TERMINATE
31 SIGSYS Terminate + core (typically kernel-generated by seccomp)

Where the table says "(kernel-generated)", the signal is normally produced by the kernel in response to a hardware fault, a resource-limit overrun, an asynchronous I/O event, or a child-state transition — no userspace agent is sending it, and no SD check is performed at delivery. A userspace process can still send these signals deliberately via kill(), in which case the listed access mask applies; but the common case is the kernel-generated path.

Termination signals

SIGHUP (1) — hangup

Originally signalled to a process when its controlling terminal closed (modem hangup, terminal-window close). Modern usage is overwhelmingly the convention "reload your configuration": daemons commonly install a SIGHUP handler that re-reads config files, reopens log files, and resumes operation without losing in-flight work.

Default action: terminate. A process that does not handle SIGHUP and whose controlling terminal closes will exit.

SIGINT (2) — interrupt

Sent by the terminal driver when the user types Ctrl+C. Default action is terminate. Foreground processes typically handle this to perform graceful shutdown; long-running CLI tools commonly use it to interrupt the current operation without exiting the program.

SIGQUIT (3) — quit

Sent by the terminal driver when the user types Ctrl+. Default action is terminate with a core dump — historically used to capture a snapshot of a hung program for debugging. Modern programs often handle SIGQUIT to print thread stacks (the JVM does this) before exiting.

SIGABRT (6) — abort

Raised by the C library abort() function and by assert() failures. Default action is terminate with core dump. The standard signal for "the program has detected an unrecoverable inconsistency and is choosing to die noisily." Handlers may catch SIGABRT to perform last-rites cleanup but should not prevent termination — the C library will reraise it after the handler returns.

SIGKILL (9) — kill

The forced termination signal. Cannot be caught, blocked, or ignored. A process receiving SIGKILL is terminated immediately by the kernel; the receiver has no opportunity to clean up, write final state, or notify peers.

SIGKILL is the lever of last resort. It is also the only signal guaranteed to terminate any target a sender has authority over: a misbehaving process trapping every other signal cannot trap this one. The combination of PROCESS_TERMINATE plus PIP dominance plus the uncatchability of SIGKILL is what makes kernel-level lifecycle management work.

SIGTERM (15) — terminate

The graceful termination request. Identical to SIGKILL in default action (terminate the process) but catchable, blockable, and ignorable. Software that wants to be a good citizen handles SIGTERM by completing in-flight requests, flushing buffers, releasing resources, and exiting cleanly.

The standard shutdown idiom is "send SIGTERM, wait some grace period, send SIGKILL if still alive." peinit follows this pattern when stopping services.

SIGUSR1, SIGUSR2 (10, 12) — user-defined

Reserved for application-specific use. The kernel never generates them; their meaning is whatever the application defines. Common uses include log rotation, statistics dumping, and toggling debug modes.

SIGPWR (30) — power failure

Originally signalled by UPS daemons to indicate imminent power loss. On Peios, power-management events are propagated through eventd and the registry; SIGPWR is supported for compatibility with software that still listens for it but is not the primary mechanism.

SIGSTKFLT (16) — stack fault

Defined in the ABI but unused on modern hardware. Linux declares it for compatibility; Peios does the same. Sending SIGSTKFLT works (it requires PROCESS_TERMINATE) but no kernel path generates it.

Stop and continue

SIGSTOP (19) — stop

The forced stop. Cannot be caught, blocked, or ignored. The target process halts execution and waits for SIGCONT. SIGSTOP is the suspend-side counterpart of SIGKILL: a sender holding PROCESS_SUSPEND_RESUME plus PIP dominance can always pause the target regardless of what handlers it has installed.

SIGTSTP (20) — terminal stop

Sent by the terminal driver when the user types Ctrl+Z. Like SIGSTOP, the default action is to stop the process — but unlike SIGSTOP, it is catchable. Programs that want to perform cleanup before suspending (saving cursor position, restoring terminal state) handle SIGTSTP, do their work, then send themselves a real SIGSTOP to actually pause.

SIGCONT (18) — continue

Resumes a stopped process. The default action is "continue if stopped" — there is no behaviour for an already-running process, so it is generally safe to send. Catchable, but most handlers exist only for trace logging.

SIGTTIN, SIGTTOU (21, 22) — background terminal access

Sent to a backgrounded process that attempts to read from (SIGTTIN) or write to (SIGTTOU, when stty tostop is set) the controlling terminal. Default action is to stop the process. Shells use these signals to enforce the "background processes don't take over the terminal" semantics.

Informational signals

SIGCHLD (17) — child state change

Sent to a parent process when one of its children changes state (exits, is killed by a signal, stops, continues). The default action is ignore, meaning a parent that does not install a handler will not be notified — but the kernel still queues the child as a zombie until reaped. See Process Lifecycle for the wait-and-reap discussion.

A handler installed for SIGCHLD typically calls waitpid() in a loop with WNOHANG to reap any newly-finished children. Mismanagement of SIGCHLD is a classic source of zombie leaks.

SIGURG (23) — urgent socket data

Sent when out-of-band data arrives on a socket. Almost no modern protocol uses TCP urgent data, so SIGURG is rarely seen. Default action is ignore. Sending SIGURG to another process requires PROCESS_SIGNAL (the lightweight informational mask) — there's no security justification for restricting it further; the receiver chooses whether to handle it.

SIGWINCH (28) — window change

Delivered when the controlling terminal's size changes (the user resized the terminal window). Default action is ignore. Programs that lay out their output based on terminal width — text editors, less, htop — install a handler that re-reads the terminal size and redraws.

PROCESS_SIGNAL is the right mask: terminal emulators and tmux/screen legitimately need to send SIGWINCH to many processes, often crossing user boundaries (a multi-user tmux server sending SIGWINCH to children running as different users), without those processes granting the heavyweight PROCESS_TERMINATE.

Hardware faults (kernel-generated)

These signals are delivered to a process by the kernel in response to a fault the process itself caused. They bypass the SD check entirely — there is no userspace agent to authorise.

SIGSEGV (11) — segmentation violation

The most common fault signal. Raised when the process accesses memory that is not mapped, or accesses memory in a way the mapping does not permit (writing a read-only page, executing a non-executable page). The siginfo si_code distinguishes the cause: SEGV_MAPERR (no mapping at the address), SEGV_ACCERR (mapping exists but the access is not permitted), SEGV_PKUERR (memory protection key denied access). si_addr gives the faulting address.

SIGBUS (7) — bus error

Raised on memory accesses that fault for reasons other than virtual-address mapping: misaligned access on architectures that require alignment (BUS_ADRALN), access to memory beyond the end of a memory-mapped file (BUS_ADRERR), uncorrectable hardware memory errors (BUS_MCEERR_AR and BUS_MCEERR_AO).

The hardware-error variants are particularly serious — they indicate the kernel has detected an actual RAM failure. Robust services that handle SIGBUS log the event, mark the affected memory unusable, and either continue with reduced state or terminate.

SIGFPE (8) — floating-point exception

Despite the name, primarily raised for integer divide-by-zero and integer overflow on architectures that trap those. Floating-point IEEE-754 violations rarely raise SIGFPE because most operations produce NaN/Inf rather than trapping.

SIGILL (4) — illegal instruction

Raised when the CPU attempts to execute an instruction it does not recognise — typically because a function pointer was corrupted, the program counter ended up in a non-code region, or a stub for a CPU feature unavailable on this hardware was actually called.

SIGTRAP (5) — trace/breakpoint

Raised when execution hits an int3 instruction (x86) or equivalent breakpoint trap. Used by debuggers to implement breakpoints. A non-debugged process receiving SIGTRAP is being told something has gone deeply wrong; the default action is terminate with core.

SIGSYS (31) — bad system call

Raised when a syscall is denied by a seccomp filter configured with SECCOMP_RET_TRAP, or by the kernel for genuinely invalid syscall numbers. Default action is terminate with core. The full discussion of seccomp's role and the SIGSYS signal payload is in the Seccomp chapter.

Asynchronous I/O and timers (kernel-generated)

SIGPIPE (13) — broken pipe

Sent to a process that writes to a pipe or socket whose other end has closed. Default action is terminate, which is almost never desired — most programs install SIG_IGN for SIGPIPE at startup and check write()'s return value for EPIPE instead.

SIGALRM (14) — alarm timer

Sent when an alarm() or setitimer(ITIMER_REAL, ...) timer expires. The signal targets the process that set the timer; userspace senders can also deliver it via kill(), requiring PROCESS_TERMINATE.

SIGVTALRM (26), SIGPROF (27) — virtual / profiling timers

Sent when setitimer(ITIMER_VIRTUAL, ...) or setitimer(ITIMER_PROF, ...) expire — virtual time (CPU time spent in user mode only) and profiling time (CPU time spent in user + kernel mode). Used by sampling profilers.

SIGIO / SIGPOLL (29) — I/O ready

Sent when an asynchronous I/O readiness event occurs on a file descriptor configured with F_SETOWN and O_ASYNC. Largely obsolete on modern Linux — epoll and io_uring replaced this pattern decades ago. See epoll and Polling for the modern equivalents.

SIGXCPU (24), SIGXFSZ (25) — resource limits

Sent when the process exceeds its RLIMIT_CPU (CPU time) or RLIMIT_FSIZE (file size) limit. The first delivery is at the soft limit, intended to give the process a chance to clean up. The hard limit raises SIGKILL if reached.

Signals not in this table

The signal numbers from 32 through 64 are the real-time signals, covered separately in Real-Time Signals. They differ from standard signals in three ways: they are queued (not coalesced), they carry a payload, and they have a defined priority order.

Some older Unix systems define additional signals (SIGEMT, SIGINFO, SIGTHR) that Linux does not implement; Peios follows Linux on the standard signal set.

See also