diff options
Diffstat (limited to 'src/exec.c')
-rw-r--r-- | src/exec.c | 24 |
1 files changed, 16 insertions, 8 deletions
@@ -15,7 +15,7 @@ struct process_info { pid_t pid; - int killed; + int dead; int stderr_pipe; process_exit_cb_t cb; void *user; @@ -60,7 +60,6 @@ static void close_child_pipe(struct process_info *p) { } - static void free_process_info(struct process_info *p) { assert (p); close_child_pipe(p); @@ -103,22 +102,29 @@ static void *oop_sigchld_cb(oop_source *source, int sig, void *user) { struct process_info *p; assert(source && sig == SIGCHLD); - if ((pid = wait(&status)) <= 0) { + if ((pid = waitpid(-1, &status, WUNTRACED)) <= 0) { daemon_log(LOG_ERR, "wait() failed: %s", strerror(errno)); return OOP_HALT; } + if (WIFSTOPPED(status)) { + daemon_log(LOG_ERR, "Child process stopped!"); + return OOP_CONTINUE; + } + if (!(p = find_process(pid))) { daemon_log(LOG_WARNING, "Got SIGCHLD for unknown process, reaping"); return OOP_CONTINUE; } - assert(p && p->cb); + assert(p && !p->dead); - if (!p->killed) + p->dead = 1; + if (p->cb) p->cb(pid, status, p->user); - remove_process(pid); + if (p->stderr_pipe < 0) + remove_process(pid); return OOP_CONTINUE; } @@ -149,6 +155,10 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user if (s == 0) { /* EOF */ close_child_pipe(p); + + if (p->dead) + remove_process(p->pid); + return OOP_CONTINUE; } @@ -224,7 +234,6 @@ pid_t child_process_create(const char *file, char *const argv[], int *ifd, int * p->cb = cb; p->user = user; p->next = procs; - p->killed = 0; p->stderr_pipe = stderr_fds[0]; close(stderr_fds[1]); @@ -324,6 +333,5 @@ int child_process_kill(pid_t pid) { return -1; } - p->killed = 1; return 0; } |