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 @@ | |||
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 | |||
21 | static 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 | ||
30 | duration_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 | } | ||
56 | void 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 | ||
72 | duration_t FAST_FUNC parse_duration_str(char *str) | ||
73 | { | ||
74 | return xatou_range_sfx(*argv, 0, UINT_MAX, duration_suffixes); | ||
75 | } | ||
76 | #endif | ||