Hi All,
I facing a problem in handling signals between parent process communication. I am trying to send a signal(SIGINT) from child to parent. I am using kill function to do so and I am trying to read the signal using sigaction(). But the program is ending abruptly and I am not able to figure out why! Could anyone of you please help me?
The code is as follows :
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
void sig_usr(int signo){
if(signo == SIGINT)
printf("Signal caught!");
return;
}
int main(void){
pid_t pid, ppid;
ppid = getpid();
printf("%d ", ppid);
if((pid = fork()) == 0){ //Child
kill(ppid, SIGINT);
}
else{
printf("%d %d ",ppid, pid);
struct sigaction sig;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sig.sa_handler = sig_usr;
if(sigaction(SIGINT,&sig,NULL) == 0)
printf("Signal processed OKay ");
sleep(10);
}
}
start by setting up the signal handler before you create the child
int main(void)
{
pid_t pid, ppid;
ppid = getpid();
struct sigaction sig;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sig.sa_handler = sig_usr;
printf("%d ", ppid);
if((pid = fork()) == 0)
{ //Child
kill(ppid, SIGINT);
}
else
{
printf("%d %d ",ppid, pid);
if(sigaction(SIGINT,&sig,NULL) == 0)
printf("Signal processed OKay ");
sleep(10);
}
}
And... consider not using functions like printf in a signal handler. See async-signal safe
functions:
System Interfaces Chapter 2
Thank you. But I didnt get why printf() should not be used...Looking at the link you have posted, I am guessing functions like printf cannot be interruped in the middle. Am I right?
And which other function should I consider using for printing within handler?
The reverse - printf CAN be interrupted so you get a hashcan result.
write() - which is listed in the functions in the link.
Let me rephrase this correctly - async-signal safe functions are defined to be usable in signal handlers and have them behave as advertised.
When executing a call that is not async-signal safe you get undefined results when a second signal hits a signal handler that is currently executing that function. ie., if the function call works it is purely by accident not design.
printf is a large chunk of code made from a lot of functions and system calls. write() is a single base system call that is not made of sub-functions and code in user space like printf. It is a single kernel mode call.
Thank you. Now I get it.
Hey, I have two more questions. I was trying sigaction before fork(), but I see some unexpected results!
- I trigger SIGINT signal only once using kill function. I expect this to trigger respective signal handler and do the operation. But even if I am sending SIGINT only once, I am getting "Signal processed OKay" printed twice! Shouldn't this be printed only once as I am sending SIGINT only once?
Output :
Signal processed OKay 7006 0 Success SIGINT signal caught!!
Signal processed OKay 7006
Source code :
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
static void sig_usr(int signo){
if(signo == SIGINT){
char buf[] = "SIGINT signal caught!!\n";
int wr = strlen(buf);
write(STDOUT_FILENO, buf, wr);
}
return;
}
int main(void)
{
pid_t pid, ppid;
ppid = getpid();
struct sigaction sig;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sig.sa_handler = sig_usr;
if(sigaction(SIGINT,&sig,NULL) == 0)
printf("Signal processed OKay ");
sleep(10);
printf("%d ", ppid);
if((pid = fork()) == 0)
{ //Child
kill(ppid, SIGINT);
}
}
- Secondly, I am facing some problems when I try to send 2 SIGINT signals one after the other continuously from child process! i.e, when another kill() function is used after the first one in above code. The result I expected was two "SIGINT signal caught!!" messages. But I am getting only one instead.
In general, if I am sending signals of same kind continuously of same kind from child to parent, anything in particular I need to do?
Sorry for the elongated mail. Please help.
Regards!