C++ Signal Handling
Signals are interruptions sent by the operating system to a process to cause it to cease doing its current job and focus on the task for which the interrupt was produced. The operating system can also emit signals based on system or error conditions.
There are some signals that the program will not detect, however there is a list below of signals that you may catch in your program and use to take necessary actions.
The following is a list of signals, along with their descriptions and capabilities:
SIGABRT | Abnormal program termination, such as a request to abort. |
SIGFPE | A mistaken arithmetic operation, such as a division by zero or an overflow operation. |
SIGILL | It is used to identify erroneous instructions. |
SIGINT | It receives an interrupt signal from an interactive program. |
SIGSEGV | Incorrect storage access. |
SIGTERM | A program termination request was issued. |
SIGHUP | It reports that the user's terminal is disconnected (POSIX). It is used to indicate that the controlling procedure has ended. |
SIGQUIT | To end a process and create a core dump, use this command. |
SIGTRAP | Trap for traces. |
SIGBUS | This is a BUS error, indicating that you tried to visit an incorrect address. |
SIGUSR1 | Signal 1 is a user-defined signal. |
SIGUSR2 | Signal 2 is a user-defined signal. |
SIGALRM | Access to an incorrect address is shown by an alarm clock. |
SIGTERM | Termination device. |
SIGCOUNT | This signal can be ignored, blocked, or handled. |
SIGSTOP | This signal delivered to process to make it proceed. |
The function signal ()
Unexpected interruptions or events can be trapped using the signal-handling library's function signal.
void (*signal (int sig, void (*func)(int)))(int); //syntax
Parameters:
- The signal is handled by this function.
- It describes how to handle the number of signals indicated by sig.
The parameter func defines one of the three methods a programme can handle a signal.
- SIG DFL (default handling): The signal that is handled by the default action for that signal.
- Ignore Signal (SIG IGN): The signal is ignored, and the code execution continues even if the signal was not intended.
- Specific function is defined to handle the signal.
- It is important to remember that the signal we want to capture should be recorded with the signal function and connected with the signal handling function.
Note: The signal processing function should be of type void.
Return
This function's return type is the same as the type of its parameter func. If this method's request is successful, it provides a reference to the handler function that was in responsibility of processing this signal before the call, if one existed.
Data Races
The term "data race" is undefined. If you call this function in a multi threading software then it will create undefined behavior.
Example to show how to utilize the signal() function:
#include <iostream>
#Include <bits/sdtc++.h>
#include <stdlib>
#include <csignal>
using namespace std;
signal signalled = 0;
void handler(int signal)
{
signalled = 1;
}
int main()
{
sig(SIGINT, handler);
raise(SIGINT);
if (signalled)
cout << "Signal is handled";
else
cout << "Signal is not handled";
return 0;
}
OUTPUT:
Signal is handled
Explanation
In the above example in C++, we used data races which is undefined which calls the function in multi threading software.
Another example to show how to utilize the signal() function:
#include <csignal>
#include <iostream>
#include <bits/sdtc++.h>
#include <stdlib>
using namespace
{
volatile std::sig eSignal_Status;
}
void signal_handler(int signal)
{
eSignal_Status = signal;
}
int main()
{
// Install a signal handler
std::signal(SIGINT, signal_handler);
std::cout << "Signal_Value: " << eSignal_Status << '\n';
std::cout << "Sending_signal " << SIGINT << '\n';
std::raise(SIGINT);
std::cout << "Signal_Value: " << eSignal_Status << '\n';
}
OUTPUT:
Signal_Value: 0
Sending_signal 2
Signal_Value: 2
Explanation
In the above example in C++, we have utilized the signal function which calls the function in multi threading software.
The function race ()
Signals are sent to the currently running application using the C++ signal raise () method.
The raise () method was declared in the < csignal > header file to handle a specific signal.
int raise (int signal); //syntax
The signal number that should be forwarded for processing. One of the following values can be used:
- SIGINT
- SIGABRT
- SIGFPe
- SIGILL
- SIGSeGV
- SIGTeRM
- SIGHUP
Return Value
On success, it returns 0; on failure, it returns a non-zero.
Exception
If no function handlers have been specified with signal to handle the raised signal, this function never throws an exception.
Example of a program showing how to utilize the raise () method when SIGABRT is passed:
#include <iostream>
#inlcude <bits/stdc++.h>
#include <stdlib>
#include <csignal>
using namespace std;
signal sig_value = 0;
void handler(int sig)
{
sig_value = sig;
}
int main()
{
signal(SIGABRT, handler);
cout << "Before signal handler is called" << endl;
cout << "Signal = " << sig_value << endl;
raise(SIGABRT);
cout << "After signal handler is called" << endl;
cout << "Signal = " << sig_value << endl;
return 0;
}
OUTPUT:
Before signal handler is called
Signal = 0
After signal handler is called
Signal = 6
Explanation
In the above program in C++, we have passed SIGABRT and utilized the raise function by passing SIGABRT and handler in the main function.