aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-09-20 18:45:59 +0200
committerdec05eba <dec05eba@protonmail.com>2020-09-20 18:45:59 +0200
commitf41a28fe3ec5042849583081ca0e1aa6c38a7187 (patch)
treefe9967e994ff0fa9357dca81174a3d0ed092a4f1 /src
parent45c427b23e035aac49bc961115a1beff1f74d5ee (diff)
Daemonize async process to automatically reap the child when it dies
Diffstat (limited to 'src')
-rw-r--r--src/Program.c41
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;