Search code examples
clinuxclone

Stop parent from terminating when child terminates?


I'd like to spawn a process and use stdin/out to communicate to it. That all works, but I noticed when the child terminates via signal the parent does too. Here's an example below. If you uncomment true the program will print "Finish". If you compile and uncomment selfterm then it won't and the parent will terminate with the exit code 137. Why does the parent terminate and how do I prevent it?

main.c

#include <signal.h>
#include <sched.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int doexec(void*) {
    //char*bin = "/usr/bin/true";
    //char*bin = "/tmp/selfterm";
    char*args[] = {bin, 0};
    int err = execv(bin, args);
    return err;
}
int main(int argc, char *argv[]) {
    int pid = clone(doexec, malloc(2*1024*1024)+2*1024*1024, CLONE_VFORK|SIGCHLD, 0);
    int status=0;
    wait(&status);
    puts("Finish");
}

selfterm.c

#include<signal.h>
int main(int argc, char *argv[]) { kill(0, 9); }

Solution

  • From kill() manual:

    If pid equals 0, then sig is sent to every process in the process group of the calling process.

    kill(0, 9); terminates all processes in the group including parent process.

    You can use raise() to send signal to the caller process:

    raise(SIGKILL);
    

    If you want to run child process in process group separated from parent, you can make child process to be a leader of new session with setsid():

    int doexec(void *) {
        char *args[] = { "./selfterm", NULL };
        setsid();
        execv(args[0], args);
        return 1;
    }