sigaction()
Examine or specify the action associated with a signal
Synopsis:
#include <signal.h>
int sigaction( int sig,
const struct sigaction * act,
struct sigaction * oact );
Arguments:
- sig
- The signal number (defined in <signal.h>). For more information, see
POSIX and QNX OS signals
in the documentation for SignalAction().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 OS 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.
- act
- NULL, or a pointer to a sigaction structure that specifies how you want to modify the action for the given signal.
- oact
- NULL, or a pointer to a sigaction structure that the function fills with information about the current action for the signal.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
You can use sigaction() to examine or specify (or both) the action that's associated with a specific signal:
- If act isn't NULL, the specified signal is modified.
- If oact isn't NULL, the previous action is stored in the structure it points to.
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.
- If you use longjmp() to return from a signal handler, the signal remains masked. You can use siglongjmp() to restore the mask to the state saved by a previous call to sigsetjmp().
- The kernel saves and restores the FPU context on entering and leaving signal handlers, so it's safe to use floating-point operations in them.
Returns:
- 0
- Success.
- -1
- An error occurred (errno is set).
Errors:
- EAGAIN
- Insufficient system resources are available to set up the signal's action.
- EFAULT
- A fault occurred trying to access the buffers provided.
- EINVAL
- The signal sig isn't valid.
Examples:
#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.
*/
Classification:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |