aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
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 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright (C) 2018 Denys Vlasenko
6 *
7 * Licensed under GPLv2, see file LICENSE in this source tree.
8 */
9//config:config FLOAT_DURATION
10//config: bool "Enable fractional duration arguments"
11//config: default y
12//config: help
13//config: Allow sleep N.NNN, top -d N.NNN etc.
14
15//kbuild:lib-$(CONFIG_SLEEP) += duration.o
16//kbuild:lib-$(CONFIG_TOP) += duration.o
17//kbuild:lib-$(CONFIG_TIMEOUT) += duration.o
18
19#include "libbb.h"
20
21static const struct suffix_mult duration_suffixes[] = {
22 { "s", 1 },
23 { "m", 60 },
24 { "h", 60*60 },
25 { "d", 24*60*60 },
26 { "", 0 }
27};
28
29#if ENABLE_FLOAT_DURATION
30duration_t FAST_FUNC parse_duration_str(char *str)
31{
32 duration_t duration;
33
34 if (strchr(str, '.')) {
35 double d;
36 char *pp;
37 int len = strspn(str, "0123456789.");
38 char sv = str[len];
39 str[len] = '\0';
40 errno = 0;
41 d = strtod(str, &pp);
42 if (errno || *pp)
43 bb_show_usage();
44 str += len;
45 *str-- = sv;
46 sv = *str;
47 *str = '1';
48 duration = d * xatoul_sfx(str, duration_suffixes);
49 *str = sv;
50 } else {
51 duration = xatoul_sfx(str, duration_suffixes);
52 }
53
54 return duration;
55}
56void FAST_FUNC sleep_for_duration(duration_t duration)
57{
58 struct timespec ts;
59
60 ts.tv_sec = MAXINT(typeof(ts.tv_sec));
61 ts.tv_nsec = 0;
62 if (duration >= 0 && duration < ts.tv_sec) {
63 ts.tv_sec = duration;
64 ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
65 }
66 do {
67 errno = 0;
68 nanosleep(&ts, &ts);
69 } while (errno == EINTR);
70}
71#else
72duration_t FAST_FUNC parse_duration_str(char *str)
73{
74 return xatou_range_sfx(*argv, 0, UINT_MAX, duration_suffixes);
75}
76#endif