diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-08-03 18:17:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-08-03 18:17:12 +0200 |
commit | 4c20d9f2b0223874e2b5ac1235d5f33fdd02589b (patch) | |
tree | e533a2de1fe3e146bb1dcd410e7c6ff6b68fa0a6 /libbb | |
parent | 9b1c8bf89be668a533505e5fb4405bac6eed651c (diff) | |
download | busybox-4c20d9f2b0223874e2b5ac1235d5f33fdd02589b.tar.gz |
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 <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/duration.c | 76 |
1 files changed, 76 insertions, 0 deletions
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 |