aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-08-03 18:17:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-08-03 18:17:12 +0200
commit4c20d9f2b0223874e2b5ac1235d5f33fdd02589b (patch)
treee533a2de1fe3e146bb1dcd410e7c6ff6b68fa0a6 /libbb
parent9b1c8bf89be668a533505e5fb4405bac6eed651c (diff)
downloadbusybox-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.c76
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