sigaction()--Examine and Change Signal Action


  Syntax
 #include <signal.h>

 int sigaction( int sig, const struct sigaction *act,   
                struct sigaction *oact );

  Service Program Name: QP0SSRV1

  Default Public Authority: *USE

  Threadsafe: Yes

The sigaction() function examines, changes, or both examines and changes the action associated with a specific signal.

The sig argument must be one of the macros defined in the <signal.h> header file.

If sigaction() fails, the action for the signal sig is not changed.


Authorities and Locks

None.


Parameters

sig
(Input) A signal from the list defined in Control Signals Table.

*act
(Input) A pointer to the sigaction structure that describes the action to be taken for the signal. Can be NULL.

If act is a NULL pointer, signal handling is unchanged. sigaction() can be used to inquire about the current handling of signal sig.

If act is not NULL, the action specified in the sigaction structure becomes the new action associated with sig.

*oact
(Output) A pointer to a storage location where sigaction() can store a sigaction structure. This structure contains the action currently associated with sig. Can be NULL.

If oact is a NULL pointer, sigaction() does not store this information.

The sigaction() function uses structures of the sigaction type. The following is an example of a sigaction() structure:

struct sigaction {
    void      (*sa_handler)(int);
    sigset_t  sa_mask;
    int       sa_flags;
    void      (*sa_sigaction)(int, siginfo_t *,void *);
};

The members of the sigaction structure are as follows:

When a signal catcher installed by sigaction(), with the SA_RESETHAND flag set off, catches a signal, the system calculates a new signal mask by taking the union of the following:

This new mask stays in effect until the signal handler returns, or until sigprocmask(), sigsuspend(), or siglongjmp() is called. When the signal handler ends, the original signal mask is restored.

After an action has been specified for a particular signal, it remains installed until it is explicitly changed with another call to sigaction().

There are three types of actions that can be associated with a signal: SIG_DFL, SIG_IGN, or a pointer to a function. Initially, all signals are set to SIG_DFL or SIG_IGN. The actions prescribed by these values are as follows:

The following is an example of the siginfo_t structure:

typedef struct siginfo_t {
   int      si_signo;               /* Signal number                 */
   int      si_source   :   1;      /* Signal source                 */
   int      reserved1   :  15;      /* Reserved (binary 0)           */
   short    si_data_size;           /* Size of additional signal
                                       related data (if available)   */
   _MI_Time si_time;                /* Time of signal                */
   struct {
       char reserved2[2]  /* Pad (reserved)                */
       char si_job[10];   /* Simple job name               */
       char si_user[10];  /* User name                     */
       char si_jobno[6];  /* Job number                    */
       char reserved3[4]; /* Pad (reserved)                */
   } si_QJN;                        /* Qualified job name            */
   int      si_code;                /* Cause of signal               */
   int      si_errno;               /* Error number                  */
   pid_t    si_pid;                 /* Process ID of sender          */
   uid_t    si_uid;                 /* Real user ID of sender        */
   char     si_data[1];   /* Additional signal related
                                       data (if available)           */
} siginfo_t;

The members of the siginfo_t structure are as follows:



Control Signals Table

See Default Actions for a description of the value given.

Default Actions:



Return Value



Error Conditions

If sigaction() is not successful, errno usually indicates one of the following errors. Under some conditions, errno could indicate an error other than those listed here.

[EINVAL]

The value specified for the argument is not correct.

A function was passed incorrect argument values, or an operation was attempted on an object and the operation specified is not supported for that type of object.

An argument value is not valid, out of range, or NULL.

[ENOTSIGINIT]

Process not enabled for signals.

An attempt was made to call a signal function under one of the following conditions:

  • The signal function is being called for a process that is not enabled for asynchronous signals.
  • The signal function is being called when the system signal controls have not been initialized.

[ENOTSUP]

Operation not supported.

The operation cannot be performed while running in a system job. An attempt was made to change a signal action while running in a system job.



