From 4c20d9f2b0223874e2b5ac1235d5f33fdd02589b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 3 Aug 2018 18:17:12 +0200 Subject: extend fractional duration support to "top -d N.N" and "timeout" function old new delta parse_duration_str - 168 +168 sleep_for_duration - 157 +157 top_main 885 928 +43 timeout_main 269 312 +43 handle_input 571 614 +43 duration_suffixes - 40 +40 sfx 40 - -40 sleep_main 364 79 -285 ------------------------------------------------------------------------------ (add/remove: 4/1 grow/shrink: 3/1 up/down: 494/-325) Total: 169 bytes Signed-off-by: Denys Vlasenko --- libbb/duration.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 libbb/duration.c (limited to 'libbb/duration.c') diff --git a/libbb/duration.c b/libbb/duration.c new file mode 100644 index 000000000..765a1e9fe --- /dev/null +++ b/libbb/duration.c @@ -0,0 +1,76 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2018 Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config FLOAT_DURATION +//config: bool "Enable fractional duration arguments" +//config: default y +//config: help +//config: Allow sleep N.NNN, top -d N.NNN etc. + +//kbuild:lib-$(CONFIG_SLEEP) += duration.o +//kbuild:lib-$(CONFIG_TOP) += duration.o +//kbuild:lib-$(CONFIG_TIMEOUT) += duration.o + +#include "libbb.h" + +static const struct suffix_mult duration_suffixes[] = { + { "s", 1 }, + { "m", 60 }, + { "h", 60*60 }, + { "d", 24*60*60 }, + { "", 0 } +}; + +#if ENABLE_FLOAT_DURATION +duration_t FAST_FUNC parse_duration_str(char *str) +{ + duration_t duration; + + if (strchr(str, '.')) { + double d; + char *pp; + int len = strspn(str, "0123456789."); + char sv = str[len]; + str[len] = '\0'; + errno = 0; + d = strtod(str, &pp); + if (errno || *pp) + bb_show_usage(); + str += len; + *str-- = sv; + sv = *str; + *str = '1'; + duration = d * xatoul_sfx(str, duration_suffixes); + *str = sv; + } else { + duration = xatoul_sfx(str, duration_suffixes); + } + + return duration; +} +void FAST_FUNC sleep_for_duration(duration_t duration) +{ + struct timespec ts; + + ts.tv_sec = MAXINT(typeof(ts.tv_sec)); + ts.tv_nsec = 0; + if (duration >= 0 && duration < ts.tv_sec) { + ts.tv_sec = duration; + ts.tv_nsec = (duration - ts.tv_sec) * 1000000000; + } + do { + errno = 0; + nanosleep(&ts, &ts); + } while (errno == EINTR); +} +#else +duration_t FAST_FUNC parse_duration_str(char *str) +{ + return xatou_range_sfx(*argv, 0, UINT_MAX, duration_suffixes); +} +#endif -- cgit v1.2.3