diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | cmd/Makemodule.am | 7 | ||||
-rw-r--r-- | cmd/waitfile.c | 82 |
3 files changed, 89 insertions, 1 deletions
@@ -21,5 +21,6 @@ shutdown killall5 runsvc gcrond +waitfile etc/initd.env diff --git a/cmd/Makemodule.am b/cmd/Makemodule.am index e472106..203a840 100644 --- a/cmd/Makemodule.am +++ b/cmd/Makemodule.am @@ -14,6 +14,11 @@ killall5_CPPFLAGS = $(AM_CPPFLAGS) killall5_CFLAGS = $(AM_CFLAGS) killall5_LDFLAGS = $(AM_LDFLAGS) +waitfile_SOURCES = cmd/waitfile.c +waitfile_CPPFLAGS = $(AM_CPPFLAGS) +waitfile_CFLAGS = $(AM_CFLAGS) +waitfile_LDFLAGS = $(AM_LDFLAGS) + SRVHEADERS = cmd/service/servicecmd.h service_SOURCES = cmd/service/servicecmd.c cmd/service/help.c @@ -31,4 +36,4 @@ dist_man8_MANS += cmd/shutdown.8 cmd/service/service.8 EXTRA_DIST += $(SRVHEADERS) sbin_PROGRAMS += service shutdown -helper_PROGRAMS += killall5 runsvc +helper_PROGRAMS += killall5 runsvc waitfile diff --git a/cmd/waitfile.c b/cmd/waitfile.c new file mode 100644 index 0000000..e994fd1 --- /dev/null +++ b/cmd/waitfile.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: ISC */ +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <limits.h> +#include <unistd.h> +#include <signal.h> +#include <stdio.h> +#include <ctype.h> +#include <poll.h> + +static int strtoui(const char *str) +{ + int i = 0; + + if (!isdigit(*str)) + return -1; + + while (isdigit(*str)) { + if (i > (INT_MAX / 10)) + return -1; + + i = i * 10 + (*(str++)) - '0'; + } + + if (*str != '\0') + return -1; + + return i; +} + +static void sigproc(int signo) +{ + if (signo == SIGALRM) { + fputs("waitfile timeout\n", stderr); + exit(EXIT_FAILURE); + } +} + +int main(int argc, char **argv) +{ + int i, found, timeout, probetime; + struct stat sb; + + if (argc < 4) + goto fail_usage; + + timeout = strtoui(argv[1]); + probetime = strtoui(argv[2]); + if (timeout < 0 || probetime < 0) + goto fail_timeout; + + signal(SIGALRM, sigproc); + alarm(timeout); + + for (;;) { + found = 1; + + for (i = 3; i < argc; ++i) { + if (stat(argv[i], &sb) != 0) { + found = 0; + break; + } + } + + if (found) { + alarm(0); + break; + } + + poll(NULL, 0, probetime); + } + + return EXIT_SUCCESS; +fail_timeout: + fputs("Timeout values must be integers!\n", stderr); + goto fail_usage; +fail_usage: + fputs("Usage: waitfile <timeout secs> <probe time ms> FILES...\n", + stderr); + return EXIT_FAILURE; +} |