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:

Member name Description
void (*) (int) sa_handler A pointer to the function assigned to handle the signal. The value of this member also can be SIG_DFL (indicating the default action) or SIG_IGN (indicating that the signal should be ignored).

sigset_t sa_mask A signal set (set of signals) to be added to the signal mask of the calling process before the signal-catching function sa_handler is called. For more information about signal sets, see sigprocmask()--Examine and Change Blocked Signals. You cannot use this mechanism to block the SIGKILL or SIGSTOP signals. If sa_mask includes these signals, they are ignored and sigaction() does not return an error.

sa_mask must be set by using one or more of the signal set manipulation functions: sigemptyset(), sigfillset(), sigaddset(), or sigdelset()

int sa_flags A collection of flag bits that affect the behavior of signals. The following flag bits can be set in sa_flags:

SA_NOCLDSTOP If this flag is set, the system does not generate a SIGCHLD signal when child processes stop. This is relevant only when the sig argument of sigaction() is SIGCHLD.
SA_NODEFER If this flag is set and sigis caught, sig is not added to the signal mask of the process on entry to the signal catcher unless it is included in sa_mask. If this flag is not set, sig is always added to the signal mask of the process on entry to the signal catcher. This flag is supported for compatibility with applications that use signal() to set the signal action.
SA_RESETHAND If this flag is set, the signal-handling action for the signal is reset to SIG_DFL and the SA_SIGINFO flag is cleared on entry to the signal-catching function. Otherwise, the signal-handling action is not changed on entry to the signal-catching function. This flag is supported for compatibility with applications that use signal() to set the signal action.
SA_SIGINFO If this flag is not set and the signal is caught, the signal-catching function identified by sa_handler is entered. If this flag is set and the signal is caught, the signal-catching function identified by sa_sigaction is entered.
void (*) (int, siginfo_t *, void *) sa_sigaction A pointer to the function assigned to handle the signal. If SA_SIGINFO is set, the signal-catching function identified by sa_sigaction is entered with additional arguments and sa_handler is ignored. If SA_SIGINFO is not set, sa_sigaction is ignored. If sig_action() is called from a program using data model LLP64, the parameters to sa_sigaction must be declared as siginfo_t *__ptr128 and void *__ptr128.

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:

Action Description
SIG_DFL (signal-specific default action)
  • The default actions for the supported signals are specified in Control Signals Table

  • If the default action is to stop the process, that process is temporarily suspended. When a process stops, a SIGCHLD signal is generated for its parent process, unless the parent process has set the SA_NOCLDSTOP flag. While a process is stopped, any additional signals sent to the process are not delivered. The one exception is SIGKILL, which always ends the receiving process. When the process resumes, any unblocked signals that were not delivered are then delivered to it.

  • If the default action is to ignore the signal, setting a signal action to SIG_DFL causes any pending signals for that signal to be discarded, whether or not the signal is blocked.
SIG_IGN (ignore signal)
  • Delivery of the signal has no effect on the process. The behavior of a process is undefined if it ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill() or raise().

  • If the default action is to ignore the signal, setting a signal action to SIG_DFL causes any pending signals for that signal to be discarded, whether or not the signal is blocked.

  • The signal action for the signals SIGKILL and SIGSTOP cannot be set to SIG_IGN.
Pointer to a function (catch signal)
  • On delivery of the signal, the receiving process runs the signal-catching function. When the signal-catching function returns, the receiving process resumes processing at the point at which it was interrupted.

  • If SA_SIGINFO is not set, the signal-catching function identified by sa_handler is entered as follows:
    void func( int signo );
    
    where the following is true:

    • func is the specified signal-catching function.
    • signo is the signal number of the signal being delivered.

  • If SA_SIGINFO is set, the signal-catching function identified by sa_sigaction is entered as follows:
    void func( int signo, siginfo_t *info, void *context );
    
    where the following is true:

    • func is the specified signal-catching function.
    • signo is the signal number of the signal being delivered.
    • *info points to an object of type siginfo_t associated with the signal being delivered.
    • context is set to the NULL pointer.

  • The behavior of a process is undefined if it returns normally from a signal-catching function for a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill() or raise().

  • The signals SIGKILL and SIGSTOP cannot be caught.

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:

