<signal.h> provides signal handling for asynchronous events: SIGINT (Ctrl+C), SIGTERM, SIGSEGV, etc. Register a handler with signal(SIGNUM, handler). Handlers run asynchronously and can only safely call async-signal-safe functions like write and _exit.
The standard pattern is to set a flag in the handler and check it in the main loop.
This example catches SIGINT by setting a flag that the main loop polls.
// compile: gcc -o signalexample signalexample.c // run: ./signalexample (press Ctrl+C) // description: signal handler that sets a flag for clean shutdown #include <signal.h> #include <stdio.h> #include <unistd.h> volatile sig_atomic_t stop = 0; void handler(int sig) { stop = 1; } int main() { signal(SIGINT, handler); puts("running... press Ctrl+C to stop"); while (!stop) { putchar('.'); fflush(stdout); sleep(1); } puts("\nshutting down cleanly"); return 0; }
Signal handling:
signal(sig, handler): register signal handlervoid (*handler)(int sig) functionHandler special values:
SIG_DFL: restore default handlerSIG_IGN: ignore signalSIG_ERR: error return valueSignal-safe types:
sig_atomic_t: type guaranteed safe for assignments in signal handlersvolatile sig_atomic_t flag;Common signals (POSIX):
SIGINT: interrupt (Ctrl+C from terminal)SIGTERM: termination signal (from kill command)SIGABRT: abnormal termination (from abort())SIGSEGV: segmentation fault (invalid memory access)SIGFPE: floating-point exception (divide by zero)SIGALRM: alarm clock signal (from alarm())SIGCHLD: child process terminated/stoppedSIGPIPE: broken pipe (write to closed socket/pipe)SIGKILL: kill signal (cannot be caught or ignored)SIGSTOP: stop signal (cannot be caught, suspends process)Modern alternative (POSIX):
sigaction(): preferred over signal() for more controlsigprocmask(): block/unblock signalspause(): wait for signal