summary refs log tree commit diff
path: root/scripts
diff options
context:2020-02-09
    ion>space:mode:
    authorJune McEnroe <june@causal.agency>2020-02-12 21:31:09 -0500
    committerJune McEnroe <june@causal.agency>2020-02-12 21:31:09 -0500
    commit9bed890aa889dad4c46b6d18fff8cbdac9feab1a (patch)
    treed408ff3884efc17c440bec56ee8311aecaecbc62 /scripts
    parentDocument scripts in README (diff)
    downloadcatgirl-9bed890aa889dad4c46b6d18fff8cbdac9feab1a.tar.gz
    catgirl-9bed890aa889dad4c46b6d18fff8cbdac9feab1a.zip
    Add sandman wrapper
    Diffstat (limited to '')
    -rw-r--r--scripts/.gitignore1
    -rw-r--r--scripts/sandman.136
    -rw-r--r--scripts/sandman.m88
    3 files changed, 125 insertions, 0 deletions
    diff --git a/scripts/.gitignore b/scripts/.gitignore
    new file mode 100644
    index 0000000..f6dc107
    --- /dev/null
    +++ b/scripts/.gitignore
    @@ -0,0 +1 @@
    +sandman
    diff --git a/scripts/sandman.1 b/scripts/sandman.1
    new file mode 100644
    index 0000000..35765ec
    --- /dev/null
    +++ b/scripts/sandman.1
    @@ -0,0 +1,36 @@
    +.Dd February 12, 2020
    +.Dt SANDMAN 1
    +.Os
    +.
    +.Sh NAME
    +.Nm sandman
    +.Nd sleep wrapper
    +.
    +.Sh SYNOPSIS
    +.Nm
    +.Op Fl t Ar secs
    +.Ar command ...
    +.
    +.Sh DESCRIPTION
    +The
    +.Nm
    +utility wraps a
    +.Ar command ,
    +sending it
    +.Dv SIGHUP
    +when the system goes to sleep,
    +and restarting it
    +when the system wakes.
    +.
    +.Pp
    +The arguments are as follows:
    +.Bl -tag -width Ds
    +.It Fl t Ar secs
    +Wait for
    +.Ar secs
    +before restarting the process.
    +The default is 8 seconds.
    +.El
    +.
    +.Sh AUTHORS
    +.An June Bug Aq Mt june@causal.agency
    diff --git a/scripts/sandman.m b/scripts/sandman.m
    new file mode 100644
    index 0000000..838920d
    --- /dev/null
    +++ b/scripts/sandman.m
    @@ -0,0 +1,88 @@
    +/* Copyright (C) 2019, 2020  C. McEnroe <june@causal.agency>
    + *
    + * This program is free software: you can redistribute it and/or modify
    + * it under the terms of the GNU 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 General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program.  If not, see <https://www.gnu.org/licenses/>.
    + */
    +
    +#import <Cocoa/Cocoa.h>
    +#import <err.h>
    +#import <signal.h>
    +#import <stdio.h>
    +#import <stdlib.h>
    +#import <sysexits.h>
    +#import <unistd.h>
    +
    +typedef unsigned uint;
    +
    +static pid_t pid;
    +static void spawn(char *argv[]) {
    +	pid = fork();
    +	if (pid < 0) err(EX_OSERR, "fork");
    +	if (pid) return;
    +	execvp(argv[0], argv);
    +	err(EX_CONFIG, "%s", argv[0]);
    +}
    +
    +static void handler(int signal) {
    +	(void)signal;
    +	int status;
    +	pid_t pid = wait(&status);
    +	if (pid < 0) _exit(EX_OSERR);
    +	_exit(status);
    +}
    +
    +int main(int argc, char *argv[]) {
    +	uint delay = 8;
    +
    +	int opt;
    +	while (0 < (opt = getopt(argc, argv, "t:"))) {
    +		switch (opt) {
    +			break; case 't': delay = strtoul(optarg, NULL, 10);
    +			break; default:  return EX_USAGE;
    +		}
    +	}
    +	argc -= optind;
    +	argv += optind;
    +	if (!argc) errx(EX_USAGE, "command required");
    +
    +	NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
    +	NSNotificationCenter *notifCenter = [workspace notificationCenter];
    +
    +	[notifCenter addObserverForName:NSWorkspaceWillSleepNotification
    +							 object:nil
    +							  queue:nil
    +						 usingBlock:^(NSNotification *notif) {
    +							 (void)notif;
    +							 signal(SIGCHLD, SIG_IGN);
    +							 int error = kill(pid, SIGHUP);
    +							 if (error) err(EX_UNAVAILABLE, "kill");
    +							 int status;
    +							 wait(&status);
    +						 }];
    +
    +	[notifCenter addObserverForName:NSWorkspaceDidWakeNotification
    +							 object:nil
    +							  queue:nil
    +						 usingBlock:^(NSNotification *notif) {
    +							 (void)notif;
    +							 warnx("waiting %u seconds...", delay);
    +							 sleep(delay);
    +							 signal(SIGCHLD, handler);
    +							 spawn(argv);
    +						 }];
    +
    +	signal(SIGCHLD, handler);
    +	spawn(argv);
    +
    +	[[NSApplication sharedApplication] run];
    +}