summary refs log tree commit diff
path: root/sandman.m
diff options
context:
space:
mode:
authorCurtis McEnroe2019-07-02 18:04:27 -0400
committerCurtis McEnroe2019-07-02 18:04:27 -0400
commit39a752c46e917c53de635b32b19c16e5c701ef5e (patch)
tree43e8b18a6571b3ba352f9a3f8a1f646ce4a88d89 /sandman.m
parentd8cffb8ae7c949a85b35a15f344fec592d7df060 (diff)
Restart process in sandman
Diffstat (limited to 'sandman.m')
-rw-r--r--sandman.m46
1 files changed, 33 insertions, 13 deletions
diff --git a/sandman.m b/sandman.m
index cc8bcc9..94c7d1a 100644
--- a/sandman.m
+++ b/sandman.m
@@ -1,4 +1,4 @@
-/* Copyright (C) 2018  Curtis McEnroe <june@causal.agency>
+/* Copyright (C) 2019  C. McEnroe <june@causal.agency>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
@@ -21,36 +21,43 @@
 #import <sysexits.h>
 #import <unistd.h>
 
-void handler(int sig) {
+static volatile sig_atomic_t sleeping;
+
+static void sigchld(int sig) {
 	(void)sig;
 	int status;
 	pid_t pid = wait(&status);
 	if (pid < 0) _exit(EX_OSERR);
-	if (WIFSIGNALED(status)) {
+	if (WIFSIGNALED(status) && WTERMSIG(status) != SIGHUP) {
 		_exit(128 + WTERMSIG(status));
-	} else {
+	} else if (!sleeping) {
 		_exit(WEXITSTATUS(status));
 	}
 }
 
+static pid_t spawn(char *argv[]) {
+	pid_t pid = fork();
+	if (pid < 0) err(EX_OSERR, "fork");
+	if (pid) return pid;
+	execvp(argv[0], argv);
+	err(EX_NOINPUT, "%s", argv[0]);
+}
+
+static pid_t pid;
+
 int main(int argc, char *argv[]) {
 	if (argc < 2) return EX_USAGE;
 
 	sigset_t mask;
 	sigemptyset(&mask);
-	struct sigaction sa = {
-		.sa_handler = handler,
+	struct sigaction action = {
+		.sa_handler = sigchld,
 		.sa_mask = mask,
 		.sa_flags = SA_NOCLDSTOP | SA_RESTART,
 	};
-	sigaction(SIGCHLD, &sa, NULL);
+	sigaction(SIGCHLD, &action, NULL);
 
-	pid_t pid = fork();
-	if (pid < 0) err(EX_OSERR, "fork");
-	if (!pid) {
-		execvp(argv[1], &argv[1]);
-		err(EX_NOINPUT, "%s", argv[1]);
-	}
+	pid = spawn(&argv[1]);
 
 	[
 		[[NSWorkspace sharedWorkspace] notificationCenter]
@@ -59,10 +66,23 @@ int main(int argc, char *argv[]) {
 		queue: nil
 		usingBlock: ^(NSNotification *note) {
 			(void)note;
+			sleeping = 1;
 			int error = kill(pid, SIGHUP);
 			if (error) err(EX_UNAVAILABLE, "kill %d", pid);
 		}
 	];
 
+	[
+		[[NSWorkspace sharedWorkspace] notificationCenter]
+		addObserverForName: NSWorkspaceDidWakeNotification
+		object: nil
+		queue: nil
+		usingBlock: ^(NSNotification *note) {
+			(void)note;
+			sleeping = 0;
+			pid = spawn(&argv[1]);
+		}
+	];
+
 	[[NSApplication sharedApplication] run];
 }