views:

834

answers:

4

I am trying to create a child process and then send SIGINT to the child without terminating the parent. I tried this:

pid=fork();
  if (!pid)
  {
      setpgrp();
      cout<<"waiting...\n";
      while(1);
  }
  else
      {
      cout<<"parent";
      wait(NULL);
      }

but when I hit C-c both process were terminated

+5  A: 

From the command line:

kill -INT pid

From C:

kill (pid, SIGINT);

where pid is the process ID you want to send the signal to.

The parent can get the relevant PID from the return value from fork(). If a child wants its own PID, it can call getpid().

paxdiablo
+2  A: 

You could try implementing a SIGINT signal handler which, if a child process is running, kills the child process (and if not, shuts down the application).

Alternatively, set the parent's SIGINT handler to SIG_IGN and the child's to SIG_DFL.

Matthew Iselin
I used `sigaction` to change the signal handler for the parent and it worked, but when tried to set the parent to SIG_IGN and the child to SIG_DFL both child and parent ignored the signal.
Yaron
A: 

Well, that is because Control-C is sending the signal to the parent process. And if you kill the parent, you kill the child. They both die.

Solution: Create a sighandler in the parent process using trap to catch SIGINT. Then you use the kill command to pass that to the child process whose id you have so cleverly saved in your pid variable.

Rap
+4  A: 

Aha, the mystery of process groups and sessions and process group leaders and session group leaders appears again.

Your control/C sent the signal to a group. You need to signal an individual pid, so follow paxdiablo's instructions or signal ("kill") the child from the parent. And don't busy wait! Put a sleep(1) in the loop, or better yet, one of the wait(2) system calls.

DigitalRoss
Busy wait was just for testing.... real program will be different
Yaron