- A signal is a notification to a process indicating the occurrence of an event. It is also called a software interrupt and is not predictable, making it an asynchronous event.
- A signal can be specified with a number or a name, typically starting with SIG. The available signals can be listed using the command kill -l.

Whenever a signal is raised (either programmatically or by the system), a default action is performed. But what if you don’t want to perform the default action and instead want to perform your own actions upon receiving the signal? Yes, it is possible to handle the signal, but not for all signals. What if you want to ignore the signal? Yes, it is possible to ignore the signal, which means neither performing the default action nor handling the signal. It is possible to ignore or handle almost all signals, except for SIGSTOP and SIGKILL, which cannot be ignored or handled.
In summary, the actions performed for the signals are as follows –
- Default Action:
When a signal is raised, the operating system performs a predefined action associated with the signal. - Handle the Signal:
You can define custom behavior when a signal is received, overriding the default action. This is possible for most signals. - Ignore the Signal:
It is possible to ignore a signal, meaning neither the default action is performed nor any custom handling occurs. Most signals can be ignored, except for SIGSTOPand SIGKILL.
As discussed the signal can be handled altering the execution of default action. Signal handling can be done in either of the two ways i.e., through system calls, signal() and sigaction().
#include
typedef void (*sighandler_t)(int);
sighandler_tsignal(int signum, sighandler_t handler);
- The system call signal()registers a signal handler that is called when the signal, specified by signum, is generated. The handler can be one of the following:
- SIG_IGN: To ignore the signal.
- SIG_DFL: To restore the default action for the signal.
- User-defined handler: A function or address defined by the user to handle the signal.
- On success, the signal()system call returns the address of a function that takes an integer argument and has no return value. If there is an error, it returns SIG_ERR.
- While signal()allows you to register a handler for signals, it doesn’t provide advanced functionalities like masking signals to block them, modifying signal behavior, or other fine-tuning options. These features can be achieved using the sigaction() system call.
#include
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
This system call is used to either examine or change a signal action. If the act is not null, the new action for signal signum is installed from the act. If oldact is not null, the previous action is saved in oldact.
The sigaction structure contains the following fields –
Field 1: Handler – This specifies the signal handler, which is either defined in sa_handler (for simpler signal handling) or sa_sigaction (for more advanced signal handling with additional information about the signal).
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
- Handler for sa_handler:
The sa_handlerspecifies the action to be performed based on the signal number (signum). It can be one of the following:- SIG_DFL: Default action for the signal.
- SIG_IGN: Ignore the signal.
- Pointer to a custom signal handling function.
- Handler for sa_sigaction:
The sa_sigactionspecifies a more detailed handler. It takes three arguments:- signal number: First argument.
- siginfo_t structure: Second argument, providing detailed signal information.
- user context: Third argument, a pointer to user context (as returned by getcontext()or setcontext()).
The siginfo_t structure contains information like:
- Signal number.
- Signal value.
- Process ID of the sending process.
- Real user ID of the sending process, etc.
- Field 2 – Set of signals to be blocked:
- int sa_mask: Specifies the set of signals that should be blocked during the execution of the signal handler.
- Field 3 – Special flags:
- int sa_flags: A set of flags that modify the behavior of the signal handling.
- Field 4 – Restore handler:
- void (*sa_restorer) (void): This field is used for restoring the previous signal handler after the execution of the custom handler.
For a comparison between signal-based IPC and other methods like sockets, read this overview on Linux IPC.