0

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 
2
  • See How to avoid using printf() in signal handlers? It explains that using printf() in a signal handler is no allowed by the C standard (which has incredibly rigid rules about what can appear in a signal handler) or POSIX (which has much more relaxed rules, but still doesn't allow you to use printf()). Commented May 28, 2022 at 15:48
  • Using both i and j seems a little odd; they are carefully kept with the same value. Commented May 28, 2022 at 15:50

2 Answers 2

2

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; } 
Sign up to request clarification or add additional context in comments.

2 Comments

the signal handler is calling itself ... why..? void sighup(int sig) { signal(SIGHUP, sighup); gotsig = sig; }
pause() can be call outside the while(1){}??
0
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<signal.h> void signint(int sig); void sighup(int sig); void sigquit(int sig); int gotsig; int main() { int pid,i; pid = fork(); if(pid < 0) { perror("fork"); exit(0); } if(pid == 0) { signal(SIGHUP,sighup); signal(SIGINT,signint); signal(SIGQUIT,sigquit); pause(); while(1) { if(gotsig == SIGINT) { printf("Child : Child process recieved SIGINT signal\n"); gotsig = -1; }else if(gotsig == SIGHUP) { printf("Child : Child process recieved SIGHUP signal\n"); gotsig = -1; }else if(gotsig == SIGQUIT) { printf("Dady killed me....!\n"); exit(0); } } }else { sleep(1); for(i = 1; i <=5 ; i++) { if(i % 2 == 0) { printf("Parent : sending SIGINT signal\n"); kill(pid,SIGINT); sleep(3); }else { printf("Parent : sending SIGHUP signal\n"); kill(pid,SIGHUP); sleep(3); } } printf("Parent : sending SIGQUIT signal\n"); kill(pid,SIGQUIT); } } void signint(int sig) { gotsig = sig; } void sighup(int sig) { gotsig = sig; } void sigquit(int sig) { gotsig = sig; } 

Above code work fine for me.

Output :

Parent : sending SIGHUP signal Child : Child process recieved SIGHUP signal Parent : sending SIGINT signal Child : Child process recieved SIGINT signal Parent : sending SIGHUP signal Child : Child process recieved SIGHUP signal Parent : sending SIGINT signal Child : Child process recieved SIGINT signal Parent : sending SIGHUP signal Child : Child process recieved SIGHUP signal Parent : sending SIGQUIT signal Dady killed me....! 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.