/* Copyright (C) 2021 June 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 * 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 . */ #include #include #include #include #include #include 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); } }