[Previous]
[Contents]
[Next]

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 );

Description:

The sigaction() function allows the calling process to examine or specify (or both) the action to be associated with a specific signal. The argument signo specifies the signal. The structure sigaction contains the following members:

sa_handler
SIG_DFL, SIG_IGN, or a pointer to a function.
sa_mask
An additional set of signals to be masked (blocked) during execution of the signal-catching function.
sa_flags
Special flags to affect behavior of the signal. Set to zero for now.

If act isn't NULL, the specified signal is modified, based on the action pointed to. If oact isn't NULL, the previous action is stored in the structure it points to. The combination of act and oact allows you to query or set (or both) the action for a signal.

The signal() function is implemented on top of this function. It calls this routine with sa_mask and sa_flags set to zero, and sa_handler set to the passed function. This function is more powerful than signal() since it allows you to specify any signal mask when your signal handler is invoked. This allows you to protect yourself against other signals in a multi-signal environment. Both the signal() function and the sigaction() function always mask the signal that invoked the signal handler even if you specify a mask of zero. When your handler returns through a normal return, the previous mask will be restored, and any pending and now unmasked signals will be acted on.

If you use longjmp() to return from a signal handler, the signal will remain masked, You can use siglongjmp() to restore the mask to the state saved by a previous call to sigsetjmp().

Returns:

0
Success
-1
An error occurred. errno is set to indicate the error.

Errors:

EINVAL
The signal signo isn't valid, or is SIGKILL or SIGSTOP (i.e. you can't change the action for these signals).

Examples:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void main()
  {
    extern void handler();
    struct sigaction act;
    sigset_t set;

    sigemptyset( &set );
    sigaddset( &set, SIGUSR1 );
    sigaddset( &set, SIGUSR2 );

    /*
     * Define a handler for SIGUSR1 such that when
     * entered both SIGUSR1 and SIGUSR2 are masked.
     */
    act.sa_flags = 0;
    act.sa_mask = set;
    act.sa_handler = &handler;
    sigaction( SIGUSR1, &act, NULL );

    kill( getpid(), SIGUSR1 );

    /* Program will terminate with a SIGUSR2 */
  }

void handler( signo )
  {
    static int first = 1;

    printf( "Enter handler with signal %d.\n", signo );
    if( first ) {
      first = 0;
      kill( getpid(), SIGUSR1 );  /* Prove signal masked */
      kill( getpid(), SIGUSR2 );  /* Prove signal masked */
    }
    printf( "End signal handler.\n" );
  }

/*
 * - 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:

POSIX 1003.1

Safety:
Interrupt handler No
Signal handler Yes, but modifies errno
Thread Yes

See also:

errno, kill(), raise(), sigaddset(), sigdelset(), sigemptyset(), sigfillset(), sigismember(), signal(), sigpending(), sigprocmask()


[Previous]
[Contents]
[Next]