summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCurtis McEnroe2019-07-02 18:04:27 -0400
committerCurtis McEnroe2019-07-02 18:04:27 -0400
commit39a752c46e917c53de635b32b19c16e5c701ef5e (patch)
tree43e8b18a6571b3ba352f9a3f8a1f646ce4a88d89
parentd8cffb8ae7c949a85b35a15f344fec592d7df060 (diff)
Restart process in sandman
-rw-r--r--sandman.113
-rw-r--r--sandman.m46
2 files changed, 40 insertions, 19 deletions
diff --git a/sandman.1 b/sandman.1
index 2cdd70b..bd68874 100644
--- a/sandman.1
+++ b/sandman.1
@@ -1,4 +1,4 @@
-.Dd December 2, 2018
+.Dd July 2, 2019
.Dt SANDMAN 1
.Os
.
@@ -15,11 +15,12 @@
is a utility for Darwin systems.
It runs the
.Ar command
-as a child process
-and sends it the
-.Dv SIGHUP
-signal
-when the system goes to sleep.
+as a child process.
+When the system goes to sleep,
+the process is sent
+.Dv SIGHUP .
+When the system wakes up,
+the process is restarted.
.
.Sh EXIT STATUS
.Nm
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];
}