Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

sigaction - examine and change signal handling

&pagelevel(4)&pagelevel

Syntax

#include <signal.h>

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

Description

sigaction() allows the calling process to examine and/or change the signal-handling action associated with the signal sig. The possible values for sig are defined in the header file signal.h (see signal.h).

The structure sigaction, which is used to describe the action to be taken, is defined in the header signal.h and contains at least the following members:

Member type

Member name

Description

void(*)(int)

sa_handler

SIG_DFL, SIG_IGN or a pointer to a signalhandling function.

sigset_t

sa_mask

Additional set of signals to be blocked during execution of the signal-handling function.

int

sa_flags

Special flags that can be used to affect the behavior of sig.

If act is not a null pointer, it points to a structure specifying the new action to be associated with sig, thus changing the current signal action. In this case, the argument oact must point to a structure in which the current signal action is to be stored on return from sigaction().

If act is a null pointer, the current signal handling remains unchanged, so this call can be used to examine the current handling for a given signal. The argument oact may be a null pointer in this case,

sa_handler identifies the signal action for sig and may have any of the values defined as signal actions in signal.h (see signal.h).

If sa_handler specifies a signal-handling function, the sa_mask member identifies a set of signals that are added to the process signal mask before the signal-handling function is called. Note that the SIGKILL and SIGSTOP signals cannot be blocked (i.e. are not added to the signal mask by this mechanism) and that this restriction will be enforced by the system without causing an error to be indicated.

sa_flags can be used to change the behavior of the specified signal. The following flag bits, defined in the header signal.h, can be set in sa_flags:

SA_NOCLDSTOP


prevents SIGCHLD from being generated when a child process stops.

Extension

SA_NOCLDWAIT 


If this flag bit is set and sig equals SIGCHLD, the system will not create zombie processes when children of the calling process exit. If the calling process subsequently executes successive wait calls, it will block until all of the its children terminate; a value of -1 is then returned, with errno set to ECHILD.

SA_NODEFER

The signal is not automatically blocked by the system while being processed by the signal-handling function.

SA_RESETHAND 


If this option is set and the signal is caught, the disposition of the signal will be reset to SIG_DFL, and the signal will be blocked on entry to the signal handler (SIGILL and SIGTRAP cannot be automatically reset when delivered; the system silently enforces this restriction).

SA_RESTART

If this flag bit is set and the signal is caught, a system call that is interrupted by the execution of the signal-handling routine is transparently restarted by the system. Otherwise, that system call returns an EINTR error.

SA_SIGINFO

If this flag bit is cleared and the signal is caught, sig is passed as the only argument to the signal-catching function. If the flag is set and the signal is caught, blocked signals of type sig are reliably queued for the calling process, and two additional arguments are passed to the signal-catching function. If the second argument is not a null pointer, it points to a structure of type siginfo_t containing the reason for the signal; the third argument points to a structure of type ucontext_t containing the context of the receiving process at the time the signal was received. (End)

If sig is SIGCHLD and SA_NOCLDSTOP is not set in sa_flags, then a SIGCHLD signal will be generated for the calling process whenever any of its child processes stop. If sig is SIGCHLD and SA_NOCLDSTOP is set in sa_flags, no SIGCHLD signal is generated.

When a signal is caught by a signal-handling function defined by sigaction(), a new signal mask is calculated for the duration of the signal-handling function (or until a call to either sigprocmask() or sigsuspend() is made). This mask is formed by taking the union of the current signal mask and the value of the sa_mask for the signal being sent, including the sent signal itself. If the user-defined signal handler returns normally, the original signal mask is restored.

The current signal-handling action for sig remains in effect until sigaction() is called again or until one of the exec functions is called.

If the previous action (oact) for sig was established by signal(), the values of the structure components returned in the structure pointed to by oact are unspecified and, in particular, oact-> sa_handler is not necessarily the same value passed to signal(). However, if a

pointer to the same structure or a copy thereof is passed to a subsequent call to sigaction() via the act argument, handling of the signal will be as if the original call to signal() were repeated.

An attempt to set the action for a signal that cannot be caught or ignored to SIG_DFL causes an error with errno set to EINVAL.

General notes on signal handling

A signal is said to be generated for (or sent to) a process when the event that causes the signal first occurs. Examples of such events include detection of hardware faults, timer expiration and terminal activity, or an invocation of kill(). In some circumstances, the same event generates signals for multiple processes.

Each process must ensure that a signal action is specified for each signal defined by the system (see section “Signal actions” on "sigaction - examine and change signal handling"). A signal is said to be delivered to a process when the prescribed action for the process and signal is taken.

