timeout: fix arguments to match coreutils
[oweals/busybox.git] / libbb / duration.c
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