about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--daemon.h4
-rw-r--r--service.c29
2 files changed, 32 insertions, 1 deletions
diff --git a/daemon.h b/daemon.h
index 32827aa..5975034 100644
--- a/daemon.h
+++ b/daemon.h
@@ -67,6 +67,7 @@ extern char *serviceEnviron[EnvironLen];
 enum State {
 	Stop,
 	Start,
+	Restart,
 };
 
 enum { LineCap = 512 };
@@ -96,6 +97,9 @@ extern struct Services {
 
 int serviceAdd(const char *name, const char *command);
 void serviceStart(struct Service *service);
+void serviceStop(struct Service *service);
+void serviceRestart(struct Service *service);
+void serviceSignal(struct Service *service, int signal);
 
 extern char configError[];
 int configParse(const char *path);
diff --git a/service.c b/service.c
index ef4834a..290372d 100644
--- a/service.c
+++ b/service.c
@@ -19,6 +19,8 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <paths.h>
+#include <signal.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -108,7 +110,7 @@ err:
 }
 
 void serviceStart(struct Service *service) {
-	if (service->state == Start) return;
+	if (service->state != Stop) return;
 
 	if (service->intent == Start) {
 		struct timespec backoff = service->restartInterval;
@@ -164,3 +166,28 @@ void serviceStart(struct Service *service) {
 	);
 	err(StopExit, "%s", _PATH_BSHELL);
 }
+
+void serviceSignal(struct Service *service, int signal) {
+	if (service->state != Start) return;
+	int error = kill(service->pid, signal);
+	if (error) {
+		syslog(
+			LOG_ERR, "signal %s %s[%ju]: %m",
+			sys_signame[signal], service->name, (uintmax_t)service->pid
+		);
+	}
+}
+
+void serviceStop(struct Service *service) {
+	service->intent = Stop;
+	serviceSignal(service, SIGTERM);
+}
+
+void serviceRestart(struct Service *service) {
+	if (service->state == Start) {
+		service->intent = Restart;
+		serviceSignal(service, SIGTERM);
+	} else {
+		serviceStart(service);
+	}
+}