Signals: Fundamental Concepts 411
To temporarily prevent delivery of a signal, we can use the series of calls shown
in Listing 20-5 to block the signal, and then unblock it by resetting the signal mask
to its previous state.
Listing 20-5: Temporarily blocking delivery of a signal
sigset_t blockSet, prevMask;
/* Initialize a signal set to contain SIGINT */
sigemptyset(&blockSet);
sigaddset(&blockSet, SIGINT);
/* Block SIGINT, save previous signal mask */
if (sigprocmask(SIG_BLOCK, &blockSet, &prevMask) == -1)
errExit("sigprocmask1");
/* ... Code that should not be interrupted by SIGINT ... */
/* Restore previous signal mask, unblocking SIGINT */
if (sigprocmask(SIG_SETMASK, &prevMask, NULL) == -1)
errExit("sigprocmask2");
SUSv3 specifies that if any pending signals are unblocked by a call to sigprocmask(),
then at least one of those signals will be delivered before the call returns. In other
words, if we unblock a pending signal, it is delivered to the process immediately.
Attempts to block SIGKILL and SIGSTOP are silently ignored. If we attempt to block
these signals, sigprocmask() neither honors the request nor generates an error. This
means that we can use the following code to block all signals except SIGKILL and SIGSTOP:
sigfillset(&blockSet);
if (sigprocmask(SIG_BLOCK, &blockSet, NULL) == -1)
errExit("sigprocmask");
20.11 Pending Signals
If a process receives a signal that it is currently blocking, that signal is added to the
process’s set of pending signals. When (and if) the signal is later unblocked, it is
then delivered to the process. To determine which signals are pending for a pro-
cess, we can call sigpending().
#include <signal.h>
int sigpending(sigset_t *set);
Returns 0 on success, or –1 on error