summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Darwin.mk4
-rw-r--r--Makefile17
-rw-r--r--sandman.134
-rw-r--r--sandman.m72
4 files changed, 119 insertions, 8 deletions
diff --git a/Darwin.mk b/Darwin.mk
index 7ef8901..d1f26cc 100644
--- a/Darwin.mk
+++ b/Darwin.mk
@@ -1,2 +1,4 @@
LIBRESSL_PREFIX = /usr/local/opt/libressl
-LDLIBS = -lcurses -ltls
+LDLIBS = -lcurses -ltls -framework Cocoa
+BINS += sandman
+MANS += sandman.1
diff --git a/Makefile b/Makefile
index 14a4a37..e09be8b 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,9 @@ CFLAGS += -I$(LIBRESSL_PREFIX)/include
LDFLAGS += -L$(LIBRESSL_PREFIX)/lib
LDLIBS = -lcursesw -ltls
+BINS = catgirl
+MANS = catgirl.1
+
-include config.mk
OBJS += chat.o
@@ -29,7 +32,7 @@ OBJS += url.o
TESTS += format.t
TESTS += term.t
-all: tags catgirl test
+all: tags $(BINS) test
$(OBJS): chat.h
@@ -47,14 +50,14 @@ test: $(TESTS)
tags: *.h *.c
ctags -w *.h *.c
-install: catgirl catgirl.1
+install: $(BINS) $(MANS)
install -d $(PREFIX)/bin $(MANDIR)1
- install catgirl $(PREFIX)/bin/catgirl
- install -m 644 catgirl.1 $(MANDIR)1/catgirl.1
+ install $(BINS) $(PREFIX)/bin
+ install -m 644 $(MANS) $(MANDIR)1
uninstall:
- rm -f $(PREFIX)/bin/catgirl
- rm -f $(MANDIR)1/catgirl.1
+ rm -f $(BINS:%=$(PREFIX)/bin/%)
+ rm -f $(MAN:%=%(MANDIR)1/%)
chroot.tar: catgirl catgirl.1 man.sh
install -d -o root -g wheel \
@@ -92,7 +95,7 @@ install-chroot: chroot.tar
tar -xf chroot.tar -C /home/$(CHROOT_USER)
clean:
- rm -fr $(OBJS) catgirl $(TESTS) tags root chroot.tar
+ rm -fr $(OBJS) $(BINS) $(TESTS) tags root chroot.tar
README: catgirl.7
mandoc catgirl.7 | col -bx > README
diff --git a/sandman.1 b/sandman.1
new file mode 100644
index 0000000..1cd0583
--- /dev/null
+++ b/sandman.1
@@ -0,0 +1,34 @@
+.Dd November 30, 2018
+.Dt SANDMAN 1
+.Os "Causal Agency"
+.
+.Sh NAME
+.Nm sandman
+.Nd signal sleep
+.
+.Sh SYNOPSIS
+.Nm
+.Ar command ...
+.
+.Sh DESCRIPTION
+.Nm
+is a utility for Darwin systems.
+.Nm
+runs the
+.Ar command
+in a child process
+and sends it
+.Dv SIGTSTP
+and
+.Dv SIGCONT
+signals
+when the computer goes to sleep
+and wakes from sleep,
+respectively.
+.
+.Sh EXIT STATUS
+.Nm
+exits with the exit status of the child process.
+.
+.Sh SEE ALSO
+.Xr signal 3
diff --git a/sandman.m b/sandman.m
new file mode 100644
index 0000000..12a4817
--- /dev/null
+++ b/sandman.m
@@ -0,0 +1,72 @@
+/* Copyright (C) 2018 Curtis 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <err.h>
+#import <signal.h>
+#import <stdlib.h>
+#import <sysexits.h>
+#import <unistd.h>
+
+void sigchld(int sig) {
+ (void)sig;
+ int status;
+ pid_t pid = wait(&status);
+ if (pid < 0) err(EX_OSERR, "wait");
+ if (WIFSIGNALED(status)) {
+ _exit(128 + WTERMSIG(status));
+ } else {
+ _exit(WEXITSTATUS(status));
+ }
+}
+
+int main(int argc, char *argv[]) {
+ if (argc < 2) return EX_USAGE;
+
+ signal(SIGCHLD, sigchld);
+
+ pid_t pid = fork();
+ if (pid < 0) err(EX_OSERR, "fork");
+
+ if (!pid) {
+ execvp(argv[1], &argv[1]);
+ err(EX_NOINPUT, "%s", argv[1]);
+ }
+
+ NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+ NSNotificationCenter *center = [workspace notificationCenter];
+ NSOperationQueue *main = [NSOperationQueue mainQueue];
+
+ [center addObserverForName:NSWorkspaceWillSleepNotification
+ object:nil
+ queue:main
+ usingBlock:^(NSNotification *note) {
+ (void)note;
+ int error = kill(pid, SIGTSTP);
+ if (error) err(EX_UNAVAILABLE, "kill %d", pid);
+ }];
+
+ [center addObserverForName:NSWorkspaceDidWakeNotification
+ object:nil
+ queue:main
+ usingBlock:^(NSNotification *note) {
+ (void)note;
+ int error = kill(pid, SIGCONT);
+ if (error) err(EX_UNAVAILABLE, "kill %d", pid);
+ }];
+
+ [[NSApplication sharedApplication] run];
+}