Line data Source code
1 : /* sleep - delay for a specified amount of time.
2 : Copyright (C) 84, 1991-1997, 1999-2005, 2007 Free Software Foundation, Inc.
3 :
4 : This program is free software: you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation, either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : This program is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 :
17 : #include <config.h>
18 : #include <stdio.h>
19 : #include <sys/types.h>
20 : #include <getopt.h>
21 :
22 : #include "system.h"
23 : #include "c-strtod.h"
24 : #include "error.h"
25 : #include "long-options.h"
26 : #include "quote.h"
27 : #include "xnanosleep.h"
28 : #include "xstrtod.h"
29 :
30 : /* The official name of this program (e.g., no `g' prefix). */
31 : #define PROGRAM_NAME "sleep"
32 :
33 : #define AUTHORS "Jim Meyering", "Paul Eggert"
34 :
35 : /* The name by which this program was run. */
36 : char *program_name;
37 :
38 : void
39 32 : usage (int status)
40 : {
41 32 : if (status != EXIT_SUCCESS)
42 30 : fprintf (stderr, _("Try `%s --help' for more information.\n"),
43 : program_name);
44 : else
45 : {
46 2 : printf (_("\
47 : Usage: %s NUMBER[SUFFIX]...\n\
48 : or: %s OPTION\n\
49 : Pause for NUMBER seconds. SUFFIX may be `s' for seconds (the default),\n\
50 : `m' for minutes, `h' for hours or `d' for days. Unlike most implementations\n\
51 : that require NUMBER be an integer, here NUMBER may be an arbitrary floating\n\
52 : point number. Given two or more arguments, pause for the amount of time\n\
53 : specified by the sum of their values.\n\
54 : \n\
55 : "),
56 : program_name, program_name);
57 2 : fputs (HELP_OPTION_DESCRIPTION, stdout);
58 2 : fputs (VERSION_OPTION_DESCRIPTION, stdout);
59 2 : emit_bug_reporting_address ();
60 : }
61 32 : exit (status);
62 : }
63 :
64 : /* Given a floating point value *X, and a suffix character, SUFFIX_CHAR,
65 : scale *X by the multiplier implied by SUFFIX_CHAR. SUFFIX_CHAR may
66 : be the NUL byte or `s' to denote seconds, `m' for minutes, `h' for
67 : hours, or `d' for days. If SUFFIX_CHAR is invalid, don't modify *X
68 : and return false. Otherwise return true. */
69 :
70 : static bool
71 0 : apply_suffix (double *x, char suffix_char)
72 : {
73 : int multiplier;
74 :
75 0 : switch (suffix_char)
76 : {
77 0 : case 0:
78 : case 's':
79 0 : multiplier = 1;
80 0 : break;
81 0 : case 'm':
82 0 : multiplier = 60;
83 0 : break;
84 0 : case 'h':
85 0 : multiplier = 60 * 60;
86 0 : break;
87 0 : case 'd':
88 0 : multiplier = 60 * 60 * 24;
89 0 : break;
90 0 : default:
91 0 : return false;
92 : }
93 :
94 0 : *x *= multiplier;
95 :
96 0 : return true;
97 : }
98 :
99 : int
100 34 : main (int argc, char **argv)
101 : {
102 : int i;
103 34 : double seconds = 0.0;
104 34 : bool ok = true;
105 :
106 : initialize_main (&argc, &argv);
107 34 : program_name = argv[0];
108 34 : setlocale (LC_ALL, "");
109 : bindtextdomain (PACKAGE, LOCALEDIR);
110 : textdomain (PACKAGE);
111 :
112 34 : atexit (close_stdout);
113 :
114 34 : parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
115 : usage, AUTHORS, (char const *) NULL);
116 31 : if (getopt_long (argc, argv, "", NULL, NULL) != -1)
117 6 : usage (EXIT_FAILURE);
118 :
119 25 : if (argc == 1)
120 : {
121 1 : error (0, 0, _("missing operand"));
122 1 : usage (EXIT_FAILURE);
123 : }
124 :
125 61 : for (i = optind; i < argc; i++)
126 : {
127 : double s;
128 : const char *p;
129 37 : if (! xstrtod (argv[i], &p, &s, c_strtod)
130 : /* Nonnegative interval. */
131 0 : || ! (0 <= s)
132 : /* No extra chars after the number and an optional s,m,h,d char. */
133 0 : || (*p && *(p+1))
134 : /* Check any suffix char and update S based on the suffix. */
135 0 : || ! apply_suffix (&s, *p))
136 : {
137 37 : error (0, 0, _("invalid time interval %s"), quote (argv[i]));
138 37 : ok = false;
139 : }
140 :
141 37 : seconds += s;
142 : }
143 :
144 24 : if (!ok)
145 23 : usage (EXIT_FAILURE);
146 :
147 1 : if (xnanosleep (seconds))
148 0 : error (EXIT_FAILURE, errno, _("cannot read realtime clock"));
149 :
150 1 : exit (EXIT_SUCCESS);
151 : }
|