...
Code Block | ||
---|---|---|
| ||
void handler(int signum) { signal(signum, handler); /* Handlehandle Signalsignal */ } /* ... */ signal(signum, handler); |
...
For persistent platforms, calling the handler's signal()
function from within the signal handler is unnecessary.
Code Block | ||
---|---|---|
| ||
void handler(int signum) { /* Handlehandle Signalsignal */ } /* ... */ signal(signum, handler); |
...
POSIX defines the sigaction(2)
function, which assigns handlers to signals like signal(2)
but also allows you the caller to explicitly set persistence. So you can use Consequently, the sigaction(2)
and sidestep )
function can be used to eliminate the race window on non-persistent OSs.
Code Block | ||
---|---|---|
| ||
void handler(int signum) { /* Handlehandle Signalsignal */ } /* ... */ /* Equivalent to signal( signum, handler); but make signal persistent */ struct sigaction act; act.sa_handler = handler; act.sa_flags = 0; if (sigemptyset( &act.sa_mask) != 0) { /* Handlehandle Errorerror */ } if (sigaction(signum, &act, NULL) != 0) { /* Handlehandle Errorerror */ } |
While the handler in this example does not call signal()
, it safely can because the signal is masked and so the handler cannot be interrupted. Note that if If the same handler is installed for more than one signal number, it would be necessary to mask the signals explicitly in act.sa_mask
to ensure that the handler cannot be interrupted, because the system only masks the signal being delivered.
POSIX recommends sigaction(2)
and deprecates signal(2)
. Unfortunately, sigaction(2)
is not C99-compliant and is not supported on some platforms, including Windows.
...
Code Block | ||
---|---|---|
| ||
void handler(int signum) { #ifndef WINDOWS signal(signum, SIG_DFL); #endif /* Handlehandle Signalsignal */ } /* ... */ signal(signum, handler); |
...