Usage Notes

  1. When the sigaction function is used to change the action associated with a specific signal, it enables a process for signals if the process is not already enabled for signals. For details, see Qp0sEnableSignals()--Enable Process for Signals. If the system has not been enabled for signals, sigaction() is not successful, and an [ENOTSIGINIT] error is returned.

  2. The sigaction() function can be used to set the action for a particular signal with the same semantics as a call to signal(). The sigaction structure indicated by the parameter *act should contain the following:

    • A sa_handler equal to the func specified on signal().
    • A sa_mask containing the signal mask set by sigemptyset().
    • A sa_flag with the SA_RESETHAND flag set on.
    • A sa_flag with the SA_NODEFER flag set on.

  3. Some of the functions have been restricted to be serially reusable with respect to asynchronous signals. That is, the library does not allow an asynchronous signal to interrupt the processing of one of these functions until it has completed.

    This restriction needs to be taken into consideration when a signal-catching function is called asynchronously, because it causes the behavior of some of the library functions to become unpredictable.

    Because of this, when producing a strictly compliant POSIX application, only the following functions should be assumed to be reentrant with respect to asynchronous signals. Your signal-catching functions should be restricted to using only these functions:

    In addition to the above functions, the macro versions of getc() and putc() are not reentrant. However, the library versions of these functions are reentrant.


Related Information


Example

The following example shows how signal catching functions can be established using the sigaction() function.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

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

void check_mask( int sig, char *signame ) {

    sigset_t sigset;

    sigprocmask( SIG_SETMASK, NULL, &sigset );
    if( sigismember( &sigset, sig ) )
        printf( "the %s signal is blocked\n", signame );
    else
        printf( "the %s signal is unblocked\n", signame );
}

void catcher( int sig ) {

    printf( "inside catcher() function\n" );
    check_mask( SIGUSR1, "SIGUSR1" );
    check_mask( SIGUSR2, "SIGUSR2" );
}

int main( int argc, char *argv[] ) {

    struct sigaction sigact, old_sigact;
    sigset_t sigset;

   /*
    * Set up an American National Standard C style signal handler
    * by setting the signal mask to the empty signal set and
    * using the do-not-defer signal, and reset the signal handler
    * to the SIG_DFL signal flag options.
    */

    sigemptyset( &sigact.sa_mask );
    sigact.sa_flags = 0;
    sigact.sa_flags = sigact.sa_flags | SA_NODEFER | SA_RESETHAND;
    sigact.sa_handler = catcher;
    sigaction( SIGUSR1, &sigact, NULL );

   /*
    * Send a signal to this program by using
    *    kill(getpid(), SIGUSR1)
    * which is the equivalent of the American
    * National Standard C raise(SIGUSR1)
    * function call.
    */

    printf( "raise SIGUSR1 signal\n" );
    kill( getpid(), SIGUSR1 );

   /*
    * Get the current value of the signal handling action for
    * SIGUSR1.  The signal-catching function should have been
    * reset to SIG_DFL
    */

    sigaction( SIGUSR1, NULL, &old_sigact );
    if ( old_sigact.sa_handler != SIG_DFL )
        printf( "signal handler was not reset\n" );

   /*
    * Reset the signal-handling action for SIGUSR1
    */

    sigemptyset( &sigact.sa_mask );
    sigaddset( &sigact.sa_mask, SIGUSR2 );
    sigact.sa_flags = 0;
    sigact.sa_handler = catcher;
    sigaction( SIGUSR1, &sigact, NULL );

    printf( "raise SIGUSR1 signal\n" );
    kill( getpid(), SIGUSR1 );

   /*
    * Get the current value of the signal-handling action for
    * SIGUSR1.  catcher() should still be the signal catching
    * function.
    */

    sigaction( SIGUSR1, NULL, &old_sigact );
    if( old_sigact.sa_handler != catcher )
        printf( "signal handler was reset\n" );

    return( 0 );

}

Output:

    raise SIGUSR1 signal
    inside catcher() function
    the SIGUSR1 signal is unblocked
    the SIGUSR2 signal is unblocked
    raise SIGUSR1 signal
    inside catcher() function
    the SIGUSR1 signal is blocked
    the SIGUSR2 signal is blocked


API introduced: V3R6

[ Back to top | UNIX-Type APIs | APIs by category ]