| Updated: October 28, 2024 |
Examine or specify the action associated with a signal
#include <signal.h>
int sigaction( int sig,
const struct sigaction * act,
struct sigaction * oact );
If the signal terminates a process, the cleanup of the terminated process occurs by default at the priority of the thread that sent the signal. As a QNX Neutrino extension, if you OR the SIG_TERMER_NOINHERIT flag (defined in <signal.h>) into sig, the cleanup occurs at the priority of the thread that received the signal.
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
You can use sigaction() to examine or specify (or both) the action that's associated with a specific signal:
Signal handlers and actions are defined for the process and affect all threads in the process. For example, if one thread ignores a signal, then all threads ignore the signal.
You can target a signal at a thread, process, or process group (see SignalKill()). When targeted at a process, at most one thread receives the signal. This thread must have the signal unblocked (see SignalProcmask()) to be a candidate for receiving it. All synchronously generated signals (e.g., SIGSEGV) are always delivered to the thread that caused them.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int main( void )
{
void handler(int);
sigset_t set;
struct sigaction act = {
.sa_flags = 0,
.sa_handler = &handler,
};
sigemptyset( &set );
sigaddset( &set, SIGUSR2 );
act.sa_mask = set;
/*
* Define a handler for SIGUSR1 such that when
* entered both SIGUSR1 (default) and SIGUSR2 are masked.
*/
sigaction( SIGUSR1, &act, NULL );
kill( getpid(), SIGUSR1 );
/* Program will terminate with a SIGUSR2 */
return EXIT_SUCCESS;
}
#define ENTER_STRING "In signal handler\n"
#define AFTER_STRING "In signal handler after both signals sent\n"
void handler( int signo )
{
static int first = 1;
write(STDOUT_FILENO, ENTER_STRING, sizeof(ENTER_STRING));
if( first ) {
first = 0;
kill( getpid(), SIGUSR1 ); /* Prove signal masked */
kill( getpid(), SIGUSR2 ); /* Prove signal masked */
write(STDOUT_FILENO, AFTER_STRING, sizeof(AFTER_STRING));
}
}
/*
* - SIGUSR1 is set from main(), handler() is called.
* - SIGUSR1 and SIGUSR2 are set from handler().
* - however, signals are masked until we return to main().
* - returning to main() unmasks SIGUSR1 and SIGUSR2.
* - pending SIGUSR1 now occurs, handler() is called.
* - pending SIGUSR2 now occurs. Since we don't have
* a handler for SIGUSR2, we are killed.
*/
| Safety: | |
|---|---|
| Cancellation point | No |
| Interrupt handler | No |
| Signal handler | Yes |
| Thread | Yes |