...
This non-compliant program registers a single signal handler to process both SIGUSR1
and SIGUSR2
. The variable sig2
should be set to one if one or more SIGUSR1
signals are followed by SIGUSR2
. a Note that this example
Code Block | ||
---|---|---|
| ||
#include <signal.h>
#include <stdlib.h>
#include <string.h>
volatile sig_atomic_t sig1 = 0;
volatile sig_atomic_t sig2 = 0;
void handler(int signum) {
if (sig1) {
sig2 = 1;
}
sig1 = 1;
}
int main(void) {
signal(SIGUSR1, handler);
signal(SIGUSR2, handler);
while (1) {
if (sig2) break;
sleep(SLEEP_TIME);
}
/* ... */
return 0;
}
|
The problem with this code is that there is a race condition in the implementation of handler()
. If handler()
is called to handle SIGUSR1
, and is interrupted to handle SIGUSR2
, it is possible that sig2
will not be set. This non-compliant code example also violates SIG31-C. Do not access or modify shared objects in signal handlers.
Compliant Solution
This compliant solution registers two separate signal handlers to process SIGUSR1
and SIGUSR2
. The sig1_handler()
handler waits for SIGUSER1
. After this signal occurs, the sig2_handler()
is registered to handle SIGUSER2
. This solution is fully compliant and accomplishing the goal of detecting one or more SIGUSR1
signals are followed by SIGUSR2
.
Code Block | ||
---|---|---|
| ||
#include <signal.h> #include <stdlib.h> #include <string.h> volatile sig_atomic_t sig1 = 0; volatile sig_atomic_t sig2 = 0; void sig1_handler(int signum) { ifsig1 (sig1) { sig2 = 1; } sig1= 1; } void sig2_handler(int signum) { sig2 = 1; } int main(void) { signal(SIGUSR1, handler); while (1) { if (sig1) break; sleep(SLEEP_TIME); } signal(SIGUSR2, handler); while (1) { if (sig2) break; sleep(SLEEP_TIME); } /* ... */ return 0; } |
Risk Assessment
...