The Linux Programming Interface

(nextflipdebug5) #1
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
Free download pdf