Difference between revisions of "cpp/utility/program/signal"
m (Wording fix.) |
(→Parameters: add C++17 form) |
||
Line 29: | Line 29: | ||
*{{lc|SIG_IGN}} macro. The signal is ignored. | *{{lc|SIG_IGN}} macro. The signal is ignored. | ||
*pointer to a function. The signature of the function must be equivalent to the following: | *pointer to a function. The signature of the function must be equivalent to the following: | ||
− | {{ddcl| | + | {{ddcl|extern "C" void fun(int sig);}} |
− | extern "C" void fun(int sig);}}}} | + | {{rrev|since=c++17|or {{ddcl|void fun(int sig);}}}} |
+ | }} | ||
{{par end}} | {{par end}} | ||
Revision as of 09:00, 12 April 2023
Defined in header <csignal>
|
||
/* signal-handler */* signal(int sig, /* signal-handler */* handler); |
(1) | |
extern "C" using /* signal-handler */ = void(int); // exposition-only |
(2) | |
Sets the handler for signal sig to the handler handler points to. The signal handler can be set so that default handling will occur, signal is ignored, or a user-defined function is called.
When signal handler is set to a function and a signal occurs, it is implementation defined whether std::signal(sig, SIG_DFL) will be executed immediately before the start of signal handler. Also, the implementation can prevent some implementation-defined set of signals from occurring while the signal handler runs.
For some of the signals, the implementation may call std::signal(sig, SIG_IGN) at the startup of the program. For the rest, the implementation must call std::signal(sig, SIG_DFL).
(Note: POSIX introduced sigaction
to standardize these implementation-defined behaviors)
Contents |
Parameters
sig | - | the signal to set the signal handler to. It can be an implementation-defined value or one of the following values:
| ||||||||||||||
handler | - | the signal handler. This must be one of the following:
|
Return value
Previous signal handler on success or SIG_ERR on failure (setting a signal handler can be disabled on some implementations).
Signal handler
The following limitations are imposed on the user-defined function that is installed as a signal handler.
If the signal handler is called NOT as a result of std::abort or std::raise (asynchronous signal), the behavior is undefined if
|
(until C++17) |
A plain lock-free atomic operation is an invocation of a function f from <atomic> or <stdatomic.h>(since C++23), such that:
The behavior is undefined if any signal handler performs any of the following:
|
(since C++17) |
If the user defined function returns when handling SIGFPE, SIGILL, SIGSEGV or any other implementation-defined signal specifying a computational exception, the behavior is undefined.
If the signal handler is called as a result of std::abort or std::raise (synchronous signal), the behavior is undefined if the signal handler calls std::raise.
On entry to the signal handler, the state of the floating-point environment and the values of all objects is unspecified, except for
On return from a signal handler, the value of any object modified by the signal handler that is not volatile std::sig_atomic_t or lock-free std::atomic is indeterminate. |
(until C++14) | ||
A call to the function If a signal handler is executed as a result of a call to std::raise (synchronously), then the execution of the handler is sequenced-after the invocation of Two accesses to the same object of type volatile std::sig_atomic_t do not result in a data race if both occur in the same thread, even if one or more occurs in a signal handler. For each signal handler invocation, evaluations performed by the thread invoking a signal handler can be divided into two groups A and B, such that no evaluations in B happen-before evaluations in A, and the evaluations of such volatile std::sig_atomic_t objects take values as though all evaluations in A happened-before the execution of the signal handler and the execution of the signal handler happened-before all evaluations in B. |
(since C++14) |
Notes
POSIX requires that signal
is thread-safe, and specifies a list of async-signal-safe library functions that may be called from any signal handler.
Signal handlers are expected to have C linkage and, in general, only use the features from the common subset of C and C++. It is implementation-defined if a function with C++ linkage can be used as a signal handler. |
(until C++17) |
There is no restriction on the linkage of signal handlers. |
(since C++17) |
Example
#include <csignal> #include <iostream> namespace { volatile std::sig_atomic_t gSignalStatus; } void signal_handler(int signal) { gSignalStatus = signal; } int main() { // Install a signal handler std::signal(SIGINT, signal_handler); std::cout << "SignalValue: " << gSignalStatus << '\n'; std::cout << "Sending signal: " << SIGINT << '\n'; std::raise(SIGINT); std::cout << "SignalValue: " << gSignalStatus << '\n'; }
Possible output:
SignalValue: 0 Sending signal: 2 SignalValue: 2
References
- C++23 standard (ISO/IEC 14882:2024):
- 17.13.5 Signal handlers [support.signal]
- C++20 standard (ISO/IEC 14882:2020):
- 17.13.5 Signal handlers [support.signal]
- C++17 standard (ISO/IEC 14882:2017):
- 21.10.4 Signal handlers [support.signal]
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3756 | C++17 | it was unclear whether std::atomic_flag is signal-safe | it is |
See also
runs the signal handler for particular signal (function) | |
(C++11) |
fence between a thread and a signal handler executed in the same thread (function) |
C documentation for signal
|