How to kill a process tree programmatically on Linux using C
c, kill, linux, process, tree
Solution
Use setpgid in the child to set its GPID equal to its own PID. The parent then can kill(-pid,...) to signal the entire group.
pid_t pid = fork();
if(pid == 0) {
setpgid(0, 0);
execl("/bin/sh", "sh", "-c", exePath);
exit(127);
} else if(pid == -1) {
// timeout code
if(timeout) {
kill(-pid, SIGTERM);
sleep(2);
kill(-pid, SIGKILL);
}
}
That should do it.
One more thing, when you spawn a shell, make sure it doesn't enable job control. Otherwise, it will create its own process groups. Your "/bin/sh -c" is fine.
Problem
I am trying to write a function that spawns a child process, lets it run for a certain amount of time and then kills it if it hasn't finished: ``` int sysExecTimeout(const char * exePath, int timeoutSec); ``` In the function, I use `fork` and `execl` to spawn the child, and, when it times out, I use `kill(pid, SIGTERM)` and `kill(pid, SIGKILL)` after 2 seconds, to ensure the child dies: ``` pid_t pid = fork(); if(pid == 0) { execl("/bin/sh", "sh", "-c", exePath); exit(127); } else if(pid != -1) { // timeout code if(timeout) { kill(pid, SIGTERM); sleep(2); kill(pid, SIGKILL); } } ``` I am using Linux, and it seems that when a parent process dies, the child is not killed automatically. So the two `kill` calls will just kill the `/bin/sh` process and leave the `exePath` command running, since it is a child process of `/bin/sh`. I am trying to write the `sysExecTimeout` function such that it kills the entire process tree rooted at `pid`, where `pid` is the PID from `pid = fork()` I need this because the `exePath` command will spawn other commands, which can also spawn other commands, which could get stuck and consume resources. I do not have control over the `exePath` binaries/scripts that get executed, so I cannot write my own parent-dies-so-kill-the-children logic in them. I tried using `kill(0, SIGTERM)`, which almost did the job, except it also killed my own process :) I am wondering if there is a flag I can turn on programatically in C that says "hey man, when I die, take all my children and kill them, and repeat recursively for their children" such that the entire process tree started from that program dies (assuming the PID/PPID chain can be followed). I could use that flag here: ``` if(pid == 0) { turnOnRecursiveDeathFlag(); system(exePath); //execl("/bin/sh", "sh", "-c", exePath); exit(127); } ``` Is there a way to do that? I've been searching for a while, but all I can find are hacks using `ps -ef`, or modifying the children processes that you are running etc.