UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » Processes
  • » Sending signal from child to parent process!

#1 2009-11-05 09:18 PM

thierryhenry
Member
Registered: 2009-11-02
Posts: 2

Re: Sending signal from child to parent process!

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 let me know how to carry this signalling from child to parent?

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);
}
}

Offline

#2 2009-11-05 09:54 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: Sending signal from child to parent process!

Your child is running first and sending the signal before you setup the signal
handler in the parent...  Move the sigaction() stuff prior to the fork()...

Offline

#3 2009-11-06 03:07 AM

thierryhenry
Member
Registered: 2009-11-02
Posts: 2

Re: Sending signal from child to parent process!

Thank you. Now I get it.

Hey, I have two more questions. I was trying sigaction before fork(), but I see some unexpected results!
1. 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);
    }
}

2. 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!

Offline

#4 2009-11-06 02:22 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: Sending signal from child to parent process!

First of all, don't mix stdio I/O with raw FD-based I/O like that, or you're likely to get
lots of wacky, unexpected results...  Either use write(STDOUT_FILENO) everywhere,
or printf() everywhere...  In fact, just switch to raw FD I/O, because even if you go to
printf() everywhere, the way your code currently is, you're still going to get wacky
duplicate output behavior...  Because, stdout is line-buffered by default, so those
printf()'s with no "\n"s in them done before the fork() will just sit in the stdio buffers
and not be flushed until exit time (or you eventually printf() a newline later), and the
fork() will duplicate the stdio buffer contents so both parent and child think they need
to flush that data out eventually...

For ease, throw a "#define _GNU_SOURCE 1" at the top of your source (before the
#includes), and switch to dprintf(STDOUT_FILENO) in place of printf()...  Doing that
eliminates the duplicate output (and immediately outputs the messages as printed,
without buffering)...

But, right now, you're doing the sleep() before fork()'ing, which I don't think you
want, either...  You want the parent to sleep (waiting to be killed by the child), but
there's absolutely no point in sleeping before the fork()...  And, if you just blindly
throw it AFTER the fork() in the parent code, then chances are the child will have
run and done its kill() BEFORE the parent even goes into the sleep(), so if you're
counting on the signal to bust you out of the sleep() prematurely, it probably won't
unless you have the child do a smaller sleep() (or sched_yield() or something) to
let the parent run first...

As for sending multiple signals...  Standard POSIX signals coelesce...  Multiple
outstanding instances of the same signal will appear as only one occurance to the
app on the receiving end...  So, if you do kill() rapidly twice in a row with the same
signal to the same app, chances are that app will only see one of them...  Throw a
sleep() or something between the two kill()'s, and you'll probably see both...  But,
the point is, there's no guarantee...  If you need reliable queued signals, then use
real-time signals...  (Or, better yet, find a much better method of IPC than ugly-ass
signals...)

Offline

#5 2009-11-07 03:05 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: Sending signal from child to parent process!

Do a fflush(NULL) before the fork() and you should be fine.

Offline

#6 2009-11-07 07:39 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: Sending signal from child to parent process!

Do a fflush(NULL) before the fork() and you should be fine.

But, if you do that and stick with stdio, then you'd also want to switch the write() in the
signal handler to printf()...  Mixing raw FD I/O and stdio I/O on the same FD is never
a wise idea...  But, at the same time, using stdio within a signal handler isn't
technically allowed, either, because it's not async-safe...  So, you're going to have
to break one rule or another in that situation...

So, that's why I just suggested sticking with raw FD I/O everywhere, since you kind
of have to use it in the handler anyway...  Of course, this is all just dummy/example
code, and the output is all pretty meaningless, anyway...   But, it's still something
good to be aware of for any real code...

Offline

  • Index
  • » Processes
  • » Sending signal from child to parent process!

Board footer

Powered by FluxBB