From 39a752c46e917c53de635b32b19c16e5c701ef5e Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Tue, 2 Jul 2019 18:04:27 -0400 Subject: Restart process in sandman --- sandman.1 | 13 +++++++------ sandman.m | 46 +++++++++++++++++++++++++++++++++------------- 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 +/* Copyright (C) 2019 C. McEnroe * * 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 #import -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]; } -- cgit 1.4.1-2-gfad0