diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | svcscan.c | 36 | ||||
-rw-r--r-- | svcsupervise.c | 73 |
4 files changed, 108 insertions, 17 deletions
@@ -1,4 +1,4 @@ -scan -supervise +svcscan +svcsupervise *.o svc @@ -1,6 +1,14 @@ +CFLAGS ?= -std=c11 -Wall -Werror -pedantic + +all: svcscan svcsupervise + svcscan: svcscan.c - ${CC} -o svcscan -Wall -Werror -pedantic svcscan.c + ${CC} ${CFLAGS} -o svcscan svcscan.c svcsupervise: svcsupervise.c - ${CC} -o svcsupervise -Wall -Werror -pedantic svcsupervise.c + ${CC} ${CFLAGS} -o svcsupervise svcsupervise.c + +.PHONY: clean +clean: + rm -f svcscan svcsupervise @@ -127,13 +127,15 @@ direxists(const char *dir) return r; } -void +int start_supervisor(struct svc *service) { char *path; if ((asprintf(&path, "%s/%s", supdir, service->dir)) == -1 || - path == NULL) - err(1, "asprintf()"); + path == NULL) { + perror("asprintf()"); + return 0; + } pid_t p = fork(); if (p == 0) { /* Child */ @@ -141,21 +143,24 @@ start_supervisor(struct svc *service) super_path[1] = path; - if (execv(super_path[0], super_path)) + if (execv(super_path[0], super_path) == -1) err(1, "execv()"); } else if (p > 0) { /* Parent */ service->supervisor = p; } else { - err(1, "fork()"); + perror("fork()"); } free(path); + + return 1; } -void +int start_dead() { struct svc *np, *tmp; + int ret = 1; TAILQ_FOREACH_SAFE(np, &svc_norun, entries, tmp) { if (!direxists(np->dir)) { @@ -163,10 +168,13 @@ start_dead() continue; } - start_supervisor(np); - - move_run(np); + if (start_supervisor(np) == 0) + ret = 0; + else + move_run(np); } + + return ret; } void @@ -431,7 +439,10 @@ main(int argc, char **argv) err(1, "kevent()"); scan_svcdir(dir_fd); - start_dead(); + if (start_dead() == 0) { + if (kevent(kq, &evt[5], 1, NULL, 0, NULL) == -1) + perror("kevent()"); + } for (;;) { if ((e = kevent(kq, NULL, 0, revt, 6, NULL)) == -1) { @@ -452,7 +463,10 @@ main(int argc, char **argv) goto end; } } else if (revt[i].filter == EVFILT_TIMER && revt[i].ident == 1) { - start_dead(); + if (start_dead() == 0) { + if (kevent(kq, &evt[5], 1, NULL, 0, NULL) == -1) + perror("kevent()"); + } } else { fprintf(stderr, "Unknown event\n"); } diff --git a/svcsupervise.c b/svcsupervise.c index 95ede21..5872e1e 100644 --- a/svcsupervise.c +++ b/svcsupervise.c @@ -3,11 +3,17 @@ #include <unistd.h> #include <errno.h> #include <err.h> +#include <string.h> +#include <signal.h> #include <sys/types.h> +#include <sys/event.h> +#include <sys/time.h> #include <sys/stat.h> #include <sys/file.h> #include <sys/wait.h> +#include "status.h" + char *const run_path[] = { "./run", NULL }; void @@ -73,10 +79,41 @@ update_status() perror("rename()"); } +void +setup_signals() +{ + struct sigaction act; + memset(&act, 0, sizeof(act)); + + act.sa_handler = SIG_IGN; + if (sigaction(SIGHUP, &act, NULL) == -1) + err(1, "sigaction()"); + if (sigaction(SIGINT, &act, NULL) == -1) + err(1, "sigaction()"); + if (sigaction(SIGTERM, &act, NULL) == -1) + err(1, "sigaction()"); +} + +void +reset_signals() +{ + struct sigaction act; + memset(&act, 0, sizeof(act)); + + act.sa_handler = SIG_DFL; + if (sigaction(SIGHUP, &act, NULL) == -1) + err(1, "sigaction()"); + if (sigaction(SIGINT, &act, NULL) == -1) + err(1, "sigaction()"); + if (sigaction(SIGTERM, &act, NULL) == -1) + err(1, "sigaction()"); +} + int main(int argc, char **argv) { - int lock_fd; + int ctrl_fd, ok_fd, lock_fd, kq; + struct kevent evt[6], revt[6]; if (argc != 2) errx(1, "Usage: %s <dir>\n", argv[0]); @@ -95,10 +132,42 @@ main(int argc, char **argv) if (mkfifo("supervise/ok", 0600) == -1 && errno != EEXIST) err(1, "mkfifo()"); - start_proc(); /* XXX: Main loop goes here */ + setup_signals(); + + kq = kqueue(); + if (kq == -1) + err(1, "kqueue()"); + + if ((ctrl_fd = open("supervise/control", O_RDONLY | O_NONBLOCK | O_CLOEXEC)) == -1) + err(1, "open()"); + + if ((ok_fd = open("supervise/ok", O_RDONLY | O_NONBLOCK | O_CLOEXEC)) == -1) + err(1, "open()"); + + EV_SET(&evt[0], SIGHUP, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); + EV_SET(&evt[1], SIGINT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); + EV_SET(&evt[2], SIGTERM, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); + EV_SET(&evt[3], SIGCHLD, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); + EV_SET(&evt[4], ctrl_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); + //EV_SET(&evt[5], ok_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); + + if (kevent(kq, evt, 5, NULL, 0, NULL) == -1) + err(1, "kevent()"); + + for (;;) { + start_proc(); + break; + + kevent(kq, NULL, 0, revt, 5, NULL); + } + + if (close(ctrl_fd) == -1) + perror("close()"); if (close(lock_fd) == -1) perror("close()"); + reset_signals(); + return 0; } |