summary refs log tree commit diff
path: root/sandman.m
blob: 7d2f56ac9697cbd613eac08af2155ad66f06f5a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* 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 sharedWorkspace] notificationCenter]
		addObserverForName: NSWorkspaceWillSleepNotification
		object: nil
		queue: [NSOperationQueue mainQueue]
		usingBlock: ^(NSNotification *note) {
			(void)note;
			int error = kill(pid, SIGTSTP);
			if (error) err(EX_UNAVAILABLE, "kill %d", pid);
		}
	];
	
	[
		[[NSWorkspace sharedWorkspace] notificationCenter]
		addObserverForName: NSWorkspaceDidWakeNotification
		object: nil
		queue: [NSOperationQueue mainQueue]
		usingBlock: ^(NSNotification *note) {
			(void)note;
			int error = kill(pid, SIGCONT);
			if (error) err(EX_UNAVAILABLE, "kill %d", pid);
		}
	];

	[[NSApplication sharedApplication] run];
}
hover-highlight'> catgirl has no reconnect feature and generally must not do anything but read/write from/to the connected socket which does not require "inet" or "dns" promises. 2021-01-23Call pledge(2) after unveil(2)Klemens Nanni Simplify logic, be more idiomatic and finalize by pledging after all unveiling is done by omitting the "unveil" promise and thereby not allowing further calls to it. 2021-01-23Separate kiosk mode from restrict modeJune McEnroe Restrict mode will focus on sandboxing, while kiosk will continue to restrict IRC access through a public kiosk. Kiosk mode without restrict mode allows execution of man 1 catgirl with /help, assuming external sandboxing. The /list and /part commands are also added to the list of disabled commands in kiosk mode, since they are pointless without access to /join. 2021-01-21Simplify windowUpdate loops and factor out windowTopJune McEnroe No idea why I made that more complicated than it had to be looping backwards. 2021-01-21Document that M-l shows timestampsJune McEnroe 2021-01-19Don't lose swapped window when navigating to current bufferJeremy O'Brien 2021-01-19Use Warm heat for manually inserted blank linesJune McEnroe Oops, forgot about these. 2021-01-18Add example tmux(1) configKlemens Nanni Spawn one catgirl per network and handle reconnects through tmux, no extra tool required. 2021-01-17Use Warm heat for blank linesJune McEnroe So they're not hidden by M-+. 2021-01-16Add -I highlight option and /highlightJune McEnroe