sigprocmask() — Examine or change a thread

Standards

Standards / Extensions C or C++ Dependencies
POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3
both  

Format

#define _POSIX_SOURCE
#include <signal.h>

int sigprocmask(int option, const sigset_t *__restrict__ new_set,
                sigset_t *__restrict__ old_set);

General description

Examines, changes, or examines and changes the signal mask of the calling thread. If there is only one thread, it does the same for the calling process.

Typically, sigprocmask(SIG_BLOCK, …, …) is used to block signals during a critical section of code. At the end of the critical section of code, sigprocmask(SIG_SETMASK, …, …) is used to restore the mask to the previous value returned by sigprocmask(SIG_BLOCK, …, …).
option
Indicates the way in which the existing set of blocked signals should be changed. The following are the possible values for option, defined in the signal.h header file:
SIG_BLOCK
Indicates that the set of signals given by new_set should be blocked, in addition to the set currently being blocked.
SIG_UNBLOCK
Indicates that the set of signals given by new_set should not be blocked. These signals are removed from the current set of signals being blocked.
SIG_SETMASK
Indicates that the set of signals given by new_set should replace the old set of signals being blocked.
new_set
Points to a signal set giving the new signals that should be blocked or unblocked (depending on the value of option) or it points to the new signal mask if the option was sig_setmask. Signal sets are described in sigemptyset() — Initialize a signal mask to exclude all signals. If new_set is a NULL pointer, the set of blocked signals is not changed. sigprocmask() determines the current set and returns this information in *old_set. If new_set is NULL, the value of option is not significant.

The signal set manipulation functions: sigemptyset(), sigfillset(), sigaddset(), and sigdelset() must be used to establish the new signal set pointed to by new_set.

old_set
Points to a memory location where sigprocmask() can store a signal set. If new_set is NULL, old_set returns the current set of signals being blocked. When new_set is not NULL, the set of signals pointed to by old_set is the previous set.

If there are any pending unblocked signals, either at the process level or at the current thread's level after sigprocmask() has changed the signal mask, then at least one of those signals is delivered to the thread before sigprocmask() returns.

The signals SIGKILL, SIGSTOP, or SIGTRACE cannot be blocked. If you attempt to use sigprocmask() to block these signals, the attempt is simply ignored. sigprocmask() does not return an error status.

SIGFPE, SIGILL, and SIGSEGV signals that are not artificially generated by kill(), killpg(), raise(), sigqueue(), or pthread_kill() (that is, were generated by the system as a result of a hardware or software exception) will not be blocked.

If an artificially raised SIGFPE, SIGILL, or SIGSEGV signal is pending and blocked when an exception causes another SIGFPE, SIGILL, or SIGSEGV signal, both the artificial and exception-caused signals may be delivered to the application.

If sigprocmask() fails, the signal mask of the thread is not changed.

Usage notes

The use of the SIGTHSTOP and SIGTHCONT signal is not supported with this function.

Returned value

If successful, sigprocmask() returns 0.

If unsuccessful, sigprocmask() returns -1 and sets errno to one of the following values:
Error Code
Description
EINVAL
option does not have one of the recognized values.

Example

CELEBS23
/* CELEBS23

   This example changes the signal mask.

 */
#define _POSIX_SOURCE
#include <signal.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>

void catcher(int signum) {
  puts("inside catcher");
}

main() {
  time_t start, finish;
  struct sigaction sact;
  sigset_t new_set, old_set;
  double diff;

  sigemptyset(&sact.sa_mask);
  sact.sa_flags = 0;
  sact.sa_handler = catcher;
  if (sigaction(SIGALRM, &sact, NULL) != 0)
    perror("sigaction() error");
  else {
    sigemptyset(&new_set);
    sigaddset(&new_set, SIGALRM);
    if (sigprocmask(SIG_BLOCK, &new_set, &old_set) != 0)
      perror("1st sigprocmask() error");
    else {
      time(&start);
      printf("SIGALRM signals blocked at %s", ctime(&start));
      alarm(1);

      do {
        time(&finish);
        diff = difftime(finish, start);
      } while (diff < 10);
      if (sigprocmask(SIG_SETMASK, &old_set, NULL) != 0)
        perror("2nd sigprocmask() error");
      else
        printf("SIGALRM signals unblocked at %s", ctime(&finish));
    }
  }
}

Output
SIGALRM signals blocked at Fri Jun 16 12:24:19 2006
inside catcher
SIGALRM signals unblocked at Fri Jun 16 12:24:29 2006

Related information