sigsuspend() — Change mask and suspend the thread

Standards

Standards / Extensions C or C++ Dependencies

POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3

both

POSIX(ON)

Format

#define _POSIX_SOURCE
#include <signal.h>

int sigsuspend(const sigset_t *mask);

General description

Replaces the current signal mask of a thread with the signal set given by *mask and then suspends execution of the calling thread. The thread does not resume running until a signal is delivered whose action is either to execute a signal-handling function or to end the process. (Signal sets are described in more detail in sigemptyset() — Initialize a signal mask to exclude all signals.)

The signal mask indicates a set of signals that should be blocked. Such signals do not “wake up” the suspended function. The signals SIGKILL, SIGSTOP, or SIGTRACE cannot be blocked or ignored; they are delivered to the thread no matter what the mask argument specifies.

If an incoming unblocked signal ends the thread, sigsuspend() never returns to the caller. If an incoming signal is handled by a signal-handling function, sigsuspend() returns after the signal-handling function returns. The signal mask of the thread is restored to whatever it was before sigsuspend() was called, unless the signal-handling functions explicitly changed the mask.

This function is supported only in a POSIX program.

Usage notes

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

Returned value

If sigsuspend() returns, it always returns -1.

If unsuccessful, sigsuspend() sets errno to one of the following values:
Error Code
Description
EINTR
A signal was received and handled successfully.

Example

CELEBS25
⁄* CELEBS25

   This example replaces the signal mask and then suspends execution.

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

void catcher(int signum) {
  switch (signum) {
    case SIGUSR1: puts("catcher caught SIGUSR1");
                  break;
    case SIGUSR2: puts("catcher caught SIGUSR2");
                  break;
    default:      printf("catcher caught unexpected signal %d\n",
                         signum);
  }
}

main() {
  sigset_t sigset;
  struct sigaction sact;
  time_t   t;

  if (fork() == 0) {
    sleep(10);
    puts("child is sending SIGUSR2 signal - which should be blocked");
    kill(getppid(), SIGUSR2);
    sleep(5);
    puts("child is sending SIGUSR1 signal - which should be caught");
    kill(getppid(), SIGUSR1);
    exit(0);
  }

  sigemptyset(&sact.sa_mask);
  sact.sa_flags = 0;
  sact.sa_handler = catcher;
  if (sigaction(SIGUSR1, &sact, NULL) != 0)
    perror("1st sigaction() error");

  else if (sigaction(SIGUSR2, &sact, NULL) != 0)
    perror("2nd sigaction() error");

  else {
    sigfillset(&sigset);
    sigdelset(&sigset, SIGUSR1);
    time(&t);
    printf("parent is waiting for child to send SIGUSR1 at %s",
         ctime(&t));
    if (sigsuspend(&sigset) == -1)
      perror("sigsuspend() returned -1 as expected");
    time(&t);
    printf("sigsuspend is over at %s", ctime(&t));
  }
}
Output
parent is waiting for child to send SIGUSR1 at Fri Jun 16 12:30:57 2001
child is sending SIGUSR2 signal - which should be blocked
child is sending SIGUSR1 signal - which should be caught
catcher caught SIGUSR2
catcher caught SIGUSR1
sigsuspend() returned -1 as expected: Interrupted function call
sigsuspend is over at Fri Jun 16 12:31:12 2001

Related information