In the following code, I try to send SIGINT, SIGHUP, SIGQUIT signal to child process.
void sighup(int sig);
void sigint(int sig);
void sigquit(int sig);
These are my signal handler.
the issue is signal handler never invoked.
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
void sighup(int sig);
void sigint(int sig);
void sigquit(int sig);
int main()
{
int pid, i, j, k;
if ((pid = fork()) < 0)
{
perror("fork");
exit(1);
}
if(pid == 0)
{
signal(SIGHUP, sighup);
signal(SIGINT, sigint);
signal(SIGQUIT, sigquit);
}
else
{
j = 0;
for (i = 1; i <= 5; i++)
{
j++;
if (i % 2 == 0)
{
printf("PARENT: sending SIGHUP Signal : %d\n", j);
kill(pid, SIGHUP);
sleep(3);
}
else
{
printf("PARENT: sending SIGINT signal : %d\n", j);
kill(pid, SIGINT);
sleep(3);
}
}
printf("Parent sending SIGQUIT\n");
kill(pid, SIGQUIT);
}
}
void sighup(int sig)
{
signal(SIGHUP, sighup);
printf("Child: I have received sighup\n");
}
void sigint(int sig)
{
signal(SIGINT, sigint);
printf("Child: I have received sighINT\n");
}
void sigquit(int sig)
{
printf("My daddy has killed me\n");
exit(0);
}
Below lines never printed on screen
Child: I have received sighup
Child: I have received sighINT
My daddy has killed me
Output
PARENT: sending SIGINT signal : 1
PARENT: sending SIGHUP Signal : 2
PARENT: sending SIGINT signal : 3
PARENT: sending SIGHUP Signal : 4
PARENT: sending SIGINT signal : 5
Parent sending SIGQUIT
>Solution :
You have two problems here.
First, after the child process sets up its signal handlers, it exits right away. So the parent might get to send the first signal depending on timing, but not any others.
Put the child in a pause loop to have it wait for signals.
The other problem is that it’s possible that the parent might send the first signal to the child before it can set up its signal handlers. So put a short delay in the parent to allow that to happen.
if(pid == 0)
{
signal(SIGHUP, sighup);
signal(SIGINT, sigint);
signal(SIGQUIT, sigquit);
while (1) pause();
}
else
{
sleep(1);
...
Also, calling printf and exit from a signal handler are not considered safe. It’s better to have the signal handlers set a global variable and have the main part of the code check for that.
int gotsig = 0;
void sighup(int sig)
{
signal(SIGHUP, sighup);
gotsig = sig;
}
void sigint(int sig)
{
signal(SIGINT, sigint);
gotsig = sig;
}
void sigquit(int sig)
{
gotsig = sig;
}
...
while (1) {
pause();
if (gotsig == SIGHUP) {
printf("Child: I have received sighup\n");
} else if (gotsig == SIGINT) {
printf("Child: I have received sighINT\n");
} else if (gotsig == SIGQUIT) {
printf("My daddy has killed me\n");
exit(0);
}
gotsig = 0;
}