From 1be4440342a9f22258593502f6ecf68ff1bfef8c Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Tue, 10 Oct 2023 17:11:27 -0400 Subject: Parse interval suffixes --- kitd.8 | 28 +++++++++++++++++++++------- kitd.c | 29 +++++++++++++++++++---------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/kitd.8 b/kitd.8 index 9d5b89a..4bce90b 100644 --- a/kitd.8 +++ b/kitd.8 @@ -1,4 +1,4 @@ -.Dd October 8, 2023 +.Dd October 10, 2023 .Dt KITD 8 .Os . @@ -30,11 +30,22 @@ using exponential backoff. The options are as follows: .Bl -tag -width Ds .It Fl c Ar cooloff -The interval in milliseconds -for which the child process must live +The interval for which +the child process must live before the restart interval is reset to its initial value. -The default interval is 15 minutes. +.Pp +The interval may have a suffix of +.Sy s , m , h +or +.Sy d +for seconds, minutes, hours or days, +respectively. +Otherwise, +the interval is in milliseconds. +.Pp +The default cooloff interval is +.Sy 15m . .It Fl d Do not daemonize. Log to standard error @@ -47,12 +58,15 @@ The default is the last path component of .Ar command . .It Fl t Ar restart -The initial interval in milliseconds -between automatic restarts. +The initial interval between automatic restarts. This interval is doubled each time the child process is restarted. -The default interval is 1 second. +.Pp +The interval is interpreted as with +.Fl c . +The default restart interval is +.Sy 1s . .El . .Pp diff --git a/kitd.c b/kitd.c index 2c8ceee..d76cac1 100644 --- a/kitd.c +++ b/kitd.c @@ -62,13 +62,14 @@ static void lbFlush(struct LineBuffer *lb, int priority) { memmove(lb->buf, ptr, lb->len); } +enum { M = 60, H = 60*M, D = 24*H }; + static const char *humanize(const struct timeval *interval) { static char buf[256]; if (!interval->tv_sec) { snprintf(buf, sizeof(buf), "%dms", (int)(interval->tv_usec / 1000)); return buf; } - enum { M = 60, H = 60*M, D = 24*H }; int s = interval->tv_sec; int d = s / D; s %= D; int h = s / H; s %= H; @@ -80,30 +81,38 @@ static const char *humanize(const struct timeval *interval) { return buf; } +static void parse(struct timeval *interval, const char *str) { + char *endptr; + unsigned long n = strtoul(str, &endptr, 10); + timerclear(interval); + switch (*endptr) { + break; case 's': interval->tv_sec = n; + break; case 'm': interval->tv_sec = n*M; + break; case 'h': interval->tv_sec = n*H; + break; case 'd': interval->tv_sec = n*D; + break; case '\0': interval->tv_usec = n * 1000; + break; default: errx(1, "invalid suffix '%c'", *endptr); + } +} + static volatile sig_atomic_t signals[NSIG]; static void signalHandler(int signal) { signals[signal] = 1; } -static void parseInterval(struct timeval *interval, const char *millis) { - unsigned long ms = strtoul(millis, NULL, 10); - interval->tv_sec = ms / 1000; - interval->tv_usec = 1000 * (ms % 1000); -} - int main(int argc, char *argv[]) { int error; bool daemonize = true; const char *name = NULL; struct timeval restart = { .tv_sec = 1 }; - struct timeval cooloff = { .tv_sec = 15 * 60 }; + struct timeval cooloff = { .tv_sec = 15*M }; for (int opt; 0 < (opt = getopt(argc, argv, "c:dn:t:"));) { switch (opt) { - break; case 'c': parseInterval(&cooloff, optarg); + break; case 'c': parse(&cooloff, optarg); break; case 'd': daemonize = false; break; case 'n': name = optarg; - break; case 't': parseInterval(&restart, optarg); + break; case 't': parse(&restart, optarg); break; default: return 1; } } -- cgit 1.4.1