int si_signo The system-generated signal number.

int si_source Indicates whether the source of the signal is being generated by the system or another process on the system. When the signal source is another process, the members si_QJN, si_pid, and si_uid contain valid data. When the signal source is the system, those members are set to binary 0.

short si_data_size The length of si_errno, si_code, si_pid, si_uid, and any additional signal-related data. If this member is set to 0, this signal-related information is not available.

struct si_QJN The fully qualified IBM® i job name of the process sending the signal.

int si_errno If not zero, this member contains an errno value associated with the signal, as defined in <errno.h>.

int si_code If not zero, this member contains a code identifying the cause of the signal. Possible code values are defined in the <signal.h> header file.

pidt_t si_pid The process ID of the process sending the signal.

uid_t si_uid The real user ID of the process sending the signal.

char si_data[1] If present, the member contains any additional signal-related data.


Control Signals Table

See Default Actions for a description of the value given.

Value Default Action Meaning
SIGABRT 2 Abnormal termination
SIGFPE 2 Arithmetic exceptions that are not masked (for example, overflow, division by zero, and incorrect operation)
SIGILL 2 Detection of an incorrect function image
SIGINT 2 Interactive attention
SIGSEGV 2 Incorrect access to storage
SIGTERM 2 Termination request sent to the program
SIGUSR1 2 Intended for use by user applications
SIGUSR2 2 Intended for use by user applications
SIGALRM 2 A timeout signal (sent by alarm())
SIGHUP 2 A controlling terminal is hung up, or the controlling process ended
SIGKILL 1 A termination signal that cannot be caught or ignored
SIGPIPE 3 A write to a pipe that is not being read
SIGQUIT 2 A quit signal for a terminal
SIGCHLD 3 An ended or stopped child process (SIGCLD is an alias name for this signal)
SIGCONT 5 If stopped, continue
SIGSTOP 4 A stop signal that cannot be caught or ignored
SIGTSTP 4 A stop signal for a terminal
SIGTTIN 4 A background process attempted to read from a controlling terminal
SIGTTOU 4 A background process attempted to write to a controlling terminal
SIGIO 3 Completion of input or output
SIGURG 3 High bandwidth data is available at a socket
SIGPOLL 2 Pollable event
SIGBUS 2 Specification exception
SIGPRE 2 Programming exception
SIGSYS 2 Bad system call
SIGTRAP 2 Trace or breakpoint trap
SIGPROF 2 Profiling timer expired
SIGVTALRM 2 Virtual timer expired
SIGXCPU 2 Processor time limit exceeded
SIGXFSZ 2 File size limit exceeded
SIGDANGER 2 System crash imminent
SIGPCANCEL 2 Thread termination signal that cannot be caught or ignored

Default Actions:

1 End the process immediately.
2 End the request.
3 Ignore the signal.
4 Stop the process.
5 Continue the process if it is currently stopped. Otherwise, ignore the signal.


Return Value

0 sigaction() was successful.
-1 sigaction() was not successful. The errno variable is set to indicate the error.


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:


[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:


  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:

    accept() access() alarm() chdir()
    chmod() chown() close() connect()
    creat() dup() dup2() fcntl()
    fstat() getegid() geteuid() getgid()
    getgroups() getpgrp() getpid() getppid()
    getuid() kill() link() lseek()
    mkdir() open() pathconf() pause()
    read() readv() recv() recvfrom()
    recvmsg() rename() rmdir() select()
    send() sendmsg() sendto() sigaction()
    sigaddset() sigdelset() sigemptyset() sigfillset()
    sigismember() sigpending() sigprocmask() sigsuspend()
    sigtimedwait() sigwait() sigwaitinfo() setitimer()
    sleep() stat() sysconf() time()
    times() umask() uname() unlink()
    utime() write() writev()  

    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 ]