...
This noncompliant code example registers a single signal handler to process both SIGUSR1
and SIGUSR2
. The variable sig2
should be set to 1 if one or more SIGUSR1
signals are followed by SIGUSR2
, essentially implementing a finite state machine within the signal handler.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <signal.h> volatile sig_atomic_t sig1 = 0; volatile sig_atomic_t sig2 = 0; void handler(int signum) { if (signum == SIGUSR1) { sig1 = 1; } else if (sig1) { sig2 = 1; } } int main(void) { if (signal(SIGUSR1, handler) == SIG_ERR) { /* Handle error */ } if (signal(SIGUSR2, handler) == SIG_ERR) { /* Handler error */ } while (sig2 == 0) { /* Do nothing or give up CPU for a while */ } /* ... */ return 0; } |
...
The POSIX sigaction()
function assigns handlers to signals in a similar manner to the C99 signal()
function, but it also allows signal masks to be set explicitly. Consequently, sigaction()
can be used to prevent a signal handler from interrupting itself.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <signal.h> #include <stdio.h> volatile sig_atomic_t sig1 = 0; volatile sig_atomic_t sig2 = 0; void handler(int signum) { if (signum == SIGUSR1) { sig1 = 1; } else if (sig1) { sig2 = 1; } } int main(void) { struct sigaction act; act.sa_handler = &handler; act.sa_flags = 0; if (sigemptyset(&act.sa_mask) != 0) { /* Handle error */ } if (sigaddset(&act.sa_mask, SIGUSR1)) { /* Handle error */ } if (sigaddset(&act.sa_mask, SIGUSR2)) { /* Handle error */ } if (sigaction(SIGUSR1, &act, NULL) != 0) { /* Handle error */ } if (sigaction(SIGUSR2, &act, NULL) != 0) { /* Handle error */ } while (sig2 == 0) { /* Do nothing or give up CPU for a while */ } /* ... */ return 0; } |
...