signal.h
Introduction
signal.h
provides tools for handling signals (i.e. exceptions). A signal can be understood as a short message between the system and the program, and is mainly used to indicate a runtime error, or an exception event has occurred.
The header file signal.h
defines a series of macros that represent different signals.
- SIGABRT: aborted exception (possibly due to a call to the abort() method).
- SIGFPE: an arithmetic operation error occurred (possibly a division by 0 or an overflow).
- SIGILL: invalid instruction.
- SIGINT: interrupt.
- SIGSEGV: invalid memory access.
- SIGTERM: termination request.
The value of each of the above macros is a positive integer constant.
signal()
The header file signal.h
also defines a signal()
function that specifies a certain signal handling function.
signal(SIGINT, handler);
signal()
accepts two arguments, the first being a macro for a certain signal, and the second being a pointer to the function handler
that handles that signal.
The signal handler function handler
accepts an argument of type int, indicating the type of signal. It has the following prototype.
void (*func)(int);
The handler
function body can internally determine, based on this integer, exactly what kind of signal was received, since multiple signals can share the same handler function. Once the handler function has finished executing, the program resumes execution from the point where the signal was generated. However, if a SIGABRT signal is encountered and handler execution is complete, the system will abort the program.
When the system sends a signal to a program, the program can ignore the signal, i.e. it does not specify a handler function.
The return value of `signal()
is a pointer to the previous handler function, which is often stored in a variable, and the previous handler function is resumed when the new handler function has finished executing.
void (*orig_handler)(int);
orig_handler = signal(SIGINT, handler);
// After the SIGINT signal has occurred
signal(SIGINT, orig_handler);
In the above example, signal()
assigns a new handler function handler
to the signal SIGINT
, saving the original handler function inside the variable orig_handler
. When the function handler
is used, the original handler function is restored.
Signal-related macros
signal.h
also provides signal-related macros.
(1) SIG_DFL
SIG_DFL indicates the default processing function.
signal(SIGINT, SIG_DFL);
In the above example, the processing function of SIGINT is the default processing function, which is determined by the current implementation.
(2) SIG_IGN
SIG_IGN means that the signal is ignored.
signal(SIGINT, SIG_IGN);
The above example indicates that the SIGINT signal is not processed. Since pressing Ctrl + c while the program is running is issuing the SIGINT signal, the program cannot be terminated with Ctrl + c after using this statement.
(3) SIG_ERR
SIG_ERR is the signal processing function error, signal ()
return value.
if (signal(SIGINT, handler) == SIG_ERR) {
perror("signal(SIGINT, handler) failed");
// ...
}
The above example determines whether an error occurred when handler
handled SIGINT.
raise()
The raise()
function is used to raise a signal in the program.
int raise(int sig);
It accepts a signal value as an argument, indicating that the signal is emitted. Its return value is an integer that can be used to determine whether the signal was raised successfully, with 0 indicating success and non-zero indicating failure.
void handler(int sig) {
printf("Handler called for signal %d\n", sig);
}
signal(SIGINT, handler);
raise(SIGINT);
In the above example, raise()
triggers the SIGINT signal, causing the handler function to execute.