During the time between the generation of a signal and its delivery, the signal is said to be pending. Ordinarily, this interval cannot be detected by an application. However, a signal can be blocked from delivery to a process. If the action associated with a blocked signal is anything other than to ignore the signal, and if that signal is generated for the process, the signal will remain pending until either it is unblocked or the action associated with it is set to ignore the signal. If the action associated with a blocked signal is to ignore the signal and if that signal is generated for the process, it is unspecified whether the signal is discarded immediately upon generation or remains pending.

Each process has a signal mask that defines the set of signals currently blocked from delivery to it. The signal mask for a process is initialized from that of its parent. The sigaction(), sigprocmask() and sigsuspend() functions control the manipulation of the signal mask.

The determination of which action is taken in response to a signal is made at the time the signal is delivered, allowing for any changes since the time of generation. This determination is independent of the means by which the signal was originally generated. If a signal that is already pending is generated, it is undefined whether the signal will be delivered more than once. The order in which multiple, simultaneously pending signals are delivered to a process is unspecified.

When a stop signal (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU) is generated for a process, any pending signals of type SIGCONT for that process are discarded. Conversely, whenever SIGCONT is generated for a process, all pending stop signals for that process are likewise discarded. When SIGCONT is generated for a process that is stopped, the process is continued even if the SIGCONT signal is blocked or ignored. If SIGCONT is blocked and not ignored, it will remain pending until it is either unblocked or a stop signal is generated for the process.

Signal actions

The following signal actions can be associated with a signal:

  • SIG_DFL

  • SIG_IGN

  • a pointer to a signal-handling function

All signals are set to SIG_DFL or SIG_IGN (see signal.h) prior to entry of the main() routine. The signal actions prescribed by these values are as follows:

SIG_DFL - signal-specific default action:

  • The default signal handling for supported signals is described in the signal.h section.

  • If the default action is to stop the process, the execution of that process is temporarily suspended. When a process stops, a SIGCHLD signal will be generated for its parent process, unless the parent process has set the SA_NOCLDSTOP flag. While a process is stopped, any additional signals that are sent to the process will not be delivered until the process is continued, except for SIGKILL, which always terminates the receiving process. A process that is a member of an orphaned process group will not be allowed to stop in response to the SIGTSTP, SIGTTIN or SIGTTOU signals. In cases where delivery of one of these signals would stop such a process, the signal will be discarded.

  • Setting a signal action to SIG_DFL for a signal that is pending, and whose default action is to ignore the signal (for example, SIGCHLD), will cause the pending signal to be discarded, whether or not it is blocked.

SIG_IGN - ignore signal:

  • Delivery of the signal will have no effect on the process. The behavior of a process is undefined after it ignores a SIGFPE, SIGILL or SIGSEGV signal that was not generated by kill() or raise().

  • The system will not allow the action SIG_IGN for the signals SIGKILL or SIGSTOP. Setting a signal action to SIG_IGN for a signal that is pending will cause the pending signal to be discarded, whether or not it is blocked.

  • If a process sets the action for the SIGCHLD signal to SIG_IGN, the signal will be ignored.

Pointer to a signal-handling function - catch signal:

  • On delivery of the signal, the receiving process is to execute the signal-catching function at the specified address. After returning from the signal-handling function, the receiving process will resume execution at the point at which it was interrupted.

  • The signal-handling function is called in the form of a C function as follows:

    void func (int signo);

  • func

    is the specified signal-handling function, and signo is the signal number of the signal being delivered.

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

  • The system will not allow a process to catch the signals SIGKILL and SIGSTOP.

  • If a process establishes a signal-handling function for the SIGCHLD signal while it has a terminated child process for which it has not waited, it is unspecified whether a SIGCHLD signal is generated to indicate that child process.

    When signal-handling functions are invoked asynchronously with process execution, the behavior of some of the functions defined in this manual is unspecified if they are called from a signal-handling function. The following table defines a set of functions that are either reentrant or not interruptible by signals. These so-called safe functions may therefore be invoked by applications from signal-handling functions without restrictions:

    access()

    free()

    raise()

    sysconf()

    alarm()

    fstat()

    read()

    tcdrain()

    calloc()

    getegid()

    rename()

    tcflow()

    cfgetispeed()

    geteuid()

    rmdir()

    tcflush()

    cfgetospeed()

    getgid()

    setgid()

    tcgetattr()

    cfsetispeed()

    getgroups()

    setpgid()

    tcgetpgrp()

    cfsetospeed()

    getpgrp()

    setsid()

    tcsendbreak()

    chdir()

    getpid()

    setuid()

    tcsetattr()

    chmod()

    getppid()

    sigaction()

    tcsetpgrp()

    chown()

    getuid()

    sigaddset()

    time()

    close()

    kill()

    sigdelset()

    times()

    creat()

    link()

    sigemptyset()

    umask()

    dup2()

    lseek()

    sigfillset()

    uname()

    dup()

    malloc()

    sigismember()

    unlink()

    execle()

    mkdir()

    signal()

    utime()

    execve()

    mkfifo()

    sigpending()

    wait()

    _exit()

    open()

    sigprocmask()

    waitpid()

    fcntl()

    pathconf()

    sigsuspend()

    write()

    fork()

    pause()

    sleep()


    fpathconf()

    pipe()

    stat()


    All functions not in the above table are considered to be unsafe with respect to signals. In the presence of signals, all X/Open-conformant functions behave as defined when called from or interrupted by a signal-handling function, with a single exception: when a signal interrupts an unsafe function and the signal-handling function calls an unsafe function, the behavior is undefined.

