Signal handlers have to deal with reentrancy concerns and other problems. In practice, it's often more convenient to mask signals and then retrieve them from time to time. You can mask all signals (except SIGSTOP
and SIGKILL
, which you can't handle anyway) with this:
sigset_t all_signals;
sigfillset(&all_signals);
sigprocmask(SIG_BLOCK, &all_signals, NULL);
The code is slightly different if you're using pthreads. Call this in every thread, or (preferably) in the main thread before you create any others:
sigset_t all_signals;
sigfillset(&all_signals);
pthread_sigmask(SIG_BLOCK, &all_signals, NULL);
Once you've done that, you should periodically call sigtimedwait(2)
like this:
struct timespec no_time = {0, 0};
siginfo_t result;
int rc = sigtimedwait(&all_signals, &result, &no_time);
If there is a signal pending, information about it will be placed in result
and rc
will be the signal number; if not, rc
will be -1 and errno
will be EAGAIN
. If you're already calling select(2)
/poll(2)
(e.g. as part of some event-driven system), you may want to create a signalfd(2)
instead and attach it to your event loop. In this case, you still need to mask the signals as shown above.
for
loop, from 1 to 31? – Gid/usr/include/signal.h
There is no single standard macro you can use to represent all of them. Plus. You cannot trap all of them,SIGKILL
for example. – Doralynprintf
in the signal handler. The restriction on using non-async-signal-safe functions in signal handlers only applies if the signal interrupts a non-AS-safe function. All the functions called frommain
in this program are AS-safe, so the signal handler can use any functions it wants. Of course this analysis only applies to the sample program in the question; it likely does not apply to OP's actual program. – LabrieSIGKILL
) cannot be caught. – Profundity