Signal handlers must deal with re-entry problems and other problems. In practice, it is often more convenient to mask signals and then extract them from time to time. You can mask all signals (except SIGSTOP and SIGKILL , which you cannot process in any way):
sigset_t all_signals; sigfillset(&all_signals); sigprocmask(SIG_BLOCK, &all_signals, NULL);
The code is a little different if you use pthreads. Call this on each thread, or (preferably) on the main thread, before creating any others:
sigset_t all_signals; sigfillset(&all_signals); pthread_sigmask(SIG_BLOCK, &all_signals, NULL);
Once you do this, you should periodically call sigtimedwait(2) as follows:
struct timespec no_time = {0, 0}; siginfo_t result; int rc = sigtimedwait(&all_signals, &result, &no_time);
If a signal is expected, 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 are already calling select(2) / poll(2) (for example, as part of some event-driven system), you can create signalfd(2) and attach it to your event loop. In this case, you still need to mask the signals as shown above.
Kevin source share