diff options
Diffstat (limited to 'libbb/duration.c')
-rw-r--r-- | libbb/duration.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/libbb/duration.c b/libbb/duration.c new file mode 100644 index 000000000..5acd0dba3 --- /dev/null +++ b/libbb/duration.c | |||
@@ -0,0 +1,78 @@ | |||
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 | //kbuild:lib-$(CONFIG_PING) += duration.o | ||
19 | //kbuild:lib-$(CONFIG_PING6) += duration.o | ||
20 | |||
21 | #include "libbb.h" | ||
22 | |||
23 | static const struct suffix_mult duration_suffixes[] = { | ||
24 | { "s", 1 }, | ||
25 | { "m", 60 }, | ||
26 | { "h", 60*60 }, | ||
27 | { "d", 24*60*60 }, | ||
28 | { "", 0 } | ||
29 | }; | ||
30 | |||
31 | #if ENABLE_FLOAT_DURATION | ||
32 | duration_t FAST_FUNC parse_duration_str(char *str) | ||
33 | { | ||
34 | duration_t duration; | ||
35 | |||
36 | if (strchr(str, '.')) { | ||
37 | double d; | ||
38 | char *pp; | ||
39 | int len = strspn(str, "0123456789."); | ||
40 | char sv = str[len]; | ||
41 | str[len] = '\0'; | ||
42 | errno = 0; | ||
43 | d = strtod(str, &pp); | ||
44 | if (errno || *pp) | ||
45 | bb_show_usage(); | ||
46 | str += len; | ||
47 | *str-- = sv; | ||
48 | sv = *str; | ||
49 | *str = '1'; | ||
50 | duration = d * xatoul_sfx(str, duration_suffixes); | ||
51 | *str = sv; | ||
52 | } else { | ||
53 | duration = xatoul_sfx(str, duration_suffixes); | ||
54 | } | ||
55 | |||
56 | return duration; | ||
57 | } | ||
58 | void FAST_FUNC sleep_for_duration(duration_t duration) | ||
59 | { | ||
60 | struct timespec ts; | ||
61 | |||
62 | ts.tv_sec = MAXINT(typeof(ts.tv_sec)); | ||
63 | ts.tv_nsec = 0; | ||
64 | if (duration >= 0 && duration < ts.tv_sec) { | ||
65 | ts.tv_sec = duration; | ||
66 | ts.tv_nsec = (duration - ts.tv_sec) * 1000000000; | ||
67 | } | ||
68 | do { | ||
69 | errno = 0; | ||
70 | nanosleep(&ts, &ts); | ||
71 | } while (errno == EINTR); | ||
72 | } | ||
73 | #else | ||
74 | duration_t FAST_FUNC parse_duration_str(char *str) | ||
75 | { | ||
76 | return xatou_range_sfx(str, 0, UINT_MAX, duration_suffixes); | ||
77 | } | ||
78 | #endif | ||