aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Makefile12
-rw-r--r--svcscan.c36
-rw-r--r--svcsupervise.c73
4 files changed, 108 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 3bb87b5..5394ff2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-scan
-supervise
+svcscan
+svcsupervise
*.o
svc
diff --git a/Makefile b/Makefile
index 81cdd2a..13ca6fe 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/svcscan.c b/svcscan.c
index 1de5b46..5286302 100644
--- a/svcscan.c
+++ b/svcscan.c
@@ -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;
}