Signal effects on other functions

Signals affect the behavior of the following functions if they are delivered to a process while it is executing any of these functions:

catclose()

fgetwc()

getgrnam()

tcdrain()

catgets()

fopen()

getpass()

tcsetattr()

close()

fputc()

getpwnam()

tmpfile()

dup()

fputwc()

getpwuid()

wait()

fclose()

freopen()

open()

write()

fcntl()

fseek()

pause()


fflush()

fsync()

read()


fgetc()

getgrgid()

sigsuspend()


This has the following consequences:

  • If the action of the signal is to terminate the process, the process will be terminated and the function will not return.

  • If the action of the signal is to stop the process, the process will stop until continued or terminated.

  • The generation of a SIGCONT signal for a process causes the process to be continued at the point at which the process was stopped.

  • If the associated action of the signal is to invoke a signal-handling function, the relevant signal-handling function will be invoked; in this case, the original function is said to be interrupted by the signal.

  • If the signal-handling function executes a return statement, the behavior of the interrupted function will be as described for that function.

  • Signals that are ignored will not affect the behavior of any function.

  • Signals that are blocked will not affect the behavior of any function until they are delivered.

Return val.

0

 if successful.


-1

if an error occurs. errno is set to indicate the error. No new signal-handling function is defined.

Errors

sigaction() will fail if:

Extension 

 

EFAULT

act and oact point outside the allocated address space of the process. (End)

 

EINVAL

sig is not a valid signal number
or an attempt was made to catch or ignore a signal that cannot be caught ignored
or an attempt was made to set the action to SIG_DFL for a signal that cannot be caught or ignored (or both).

Notes

sigaction() supersedes signal() and should therefore be used with preference. In particular, sigaction() and signal() should not be used for the same signal in the same process.

If the same signal is registered two or more times, only the last one applies. This is especially true for signals mapped to one another. For example, the signal SIGDVZ is mapped to SIGFPE, and SIGTIM is mapped to SIGVTALRM. If a signal belonging to such a pair is registered first, and is then followed by the other, this will be treated as a repetition of the same signal.

Reentrant functions behave as described in this manual and may be used in signalhandling functions without restrictions. Applications should nonetheless consider all effects of such functions on data structures, files and process states. In particular, application writers need to consider the restrictions on interactions when interrupting sleep() and interactions among multiple file descriptors for a file description. c

In order to prevent errors arising from interrupting non-reentrant function calls, applications should protect calls to these functions either by blocking the appropriate signals or through the use of some semaphore. This manual does not address the more general problem of synchronizing access to shared data structures. Note that even the safe functions may modify the external variable errno; the signal-handling function may want to save and restore its value. Naturally, the same principles apply to reentrant application routines and asynchronous data access.

siglongjmp() is not in the list of reentrant functions. This is because the code executing after siglongjmp() can call any unsafe functions with the same danger as calling those unsafe functions directly from the signal handler. Applications that use longjmp() and sig longjmp() from within signal handlers require rigorous protection in order to be portable. Many of the other functions that are excluded from the list are traditionally implemented using either malloc(), free() or functions from stdio.h, all of which traditionally use data structures in a non-reentrant manner. Since any combination of different functions

using a common data structure can cause reentrancy problems, this manual does not define the behavior when any unsafe function is called in a signal handler that interrupts an unsafe function.

If a signal occurs without abort(), kill() or raise() being called, the behavior is undefined if the signal handler calls an X/Open-conformant library function other than one of those listed in the table above or if an object of static storage duration other than a variable of type volatile sig_atomic_t is accessed. If such a call fails, the value of errno is indeterminate.

The association between the symbolic names of signal numbers and their numeric values has not been standardized. An application will be portable only if sig uses the symbolic names.

See also

kill(), sigaddset(), sigdelset(), sigfillset(), sigemptyset(), sigismember(), sigprocmask(), sigsuspend(), signal.h, section “Signals”.