From f41a28fe3ec5042849583081ca0e1aa6c38a7187 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 20 Sep 2020 18:45:59 +0200 Subject: Daemonize async process to automatically reap the child when it dies --- src/Program.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/Program.c b/src/Program.c index fe2ae3f..bb476c4 100644 --- a/src/Program.c +++ b/src/Program.c @@ -33,12 +33,12 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void } else if(pid == 0) { /* child */ if(prctl(PR_SET_PDEATHSIG, SIGTERM) == -1) { perror("prctl(PR_SET_PDEATHSIG, SIGTERM) failed"); - exit(127); + _exit(127); } /* Test if the parent died before the above call to prctl */ if(getppid() != parent_pid) - exit(127); + _exit(127); dup2(fd[WRITE_END], STDOUT_FILENO); close(fd[READ_END]); @@ -46,7 +46,7 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void execvp(args[0], args); perror("execvp"); - exit(127); + _exit(127); } else { /* parent */ close(fd[WRITE_END]); @@ -151,16 +151,33 @@ int exec_program_async(const char **args, pid_t *result_process_id) { perror("Failed to fork"); return -err; } else if(pid == 0) { /* child */ - if(prctl(PR_SET_PDEATHSIG, SIGTERM) == -1) { - perror("prctl(PR_SET_PDEATHSIG, SIGTERM) failed"); - exit(127); - } - - /* Test if the parent died before the above call to prctl */ - if(getppid() != parent_pid) - exit(127); + if(result_process_id) { + if(prctl(PR_SET_PDEATHSIG, SIGTERM) == -1) { + perror("prctl(PR_SET_PDEATHSIG, SIGTERM) failed"); + _exit(127); + } - execvp(args[0], args); + /* Test if the parent died before the above call to prctl */ + if(getppid() != parent_pid) + _exit(127); + + execvp(args[0], args); + perror("execvp"); + _exit(127); + } else { + setsid(); + signal(SIGHUP, SIG_IGN); + + // Daemonize child to make the parent the init process which will reap the zombie child + pid_t second_child = fork(); + if(second_child == 0) { // child + execvp(args[0], args); + perror("execvp"); + _exit(127); + } else if(second_child != -1) { + _exit(0); + } + } } else { /* parent */ if(result_process_id) *result_process_id = pid; -- cgit v1.2.3