1

My C program executes commands in a bash shell. To do this, I fork and in the child process I run:

char* command = "..."; /* provided by user */
execlp("/bin/bash", "bash", "-c", command, NULL);

If this is a long running command, I would like to have the option of killing it. For example, say I'm doing:

execlp("/bin/bash", "bash", "-c", "find / test", NULL);

After this, I know the PID of the child that is executing bash, but bash is forking a separate process to execute find.

$ ps aux | grep find
zmb       7802  0.0  0.1   5252  1104 pts/1    S+   11:17   0:00 bash -c find / test
zmb       7803  0.0  0.0   4656   728 pts/1    S+   11:17   0:00 find / test

I can kill the bash process (7802), but the find process (7803) still continues to execute. How can I ensure that the bash process propagates signals to it's children?

zmb
  • 7,605
  • 4
  • 40
  • 55

2 Answers2

3

from man 2 kill:

If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.

That is you may kill all children, direct or indirect which weren't created its own process group.

user3159253
  • 16,836
  • 3
  • 30
  • 56
2

It will send a SIGTERM to the Process Group ID passed in parameter and to all children.

kill -- -$(ps -o pgid= $PID | grep -o [0-9]*)

Also, more answers on this post : Best way to kill all child processes

Community
  • 1
  • 1
naab
  • 1,122
  • 1
  • 8
  • 25
  • It sends a TERM signal to the process `$PID_OF_TEST` and all children – naab Apr 12 '14 at 15:44
  • In this case `--` tells the next `-` to be treated as a negative sign and not a flag. I had tried this but mistakenly used `kill -- $PID` (was missing the final `-`). – zmb Apr 12 '14 at 15:54
  • This isn't quite working for me. `kill` is returning `ESRCH` (no such process). – zmb Apr 12 '14 at 16:03
  • I had to `setsid()` to create a new session in the child before `exec`ing bash. Everything works as expected now. – zmb Apr 12 '14 at 16:16