summaryrefslogtreecommitdiffstats
path: root/src/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.c')
-rw-r--r--src/exec.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/exec.c b/src/exec.c
index 728c574..d9195c6 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -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;
}