diff options
Diffstat (limited to 'svcsupervise.c')
-rw-r--r-- | svcsupervise.c | 121 |
1 files changed, 78 insertions, 43 deletions
diff --git a/svcsupervise.c b/svcsupervise.c index 0770f87..e3b36fd 100644 --- a/svcsupervise.c +++ b/svcsupervise.c @@ -16,17 +16,20 @@ #include "status.h" char *const run_path[] = { "./run", NULL }; +int ctrl_fd, ok_fd, lock_fd, kq, wantup; +struct kevent evt[7], revt[7]; -void +int start_proc() { pid_t p = fork(); if (p == 0) { execv(run_path[0], run_path); + err(111, "execv()"); } else if (p > 0) { - /* XXX: Do something apropriate here */ + return 1; } else { - err(1, "fork()"); + return 0; } } @@ -218,11 +221,78 @@ try_wait() } int +handle_signal(struct kevent *revt) +{ + if (revt->ident == SIGCHLD) { + if (try_wait()) { + if (kevent(kq, &evt[6], 1, NULL, 0, NULL) == -1) + perror("kevent()"); + } + } + if (revt->ident == SIGHUP || + revt->ident == SIGINT || + revt->ident == SIGTERM) { + return 0; + } + return 1; +} + +void +try_start() +{ + if (start_proc() == 0) { + if (kevent(kq, &evt[6], 1, NULL, 0, NULL) == -1) + perror("kevent()"); + } +} + +int +read_fds(struct kevent *revt) +{ + if (revt->ident == ctrl_fd) { + if (handle_ctrl_command(ctrl_fd) == 0) + return 0; + } + if (revt->ident == ok_fd) { + char buf[1024]; + read(ok_fd, buf, sizeof(buf)); + /* Make sure the ok pipe doesn't fill up */ + } + + return 1; +} + +int +loop() +{ + int e, i; + e = kevent(kq, NULL, 0, revt, 6, NULL); + if (e == -1) { + if (errno != EINTR) + perror("kevent()"); + } else if (e > 0) { + for (i = 0; i < e; i++) { + if (revt[i].filter == EVFILT_SIGNAL) { + if (handle_signal(&revt[i]) == 0) + return 0; + } else if (revt[i].filter == EVFILT_TIMER && revt[i].ident == 1) { + try_start(); + } else if (revt[i].filter == EVFILT_READ) { + if (read_fds(&revt[i]) == 0) + return 0; + } else { + fprintf(stderr, "Unknown event\n"); + } + } + } + + return 1; +} + +int main(int argc, char **argv) { - int ctrl_fd, ok_fd, lock_fd, kq, e, i, wantup; struct stat sb; - struct kevent evt[7], revt[7]; struct procctl_reaper_kill rk; struct procctl_reaper_status rs; @@ -279,48 +349,13 @@ main(int argc, char **argv) err(1, "kevent()"); if (wantup) - start_proc(); + try_start(); for (;;) { - e = kevent(kq, NULL, 0, revt, 6, NULL); - if (e == -1) { - if (errno != EINTR) - perror("kevent()"); - continue; - } else if (e > 0) { - for (i = 0; i < e; i++) { - if (revt[i].filter == EVFILT_SIGNAL) { - if (revt[i].ident == SIGCHLD) { - if (try_wait()) { - if (kevent(kq, &evt[6], 1, NULL, 0, NULL) == -1) - perror("kevent()"); - } - } - if (revt[i].ident == SIGHUP || - revt[i].ident == SIGINT || - revt[i].ident == SIGTERM) { - goto end; - } - } else if (revt[i].filter == EVFILT_TIMER && revt[i].ident == 1) { - start_proc(); /* XXX: Handle some failures here */ - } else if (revt[i].filter == EVFILT_READ) { - if (revt[i].ident == ctrl_fd) { - if (handle_ctrl_command(ctrl_fd) == 0) - goto end; - } - if (revt[i].ident == ok_fd) { - char buf[1024]; - read(ok_fd, buf, sizeof(buf)); - /* Make sure the ok pipe doesn't fill up */ - } - } else { - fprintf(stderr, "Unknown event\n"); - } - } - } + if (loop() == 0) + break; } -end: if (procctl(P_PID, getpid(), PROC_REAP_STATUS, &rs) != -1) { if (rs.rs_children > 0) { rk.rk_sig = SIGTERM; |