diff options
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 |