Skip to content
Part IA Lent Term

UNIX Signals

What signals are

A signal is an asynchronous notification sent to a process, indicating that a particular event has occurred. Signals are the simplest UNIX IPC mechanism: they carry almost no data — just the signal number (an integer) — and the fact of their delivery.

Standard signals

SignalNumberDefault actionMeaning
SIGINT2TerminateInterrupt from keyboard (Ctrl+C)
SIGKILL9TerminateForce-kill (cannot be caught or ignored)
SIGSEGV11Core dump + terminateInvalid memory reference
SIGCHLD17IgnoreChild process terminated or stopped
SIGALRM14TerminateTimer expired (from alarm())
SIGPIPE13TerminateWrite to a pipe with no readers
SIGUSR110TerminateUser-defined signal 1
SIGUSR212TerminateUser-defined signal 2
SIGTERM15TerminatePolite termination request
SIGSTOP19StopSuspend process (cannot be caught or ignored)

Signal disposition

A process can respond to a signal in three ways:

  1. Default action: the kernel-defined response (terminate, core dump, stop, ignore).
  2. Catch: register a signal handler with signal() or sigaction(). When the signal is delivered, the handler runs (in user mode, on the process’s stack). After the handler returns, the process resumes where it was interrupted (roughly — signals interrupt system calls, which may return EINTR).
  3. Ignore: tell the kernel to discard the signal. SIGKILL and SIGSTOP cannot be ignored.

Signal delivery vs generation

A signal is generated when the event occurs (e.g., timer expires, child exits, user presses Ctrl+C). It is pending until the kernel delivers it. Delivery happens when:

  • The target process is scheduled to run.
  • The target process is returning from kernel mode to user mode (e.g., after a system call or interrupt handler).

The kernel never delivers a signal to a process running in user mode by interrupting the instruction stream — delivery is deferred to the kernel→user transition.

Unreliability of signals

Signals are not a reliable IPC mechanism for passing data:

  • Multiple instances of the same signal may be merged: if a process has one SIGCHLD pending and another child terminates, only one SIGCHLD is delivered, not two. The process cannot tell from the signal alone that two children died.
  • Signals carry no payload beyond the number. sigqueue() with SA_SIGINFO can attach a small integer, but this is POSIX real-time extensions and not part of the core IA syllabus.
  • Signals interrupt system calls. A read() that is blocked waiting for data may return -1 with errno == EINTR if a signal is delivered, forcing the programmer to restart the call.

Blocking signals

A process can block (mask) signals via sigprocmask(). Blocked signals remain pending until unblocked, at which point they are delivered. This is used to create critical sections where certain signals must not interrupt a sequence of operations.

Signal masks are inherited across fork() and preserved across exec().

Summary

  • Signals are lightweight, asynchronous event notifications carrying a signal number.
  • A process can catch, ignore, or accept the default action for a signal.
  • Signals are unreliable for data transfer — they can be merged and carry minimal payload.
  • Delivery is deferred to kernel→user transitions; blocked signals remain pending.
  • SIGKILL and SIGSTOP are the only truly unstoppable signals.