ash: move hashvar() calls into findvar()
[busybox-git.git] / libbb / duration.c
blob0024f1a660a0aeeb3c49779a1a21d8d6c88aecd1
1 /* vi: set sw=4 ts=4: */
2 /*
3 * Utility routines.
5 * Copyright (C) 2018 Denys Vlasenko
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.
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 //kbuild:lib-$(CONFIG_WATCH) += duration.o
22 #include "libbb.h"
24 static const struct suffix_mult duration_suffixes[] ALIGN_SUFFIX = {
25 { "s", 1 },
26 { "m", 60 },
27 { "h", 60*60 },
28 { "d", 24*60*60 },
29 { "", 0 }
32 #if ENABLE_FLOAT_DURATION
33 duration_t FAST_FUNC parse_duration_str(char *str)
35 duration_t duration;
37 if (strchr(str, '.')) {
38 double d;
39 char *pp;
40 int len;
41 char sv;
43 # if ENABLE_LOCALE_SUPPORT
44 /* Undo busybox.c: on input, we want to use dot
45 * as fractional separator in strtod(),
46 * regardless of current locale
48 setlocale(LC_NUMERIC, "C");
49 # endif
50 len = strspn(str, "0123456789.");
51 sv = str[len];
52 str[len] = '\0';
53 errno = 0;
54 d = strtod(str, &pp);
55 if (errno || *pp)
56 bb_show_usage();
57 str += len;
58 *str-- = sv;
59 sv = *str;
60 *str = '1';
61 duration = d * xatoul_sfx(str, duration_suffixes);
62 *str = sv;
63 } else {
64 duration = xatoul_sfx(str, duration_suffixes);
67 return duration;
69 void FAST_FUNC sleep_for_duration(duration_t duration)
71 struct timespec ts;
73 ts.tv_sec = MAXINT(typeof(ts.tv_sec));
74 ts.tv_nsec = 0;
75 if (duration >= 0 && duration < ts.tv_sec) {
76 ts.tv_sec = duration;
77 ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
79 /* NB: ENABLE_ASH_SLEEP requires that we do NOT loop on EINTR here:
80 * otherwise, traps won't execute until we finish looping.
82 //do {
83 // errno = 0;
84 // nanosleep(&ts, &ts);
85 //} while (errno == EINTR);
86 nanosleep(&ts, &ts);
88 #else
89 duration_t FAST_FUNC parse_duration_str(char *str)
91 return xatou_range_sfx(str, 0, UINT_MAX, duration_suffixes);
93 #endif