diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-09-20 18:45:59 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-09-20 18:45:59 +0200 |
commit | f41a28fe3ec5042849583081ca0e1aa6c38a7187 (patch) | |
tree | fe9967e994ff0fa9357dca81174a3d0ed092a4f1 /src | |
parent | 45c427b23e035aac49bc961115a1beff1f74d5ee (diff) |
Daemonize async process to automatically reap the child when it dies
Diffstat (limited to 'src')
-rw-r--r-- | src/Program.c | 41 |
1 files changed, 29 insertions, 12 deletions
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; |