A signal is an event generated by the UNIX and Linux systems in response to some condition, upon receipt of which a process may in turn take some action.
A signal is just like a interrupt, when it is generated by user level, a call is made to the kernel of the OS and it will action accordingly.
Signal names are defined by including the header file signal.h.
If a process receives one of these signals without first arranging to catch it, the process will be terminated immediately. Usually, a core dump file is created. This file, called core and placed in the current directory, is an image of the process that can be useful in debugging.
Syntax : –
#include <signal.h> void (*signal(int sig, void (*func)(int)))(int);
signal is a function that takes two parameters, sig and func.
The signal to be caught or ignored is given as argument sig.
The function to be called when the specified signal is received is given as func.
There are two types of signals in linux –
- Maskable
- Non-maskable
Maskable signals or interrupts in Linux are those signals which can be changed or ignonered by the user. For example, Ctrl+C , Ctrl+\.
Non-Maskable signals or interrupts are those interrupts whick cannot be changed or ignored by the user. For example, Ctrl+Z.
EXAMPLE –
#include<stdio.h> #include<signal.h> #include<sys/types.h> void sig_handler1(int num) { printf("You are here becoz of signal:%d\n",num); signal(SIGQUIT,SIG_DFL); } void sig_handler(int num) { printf("\nHi! You are here becz of signal:%d\n",num); } int main() { signal(SIGINT,sig_handler1); signal(SIGQUIT,sig_handler); while(1) { printf("Hello\n"); sleep(2); } }
Output :
Typing Ctrl+C (shown as ^C in the following output) for the first time causes the program to react and
then continue. When you type Ctrl+C again, the program ends because the behavior of SIGINT has
returned to the default behavior of causing the program to exit.
Sending Signals :-
A process may send a signal to another process, including itself, by calling kill. The call will fail if the program doesn’t have permission to send the signal, often because the target process is owned by another user.
Syntax : –
#include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig);
The kill function sends the specified signal, sig, to the process whose identifier is given by pid. It returns zero on success. To send a signal, the sending process must have permission to do so.(superuser can send signals to any process)
Example –
#include<stdio.h> #include<sys/types.h> #include<signal.h> int main() { kill(getppid(),SIGKILL); sleep(5); }
It will take the pid of current opened terminal and after compiling this code, it will create a a.out executable file.
Run- ./a.out
It will close or we can say kill the terminal.
Signals provide you with a useful alarm clock facility. The alarm function call can be used by a process to schedule a SIGALRM signal at some time in the future.
Syntax :
#include <unistd.h> unsigned int alarm(unsigned int seconds);
The alarm call schedules the delivery of a SIGALRM signal in seconds.
Calling alarm before the signal is received will cause the alarm to be rescheduled.
alarm returns the number of seconds left before any outstanding alarm call would be sent, or -1 if the call fails.
Example –
#include<stdio.h> #include<signal.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<sys/wait.h> void sig_handler(int num) { printf("\nChild Sent a signal to parent:%d\n",num); signal(SIGALRM,SIG_DFL); } int main() { int status; system("clear"); printf("\n--------Signal Handling Across Processes----------\n"); switch(fork()) { case -1: perror("\nFork Failed...\n"); exit(1); break; case 0: alarm(3); kill(getppid(),SIGALRM); //signal(SIGALRM,sig_handler); printf("\nIts Child Process\n"); sleep(5); break; default: signal(SIGALRM,sig_handler); wait(&status); printf("\nIts Parent Process\n"); } }
Output – ./a.out