A handler's visible work
A handler taking an int signal number counts the delivery, then chooses a response. In the example, SIGTERM calls quick_exit, SIGABRT calls _Exit, and SIGCONT returns. The default branch restores SIG_DFL, records the signal number in an interrupt flag, and returns. The surrounding program must inspect that flag to decide what to do next. section 17.6
A signal handler is a function invoked when a specified signal is delivered. It handles an exceptional event that need not arise from an explicit call in the current code. This differs from setjmp/longjmp, which can respond to conditions detected by the program itself. Signal delivery is one reason control flow cannot always be read from syntactic nesting alone. section 17.6 section 17.0
The event's origin matters:
- A synchronous signal follows a faulting instruction, such as one that attempts erroneous arithmetic or invalid memory access. The fault's instruction can be identified. section 17.6
- An asynchronous signal can arrive independently of the program's current operation, such as after a termination request. It may interrupt execution in an intermediate state. section 17.6
The handler has the shape of a function returning void and accepting an int signal number. The signal interface installs a handler for a signal; raise provides a way to generate one. An installation attempt must also account for failure, represented by SIG_ERR, and for an earlier disposition such as SIG_IGN or SIG_DFL. section 17.6
143 /**
144 ** @brief A minimal signal handler
145 **
146 ** After updating the signal count, for most signals this
147 ** simply stores the signal value in "interrupt" and returns.
148 **/
149 static void signal_handler(int sig) {
150 sh_count(sig);
151 switch (sig) {
152 case SIGTERM: quick_exit(EXIT_FAILURE);
153 case SIGABRT: _Exit(EXIT_FAILURE);
154 #ifdef SIGCONT
155 // continue normal operation
156 case SIGCONT: return;
157 #endif
158 default:
159 /* reset the handling to its default */
160 signal(sig, SIG_DFL);
161 interrupt = sig;
162 return;
163 }
164 }
!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":3}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":3}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":3}],[{\"line\":3,\"ch\":0},{\"line\":3,\"ch\":3}],[{\"line\":4,\"ch\":0},{\"line\":4,\"ch\":3}],[{\"line\":5,\"ch\":0},{\"line\":5,\"ch\":3}],[{\"line\":6,\"ch\":0},{\"line\":6,\"ch\":3}],[{\"line\":6,\"ch\":6},{\"line\":6,\"ch\":17}],[{\"line\":6,\"ch\":18},{\"line\":6,\"ch\":32}],[{\"line\":4,\"ch\":45},{\"line\":4,\"ch\":48}],[{\"line\":6,\"ch\":33},{\"line\":6,\"ch\":36}],[{\"line\":18,\"ch\":10},{\"line\":18,\"ch\":13}],[{\"line\":7,\"ch\":0},{\"line\":7,\"ch\":3}],[{\"line\":7,\"ch\":8},{\"line\":7,\"ch\":16}],[{\"line\":8,\"ch\":0},{\"line\":8,\"ch\":3}],[{\"line\":8,\"ch\":8},{\"line\":8,\"ch\":14}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":3}],[{\"line\":9,\"ch\":8},{\"line\":9,\"ch\":12}],[{\"line\":10,\"ch\":8},{\"line\":10,\"ch\":12}],[{\"line\":13,\"ch\":8},{\"line\":13,\"ch\":12}],[{\"line\":9,\"ch\":13},{\"line\":9,\"ch\":20}],[{\"line\":9,\"ch\":22},{\"line\":9,\"ch\":32}],[{\"line\":9,\"ch\":33},{\"line\":9,\"ch\":45}],[{\"line\":10,\"ch\":28},{\"line\":10,\"ch\":40}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":3}],[{\"line\":9,\"ch\":8},{\"line\":9,\"ch\":12}],[{\"line\":10,\"ch\":8},{\"line\":10,\"ch\":12}],[{\"line\":13,\"ch\":8},{\"line\":13,\"ch\":12}],[{\"line\":10,\"ch\":13},{\"line\":10,\"ch\":20}],[{\"line\":10,\"ch\":22},{\"line\":10,\"ch\":27}],[{\"line\":9,\"ch\":33},{\"line\":9,\"ch\":45}],[{\"line\":10,\"ch\":28},{\"line\":10,\"ch\":40}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":3}],[{\"line\":11,\"ch\":6},{\"line\":11,\"ch\":12}],[{\"line\":12,\"ch\":0},{\"line\":12,\"ch\":3}],[{\"line\":13,\"ch\":0},{\"line\":13,\"ch\":3}],[{\"line\":9,\"ch\":8},{\"line\":9,\"ch\":12}],[{\"line\":10,\"ch\":8},{\"line\":10,\"ch\":12}],[{\"line\":13,\"ch\":8},{\"line\":13,\"ch\":12}],[{\"line\":4,\"ch\":60},{\"line\":4,\"ch\":66}],[{\"line\":13,\"ch\":22},{\"line\":13,\"ch\":28}],[{\"line\":19,\"ch\":10},{\"line\":19,\"ch\":16}],[{\"line\":14,\"ch\":0},{\"line\":14,\"ch\":3}],[{\"line\":14,\"ch\":6},{\"line\":14,\"ch\":12}],[{\"line\":15,\"ch\":0},{\"line\":15,\"ch\":3}],[{\"line\":15,\"ch\":8},{\"line\":15,\"ch\":15}],[{\"line\":16,\"ch\":39},{\"line\":16,\"ch\":46}],[{\"line\":16,\"ch\":0},{\"line\":16,\"ch\":3}],[{\"line\":17,\"ch\":0},{\"line\":17,\"ch\":3}],[{\"line\":1,\"ch\":27},{\"line\":1,\"ch\":33}],[{\"line\":3,\"ch\":29},{\"line\":3,\"ch\":35}],[{\"line\":4,\"ch\":28},{\"line\":4,\"ch\":34}],[{\"line\":6,\"ch\":18},{\"line\":6,\"ch\":24}],[{\"line\":17,\"ch\":10},{\"line\":17,\"ch\":16}],[{\"line\":17,\"ch\":22},{\"line\":17,\"ch\":29}],[{\"line\":18,\"ch\":0},{\"line\":18,\"ch\":3}],[{\"line\":19,\"ch\":0},{\"line\":19,\"ch\":3}],[{\"line\":4,\"ch\":60},{\"line\":4,\"ch\":66}],[{\"line\":13,\"ch\":22},{\"line\":13,\"ch\":28}],[{\"line\":19,\"ch\":10},{\"line\":19,\"ch\":16}],[{\"line\":20,\"ch\":0},{\"line\":20,\"ch\":3}],[{\"line\":21,\"ch\":0},{\"line\":21,\"ch\":3}]]"}
!@%STYLE%@!
Follow the switch from the received signal number to each response; the default branch shows the short record-and-return path. section 17.6
TAKEAWAY: Keep handler work small. Mark the interrupt condition in a global flag, return to the interrupted context, and handle the condition there. Information shared with a handler must use volatile sig_atomic_t, atomic_flag, or another lock-free atomic data type. This restriction matters because an unexpected transfer of control complicates access to program state. section 17.7 section 17.0



