sigsuspend() — Change mask and suspend the thread
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
POSIX.1 |
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.
- Error Code
- Description
- EINTR
- A signal was received and handled successfully.
Example
/* 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));
}
}
parent is waiting for child to send SIGUSR1 at Fri Jun 16 12:30:57 2006
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 2006
Related information
- signal.h
- bsd_signal() — BSD version of signal()
- kill() — Send a signal to a process
- killpg() — Send a signal to a process group
- pause() — Suspend a process pending a signal
- pthread_kill() — Send a signal to a thread
- raise() — Raise signal
- sigaction() — Examine or change a signal action
- sigaddset() — Add a signal to the signal mask
- sigdelset() — Delete a signal from the signal mask
- sigemptyset() — Initialize a signal mask to exclude all signals
- sigfillset() — Initialize a signal mask to include all signals
- sigignore() — Set disposition to ignore a signal
- signal() — Handle interrupts
- sigpause() — Unblock a signal and wait for a signal
- sigpending() — Examine pending signals
- sigprocmask() — Examine or change a thread
- sigset() — Change a signal action or a thread