Bump to version 1.22.1
[platform/upstream/busybox.git] / coreutils / sleep.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * sleep implementation for busybox
4  *
5  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8  */
9
10 /* BB_AUDIT SUSv3 compliant */
11 /* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */
12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/sleep.html */
13
14 /* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
15  *
16  * Rewritten to do proper arg and error checking.
17  * Also, added a 'fancy' configuration to accept multiple args with
18  * time suffixes for seconds, minutes, hours, and days.
19  */
20
21 //usage:#define sleep_trivial_usage
22 //usage:        IF_FEATURE_FANCY_SLEEP("[") "N" IF_FEATURE_FANCY_SLEEP("]...")
23 //usage:#define sleep_full_usage "\n\n"
24 //usage:        IF_NOT_FEATURE_FANCY_SLEEP("Pause for N seconds")
25 //usage:        IF_FEATURE_FANCY_SLEEP(
26 //usage:       "Pause for a time equal to the total of the args given, where each arg can\n"
27 //usage:       "have an optional suffix of (s)econds, (m)inutes, (h)ours, or (d)ays")
28 //usage:
29 //usage:#define sleep_example_usage
30 //usage:       "$ sleep 2\n"
31 //usage:       "[2 second delay results]\n"
32 //usage:        IF_FEATURE_FANCY_SLEEP(
33 //usage:       "$ sleep 1d 3h 22m 8s\n"
34 //usage:       "[98528 second delay results]\n")
35
36 #include "libbb.h"
37
38 /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells */
39
40
41 #if ENABLE_FEATURE_FANCY_SLEEP || ENABLE_FEATURE_FLOAT_SLEEP
42 static const struct suffix_mult sfx[] = {
43         { "s", 1 },
44         { "m", 60 },
45         { "h", 60*60 },
46         { "d", 24*60*60 },
47         { "", 0 }
48 };
49 #endif
50
51 int sleep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
52 int sleep_main(int argc UNUSED_PARAM, char **argv)
53 {
54 #if ENABLE_FEATURE_FLOAT_SLEEP
55         double duration;
56         struct timespec ts;
57 #else
58         unsigned duration;
59 #endif
60
61         ++argv;
62         if (!*argv)
63                 bb_show_usage();
64
65 #if ENABLE_FEATURE_FLOAT_SLEEP
66
67 # if ENABLE_LOCALE_SUPPORT
68         /* undo busybox.c setlocale */
69         setlocale(LC_NUMERIC, "C");
70 # endif
71         duration = 0;
72         do {
73                 char *arg = *argv;
74                 if (strchr(arg, '.')) {
75                         double d;
76                         char *pp;
77                         int len = strspn(arg, "0123456789.");
78                         char sv = arg[len];
79                         arg[len] = '\0';
80                         errno = 0;
81                         d = strtod(arg, &pp);
82                         if (errno || *pp)
83                                 bb_show_usage();
84                         arg += len;
85                         *arg-- = sv;
86                         sv = *arg;
87                         *arg = '1';
88                         duration += d * xatoul_sfx(arg, sfx);
89                         *arg = sv;
90                 } else {
91                         duration += xatoul_sfx(arg, sfx);
92                 }
93         } while (*++argv);
94
95         ts.tv_sec = MAXINT(typeof(ts.tv_sec));
96         ts.tv_nsec = 0;
97         if (duration >= 0 && duration < ts.tv_sec) {
98                 ts.tv_sec = duration;
99                 ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
100         }
101         do {
102                 errno = 0;
103                 nanosleep(&ts, &ts);
104         } while (errno == EINTR);
105
106 #elif ENABLE_FEATURE_FANCY_SLEEP
107
108         duration = 0;
109         do {
110                 duration += xatou_range_sfx(*argv, 0, UINT_MAX - duration, sfx);
111         } while (*++argv);
112         sleep(duration);
113
114 #else /* simple */
115
116         duration = xatou(*argv);
117         sleep(duration);
118         // Off. If it's really needed, provide example why
119         //if (sleep(duration)) {
120         //      bb_perror_nomsg_and_die();
121         //}
122
123 #endif
124
125         return EXIT_SUCCESS;
126 }