Signals on Linux with C languaje.
ignals are the software interrupts send to a program to indicate that a particular event has occurred. In other words, signal is the mode to pass information from one process to another process about the state of processes (Inter Process Communication).
In linux, all the signal names starts with SIG and ends with a description. Each signal has a name, value and a default action. We can change the default action of some signals but we can’t change the default action of control signals. All the signals are defined in sys/signal.h. When the signal is received, it instructs the kernel to do a specific task. On receiving a signal, the process either handle or ignore the signal, or in some cases terminate, depending on the signal.
Signals through Command Line :
We can take a simple example to understand the working of signals. Consider the following code :
#include <stdio.h>int main()
{
while(1)
{
printf(“\nsignal demo”);
}
return 0;
}
In the above code we have an infinite loop which prints signal demo. If you press Ctrl+c while executing the binary after compiling the execution terminates. Have you ever thought about the reason for that?
Actually what is happening at that time is a simple example for signals. When we press Ctrl+c, a SIGINT is send to the program and the program terminates because the default action for that signal is to terminate.
The above example works by already defined shortcuts to the signal. Another example is ctrl+z → SIGTSTP will get triggered.
Now we can discuss about the signals that can be used through command line. The linux users will be familiar with kill/killall command. What does those commands will do? Actually kill/killall is a tool which is used to terminate process. Another use case of these tools are to send any type of signals to a process.
We can understand that with an example. Consider the above code. Execute the binary in background, because if we run in foreground we won’t be able to give another command.
Now give the command killall -SIGSEGV a.out. This command will trigger a segmentation fault and the process terminates because of that segmentation fault.
Similar examples are :
- killall -SIGSTOP a.out
- killall -SIGCONT a.out : continue the loop program with a call to bg or fg, but we can use kill to do that too
- killall -SIGINT loop : same as ctrl+c
Available Signals :
The available signals can be listed with the help of the following command :
kill -l
Send A Signal :
We can send a signal to a process using the kill command. This signal functionality we have discussed in our first section. The syntax for sending signal is as follows :
kill <signal_id> <pid>Example :kill -2 5392 →which will send SIGKILL command to the process with ID 5392kill — signal SIGKILL 5392 →This command will also behave same as that of above
Trap A Signal :
When we send a signal to a process, the signal will do a specific task and returns. But sometimes our requirement will be different.
While executing a program we will apply Ctrl+c to terminate the program and returns back to the command line. Suppose we need to perform some other task with the specific signal other than the default or assigned task. In that case trapping of a signal comes into picture. The tool we uses to trap a signal is the trap command. The syntax for trapping signal is as follows :
trap "<commands>" <signal_id>Example :
trap "rm -f $WORKDIR/project/temp_file_1 $WORKDIR/project/temp_file_2; exit" 2
The above command will remove the files temp_file_1 and temp_file_2 after receiving the Ctrl+c input and then returns back to the command line.
Without assigning any tasks we can just ignore the signals. This also can be achieved with the help of trap command. Following is the syntax to ignore the signal.
trap '' <singal_id>Example :
trap '' 2
To reset the traps we can use the following command :
trap <signal>Example :
trap 2
Signals in C :
Since my favourite language is C, most of the stories will be related to C language. So now we can check how the signal can be handled in a C code.
We have the API signal to handle signals.
sighandler_t signal(int signum, sighandler_t handler);