Linux System Programming · intermediate · ~8 min
Recognise the bugs that bite every C programmer when they first use signals.
write(), or set a flag and print later.int flag. The signal can arrive between read and write — use volatile sig_atomic_t.-1 with errno == EINTR. Either retry, or use SA_RESTART.alarm(0) and the signal. alarm(0) cancels the pending alarm, but if the kernel already queued the delivery there's a tiny window. Always check the operation's actual result.signal()). Use sigaction() and the issue disappears./* WRONG */
static int stopping = 0;
static void h(int s) { (void)s; stopping = 1; printf("stopping\n"); }
/* RIGHT */
static volatile sig_atomic_t stopping = 0;
static void h(int s) {
(void)s;
stopping = 1;
const char msg[] = "stopping\n";
write(STDERR_FILENO, msg, sizeof msg - 1);
}
Six recurring bugs: stdio in handlers, non-atomic flags, catching SIGKILL/SIGSTOP, no SIGCHLD reaper, ignoring EINTR, alarm() races. Memorise them.