The csignal header is a wrapper for the standard C <signal.h> header. It declares functions and macros related to signal handling.
UNIX and UNIX-like operating systems have much more extensive signal-handling facilities. The <csignal> handler is portable to all hosted C++ environments, regardless of operating system. If portability is a goal, be sure to use only the signals and semantics described in this section, and avoid the additional signals defined by the implementation (which might not be available on other implementations).
Default handler
void (*SIG_DFL)(int)
The SIG_DFL
macro represents the default handling of a signal. The macro expands to a constant whose value is suitable for use as the second parameter to the signal
function.
Error return
void (*SIG_ERR)(int)
The SIG_ERR
macro represents an error return from signal
. It expands to a constant expression.
Ignore signal
void (*SIG_IGN)(int)
The SIG_IGN
macro tells signal
to ignore a signal. The macro expands to a constant whose value is suitable for use as the second parameter to the signal
function.
Abort
int SIGABRT
The SIGABRT macro expands to a positive integer that reprents an abnormal termination. The abort function raises SIGABRT.
Floating point error
int SIGFPE
The SIGFPE
macro expands to a positive integer that reprents a floating point exception, such as divide by zero. An implementation is not required to raise SIGFPE
for a floating point error.
Illegal instruction
int SIGILL
The SIGILL
macro expands to a positive integer that represents an illegal instruction.
User interrupt
int SIGINT
The SIGINT
macro expands to a positive integer that represents a user interrupt.
Segmentation violation
int SIGSEGV
The SIGSEGV
macro expands to a positive integer that represents an addressing fault (segmentation violation).
Terminate
int SIGTERM
The SIGTERM
macro expands to a positive integer that represents a request to terminate the program.
Atomic type
typedef ... sig_atomic_t;
The sig_atomic_t
type is an integral type that can be accessed atomically, that is, even if a signal is delivered, the entire value is read or written.
Raise signal
int raise(int sig);
The raise
function sends a signal to the running program. The sig
parameter is the signal number. The return value is zero for success or non-zero for an error.
Set handler
void (*signal(int sig, void (*func)(int)))(int);
The signal
function controls the program's behavior when a signal is delivered to the program. The first parameter (sig
) is the signal number. The second parameter (func
) is the function to call when signal sig
is delivered.
The func
parameter can also be one of the special values SIG_DFL
or SIG_IGN
. Use SIG_DFL
to get the default behavior; use SIG_IGN
to ignore a signal.
The default behavior for a signal is implementation-defined, but it usually means terminating the program. The signal handler must not use any C++ features (such as throwing an exception), or else the results are implementation-defined. The function must have C linkage.
If the func
parameter is a function pointer, that function is called when signal sig
is delivered. Unless the signal is delivered by calling abort
or raise
, the function is highly restricted in what it can do:
SIGFPE
, the signal handler must not return, but should call abort
or exit
.signal
, and the first parameter must be sig
.volatile
sig_atomic_t
.If the handler returns normally, and the signal is not the result of a computational error, execution continues from the point where it was interrupted.
The return value of signal
is the previous value of the signal handler for sig
, or SIG_ERR
for an error. If SIG_ERR
is returned, errno
is set.
Example 13-7 shows a simple signal handler that sets a global flag when the user interrupts the program. Until the user interrupts it, the program reads input and counts the number of lines the user typed.
Example 13-7: Reading input until interrupted.
#include <csignal> #include <iostream> #include <string> volatile std::sig_atomic_t interrupted; // Signal handler sets a global flag. void sigint(int sig) { interrupted = 1; } int main() { // if (std::signal(SIGINT, sigint) == SIG_ERR) std::cerr << "Cannot set signal handler\n"; else { unsigned long count = 0; // count lines while(! interrupted) { std::cout << "> "; // user prompt std::string s; if (! std::getline(std::cin, s)) // EOF cannot terminat the loop, only SIGINT std::cin.clear(); ++count; } std::cout << "I counted " << count << " line(s).\n"; } }