Signal Sets

Many signal-related system calls need to be able to represent a group of different signals. For example, sigaction() and sigprocmask() allow a program to specify a group of signals that are to be blocked by a process, while sigpending() returns a group of signals that are currently pending for a process. (We describe these system calls shortly.)

Multiple signals are represented using a data structure called a signal set, provided by the system data type sigset_t. SUSv3 specifies a range of functions for manipulating signal sets, and we now describe these functions.

Note

On Linux, as on most UNIX implementations, the sigset_t data type is a bit mask. However, SUSv3 doesn’t require this. A signal set could conceivably be represented using some other kind of structure. SUSv3 requires only that the type of sigset_t be assignable. Thus, it must be implemented using either some scalar type (e.g., an integer) or a C structure (perhaps containing an array of integers).

The sigemptyset() function initializes a signal set to contain no members. The sigfillset() function initializes a set to contain all signals (including all realtime signals).

#include <signal.h>

int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);

Note

Both return 0 on success, or -1 on error

One of sigemptyset() or sigaddset() must be used to initialize a signal set. This is because C doesn’t initialize automatic variables, and the initialization of static variables to 0 can’t portably be relied upon as indicating an empty signal set, since signal sets may be implemented using structures other than bit masks. (For the same reason, it is incorrect to use memset(3) to zero the contents of a signal set in order to mark it as empty.)

After initialization, individual signals can be added to a set using sigaddset() and removed using sigdelset().

#include <signal.h>

int sigaddset(sigset_t *set, int sig);
int sigdelset(sigset_t *set, int sig);

Note

Both return 0 on success, or -1 on error

For both sigaddset() and sigdelset(), the sig argument is a signal number.

The sigismember() function is used to test for membership of a set.

#include <signal.h>

int sigismember(const sigset_t *set, int sig);

Note

Returns 1 if sig is a member of set, otherwise 0

The sigismember() function returns 1 (true) if sig is a member of set, and 0 (false) otherwise.

The GNU C library implements three nonstandard functions that perform tasks that are complementary to the standard signal set functions just described.

#define _GNU_SOURCE
#include <signal.h>

int sigandset(sigset_t *dest, sigset_t *left, sigset_t *right);
int sigorset(sigset_t *dest, sigset_t *left, sigset_t *right);

Note

Both return 0 on success, or -1 on error

int sigisemptyset(const sigset_t *set);

Note

Returns 1 if sig is empty, otherwise 0

These functions perform the following tasks:

Using the functions described in this section, we can write the functions shown in Example 20-4, which we employ in various later programs. The first of these, printSigset(), displays the signals that are members of the specified signal set. This function uses the NSIG constant, which is defined in <signal.h> to be one greater than the highest signal number. We use NSIG as the upper bound in a loop that tests all signal numbers for membership of a set.

The printSigMask() and printPendingSigs() functions employ printSigset() to display, respectively, the process signal mask and the set of currently pending signals. The printSigMask() and printPendingSigs() functions use the sigprocmask() and sigpending() system calls, respectively. We describe the sigprocmask() and sigpending() system calls in The Signal Mask (Blocking Signal Delivery) and Pending Signals.