diff options
-rw-r--r-- | Darwin.mk | 4 | ||||
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | sandman.1 | 34 | ||||
-rw-r--r-- | sandman.m | 72 |
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]; +} |