Sunday, November 6, 2011

Handling Multiple Signals in C programming

Now that we know how to handle one signal, let us try to handle multiple signals. Here is the program to do this…

# include <unistd.h>
# include <sys/types.h>
# include <signal.h>
void inthandler ( int signum )
{
printf ( "\nSIGINT Received\n" ) ;
}
void termhandler ( int signum )
{
printf ( "\nSIGTERM Received\n" ) ;
}
void conthandler ( int signum )
{
printf ( "\nSIGCONT Received\n" ) ;
}
int main( )
{
signal ( SIGINT, inthandler ) ;
signal ( SIGTERM, termhandler ) ;
signal ( SIGCONT, conthandler ) ;
while ( 1 )
printf ( "\rProgram Running" ) ;
return 0 ;
}

In this program apart from SIGINT we have additionally registered two new signals, namely, SIGTERM and SIGCONT. The signal( ) function is called thrice to register a different handler for each of the three signals. After registering the signals we enter a infinite while loop to print the ‘Program running’ message on the screen.

As in the previous program, here too, when we press Ctrl + C the handler for the SIGINT i.e. inthandler( ) is called. However, when we try to kill the program from the second terminal using the kill command the program does not terminate. This is because when the kill command is used it sends the running program a SIGTERM signal. The default handler for the message terminates the program. Since we have handled this signal ourselves, the handler for SIGTERM i.e. termhandler( ) gets called. As a result the printf( ) statement in the termhandler( ) function gets executed and the message ‘SIGTERM Received’ gets displayed on the screen. Once the execution of termhandler( ) function is over the program resumes its execution and continues to print ‘Program Running’. Then how are we supposed to terminate the program? Simple. Use the following command from the another terminal:

kill –SIGKILL 3276

As the command indicates, we are trying to send a SIGKILL signal to our program. A SIGKILL signal terminates the program.

Most signals may be caught by the process, but there are a few signals that the process cannot catch, and they cause the process to terminate. Such signals are often known as un-catchable signals. The SIGKILL signal is an un-catchable signal that forcibly terminates the execution of a process.
Note that even if a process attempts to handle the SIGKILL signal by registering a handler for it still the control would always land in the default SIGKILL handler which would terminate the program.
The SIGKILL signal is to be used as a last resort to terminate a program that gets out of control. One such process that makes uses of this signal is a system shutdown process. It first sends a SIGTERM signal to all processes, waits for a while, thus giving a ‘grace period’ to all the running processes. However, after the grace period is over it forcibly terminates all the remaining processes using the SIGKILL signal.
That leaves only one question—when does a process receive the SIGCONT signal? Let me try to answer this question.

A process under Linux can be suspended using the Ctrl + Z command. The process is stopped but is not terminated, i.e. it is suspended. This gives rise to the un-catchable SIGSTOP signal. To resume the execution of the suspended process we can make use of the fg (foreground) command. As a result of which the suspended program resumes its execution and receives the SIGCONT signal (CONT means continue execution).

Where Do You Go From Here 
 
You have now understood signal processing, the heart of programming under Linux. With that knowledge under your belt you are now capable of exploring the vast world of Linux on your own. Complete Linux programming deserves a book on its own. Idea here was to raise the hood and show you what lies underneath it. I am sure that if you have taken a good look at it you can try the rest yourselves. Good luck

No comments:

Post a Comment