Open In App

Signal Handling In Linux Through The signal() Function

A signal is a message or notification issued to your program by the operating system or another application (or one of its threads). Each signal is assigned a number between 1 and 31. Signals are devoid of argument, and most of the time, their names are self-explanatory. For instance, signal number 9 or SIGKILL notifies the program that it is being attempted to be killed.

List of Signals

There is a simple method for compiling a list of all the signals your system supports. Simply type the kill -l command to see all the allowed signals.



kill -l

 

Types of Signals

Signal as interrupt

Signal masks

Each signal has one of three possible states:

It is frequently simpler to handle a “signal mask” when manipulating signals and controlling signal setup. Each bit in a bit-mask has a matching signal. Since there are 32 (really 31, since 0 doesn’t count) different signals, we can store information about 32 signals in a single 32-bit integer (unsigned int). 



The operating system does exactly this. Signal masks are also utilized as arguments in other system calls, so we will need to work with them. Default signal handlers are assigned by the C library. This means that even if you ignore signals, your software will still process them and act on them as it would normally. 

What signals are good for?

As their name suggests, signals are used to signal something. There are various signal types, and each one denotes a different meaning. Each signal’s designation is determined by its semantics. In other words, you might wish to select what action should be connected to each of the signals. You might determine that your application would print anything or draw something on the screen in response to a certain signal. Most of the time, it is your choice. There is, however, a standard norm for what each and every signal should do. This accepted practice states that SIGINT should force your program to end. It is in your best interest to maintain this as the SIGINT signal’s default response. Usability is an issue. Nobody desires a non-interruptible program.

Signals that report exceptions

Signals can also be used to suggest that something unpleasant has transpired. For instance, the operating system sends a SIGSEGV signal to your application when your software creates a segmentation failure.

Other uses of signals

There are various uses for signals. 

Signal Handler

You can register your own signal handler using one of the various interfaces.

1. signal()

The oldest one is this one. It takes two arguments: a reference to a signal handler code and a signal number (one of those SIGsomethings). A single integer input representing a sent signal number is taken by the signal handler function, which returns void. In this manner, you can apply the same signal handler function to numerous signals.

Syntax:

signal(SIGINT, sig_handler);

Signal() allows you to specify the default signal handler that will be utilized for a specific signal. You can also instruct the system to disregard a certain signal. Choose SIG IGN as the signal handler if you want to ignore the signal. Set SIG DFL as the signal handler to restore the default signal handler.

Even when it appears to be everything you would need, it is preferable to stay away from employing signal (). This system call has a problem with portability. In other words, it acts differently under various operating systems. There is a more recent system call that performs all the functions of signal() while additionally providing a little bit more details about the signal itself, its origin, etc.

2. sigaction()

Another system call that modifies the signal handler is sigaction(). 

Syntax:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

A signal number is specified in its first argument. Pointers to the sigaction structure are provided as the second and third arguments. This structure describes how the given signal should be handled by the process.

Usage of signal()

Example 1: Illustrating the hangup of the signal using the below command

Syntax:

kill -signal  pid

Script:

#!/bin/bash
kill -1  500

Output: 

 

Explanation:

The signal is the name or number of the signal that has to be given in the kill command syntax above, and pid is the ID of the process to which the signal needs to be sent. The program executing with the 500 process ID receives the signal called hang-up, or HUP, from the aforementioned command. If no such process is running with pid 500 then a message will be displayed as shown in the above output.

Example 2: Illustrating the killing of signal using the below command

Script:

#!/bin/bash
kill -9  500

Output:

 

Explanation:

Use the above command to send the kill signal to a similar process. The process running under process ID 500 will be terminated by the command already mentioned. If no such process is running with pid 500 then a message will be displayed as shown in the above output.

Conclusion:

There is a default response for each signal. The action that a script or program executes in response to a signal is known as the default action for a signal. For example- stop the procedure, disregard the signal, stop the operation, carry on a halted procedure, etc.


Article Tags :