diff options
Diffstat (limited to 'catsit-timer.c')
-rw-r--r-- | catsit-timer.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/catsit-timer.c b/catsit-timer.c new file mode 100644 index 0000000..2869311 --- /dev/null +++ b/catsit-timer.c @@ -0,0 +1,70 @@ +/* Copyright (C) 2021 C. 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/>. + */ + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <sysexits.h> +#include <unistd.h> + +static void run(char *argv[]) { + pid_t pid = fork(); + if (pid < 0) err(EX_OSERR, "fork"); + if (!pid) { + execvp(argv[0], argv); + err(126, "%s", argv[0]); + } + + int status; + pid = wait(&status); + if (pid < 0) err(EX_OSERR, "wait"); + if (WIFEXITED(status)) { + status = WEXITSTATUS(status); + if (status) exit(status); + } else { + exit(status); + } +} + +int main(int argc, char *argv[]) { + if (argc < 2) errx(EX_USAGE, "interval required"); + if (argc < 3) errx(EX_USAGE, "command required"); + + unsigned interval = 0; + char *spec = argv[1]; + while (*spec) { + unsigned num = strtoul(spec, &spec, 10); + switch (*spec) { + break; case '\0': interval += num; + break; case 's': spec++; interval += num; + break; case 'm': spec++; interval += 60 * num; + break; case 'h': spec++; interval += 60 * 60 * num; + break; default: errx(EX_USAGE, "invalid interval unit %c", *spec); + } + } + if (!interval) errx(EX_USAGE, "invalid zero interval"); + +#ifdef __OpenBSD__ + int error = pledge("stdio proc exec", NULL); + if (error) err(EX_OSERR, "pledge"); +#endif + + for (;;) { + run(&argv[2]); + sleep(interval); + } +} |