timeout: support sub-second timeouts
[coreutils.git] / src / timeout.c
blob6a37508fd4d01dc43889199bd4f55bacf57f311d
1 /* timeout -- run a command with bounded time
2 Copyright (C) 2008-2011 Free Software Foundation, Inc.
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.
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.
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/>. */
18 /* timeout - Start a command, and kill it if the specified timeout expires
20 We try to behave like a shell starting a single (foreground) job,
21 and will kill the job if we receive the alarm signal we setup.
22 The exit status of the job is returned, or one of these errors:
23 EXIT_TIMEDOUT 124 job timed out
24 EXIT_CANCELED 125 internal error
25 EXIT_CANNOT_INVOKE 126 error executing job
26 EXIT_ENOENT 127 couldn't find job to exec
28 Caveats:
29 If user specifies the KILL (9) signal is to be sent on timeout,
30 the monitor is killed and so exits with 128+9 rather than 124.
32 If you start a command in the background, which reads from the tty
33 and so is immediately sent SIGTTIN to stop, then the timeout
34 process will ignore this so it can timeout the command as expected.
35 This can be seen with `timeout 10 dd&` for example.
36 However if one brings this group to the foreground with the `fg`
37 command before the timer expires, the command will remain
38 in the stop state as the shell doesn't send a SIGCONT
39 because the timeout process (group leader) is already running.
40 To get the command running again one can Ctrl-Z, and do fg again.
41 Note one can Ctrl-C the whole job when in this state.
42 I think this could be fixed but I'm not sure the extra
43 complication is justified for this scenario.
45 Written by Pádraig Brady. */
47 #include <config.h>
48 #include <getopt.h>
49 #include <stdio.h>
50 #include <sys/types.h>
51 #include <signal.h>
52 #include <sys/wait.h>
54 #include "system.h"
55 #include "c-strtod.h"
56 #include "xstrtod.h"
57 #include "sig2str.h"
58 #include "operand2sig.h"
59 #include "error.h"
60 #include "quote.h"
62 #if HAVE_SETRLIMIT
63 /* FreeBSD 5.0 at least needs <sys/types.h> and <sys/time.h> included
64 before <sys/resource.h>. Currently "system.h" includes <sys/time.h>. */
65 # include <sys/resource.h>
66 #endif
68 /* NonStop circa 2011 lacks both SA_RESTART and siginterrupt. */
69 #ifndef SA_RESTART
70 # define SA_RESTART 0
71 #endif
73 #define PROGRAM_NAME "timeout"
75 #define AUTHORS proper_name_utf8 ("Padraig Brady", "P\303\241draig Brady")
77 static int timed_out;
78 static int term_signal = SIGTERM; /* same default as kill command. */
79 static int monitored_pid;
80 static int sigs_to_ignore[NSIG]; /* so monitor can ignore sigs it resends. */
81 static double kill_after;
82 static bool foreground; /* whether to use another program group. */
84 /* for long options with no corresponding short option, use enum */
85 enum
87 FOREGROUND_OPTION = CHAR_MAX + 1
90 static struct option const long_options[] =
92 {"kill-after", required_argument, NULL, 'k'},
93 {"signal", required_argument, NULL, 's'},
94 {"foreground", no_argument, NULL, FOREGROUND_OPTION},
95 {GETOPT_HELP_OPTION_DECL},
96 {GETOPT_VERSION_OPTION_DECL},
97 {NULL, 0, NULL, 0}
100 /* Start the timeout after which we'll receive a SIGALRM.
101 Round DURATION up to the next representable value.
102 Treat out-of-range values as if they were maximal,
103 as that's more useful in practice than reporting an error.
104 '0' means don't timeout. */
105 static void
106 settimeout (double duration)
108 /* timer_settime() provides potentially nanosecond resolution.
109 setitimer() is more portable (to Darwin for example),
110 but only provides microsecond resolution and thus is
111 a little more awkward to use with timespecs, as well as being
112 deprecated by POSIX. Instead we fallback to single second
113 resolution provided by alarm(). */
115 #if HAVE_TIMER_SETTIME
116 struct timespec ts = dtotimespec (duration);
117 struct itimerspec its = { {0, 0}, ts };
118 timer_t timerid;
119 if (timer_create (CLOCK_REALTIME, NULL, &timerid) == 0)
121 if (timer_settime (timerid, 0, &its, NULL) == 0)
122 return;
123 else
125 error (0, errno, _("warning: timer_settime"));
126 timer_delete (timerid);
129 else
130 error (0, errno, _("warning: timer_create"));
131 #endif
133 unsigned int timeint;
134 if (UINT_MAX <= duration)
135 timeint = UINT_MAX;
136 else
138 unsigned int duration_floor = duration;
139 timeint = duration_floor + (duration_floor < duration);
141 alarm (timeint);
144 /* send sig to group but not ourselves.
145 * FIXME: Is there a better way to achieve this? */
146 static int
147 send_sig (int where, int sig)
149 sigs_to_ignore[sig] = 1;
150 return kill (where, sig);
153 static void
154 cleanup (int sig)
156 if (sig == SIGALRM)
158 timed_out = 1;
159 sig = term_signal;
161 if (monitored_pid)
163 if (sigs_to_ignore[sig])
165 sigs_to_ignore[sig] = 0;
166 return;
168 if (kill_after)
170 /* Start a new timeout after which we'll send SIGKILL. */
171 term_signal = SIGKILL;
172 settimeout (kill_after);
173 kill_after = 0; /* Don't let later signals reset kill alarm. */
176 /* Send the signal directly to the monitored child,
177 in case it has itself become group leader,
178 or is not running in a separate group. */
179 send_sig (monitored_pid, sig);
180 /* The normal case is the job has remained in our
181 newly created process group, so send to all processes in that. */
182 if (!foreground)
183 send_sig (0, sig);
184 if (sig != SIGKILL && sig != SIGCONT)
186 send_sig (monitored_pid, SIGCONT);
187 if (!foreground)
188 send_sig (0, SIGCONT);
191 else /* we're the child or the child is not exec'd yet. */
192 _exit (128 + sig);
195 void
196 usage (int status)
198 if (status != EXIT_SUCCESS)
199 fprintf (stderr, _("Try `%s --help' for more information.\n"),
200 program_name);
201 else
203 printf (_("\
204 Usage: %s [OPTION] DURATION COMMAND [ARG]...\n\
205 or: %s [OPTION]\n"), program_name, program_name);
207 fputs (_("\
208 Start COMMAND, and kill it if still running after DURATION.\n\
210 Mandatory arguments to long options are mandatory for short options too.\n\
211 "), stdout);
212 fputs (_("\
213 --foreground\n\
214 When not running timeout directly from a shell prompt,\n\
215 allow COMMAND to read from the TTY and receive TTY signals.\n\
216 In this mode, children of COMMAND will not be timed out.\n\
217 -k, --kill-after=DURATION\n\
218 also send a KILL signal if COMMAND is still running\n\
219 this long after the initial signal was sent.\n\
220 -s, --signal=SIGNAL\n\
221 specify the signal to be sent on timeout.\n\
222 SIGNAL may be a name like `HUP' or a number.\n\
223 See `kill -l` for a list of signals\n"), stdout);
225 fputs (HELP_OPTION_DESCRIPTION, stdout);
226 fputs (VERSION_OPTION_DESCRIPTION, stdout);
228 fputs (_("\n\
229 DURATION is a floating point number with an optional suffix:\n\
230 `s' for seconds (the default), `m' for minutes, `h' for hours \
231 or `d' for days.\n"), stdout);
233 fputs (_("\n\
234 If the command times out, then exit with status 124. Otherwise, exit\n\
235 with the status of COMMAND. If no signal is specified, send the TERM\n\
236 signal upon timeout. The TERM signal kills any process that does not\n\
237 block or catch that signal. For other processes, it may be necessary to\n\
238 use the KILL (9) signal, since this signal cannot be caught.\n"), stdout);
239 emit_ancillary_info ();
241 exit (status);
244 /* Given a floating point value *X, and a suffix character, SUFFIX_CHAR,
245 scale *X by the multiplier implied by SUFFIX_CHAR. SUFFIX_CHAR may
246 be the NUL byte or `s' to denote seconds, `m' for minutes, `h' for
247 hours, or `d' for days. If SUFFIX_CHAR is invalid, don't modify *X
248 and return false. Otherwise return true. */
250 static bool
251 apply_time_suffix (double *x, char suffix_char)
253 int multiplier;
255 switch (suffix_char)
257 case 0:
258 case 's':
259 multiplier = 1;
260 break;
261 case 'm':
262 multiplier = 60;
263 break;
264 case 'h':
265 multiplier = 60 * 60;
266 break;
267 case 'd':
268 multiplier = 60 * 60 * 24;
269 break;
270 default:
271 return false;
274 *x *= multiplier;
276 return true;
279 static double
280 parse_duration (const char* str)
282 double duration;
283 const char *ep;
285 if (!xstrtod (str, &ep, &duration, c_strtod)
286 /* Nonnegative interval. */
287 || ! (0 <= duration)
288 /* No extra chars after the number and an optional s,m,h,d char. */
289 || (*ep && *(ep + 1))
290 /* Check any suffix char and update timeout based on the suffix. */
291 || !apply_time_suffix (&duration, *ep))
293 error (0, 0, _("invalid time interval %s"), quote (str));
294 usage (EXIT_CANCELED);
297 return duration;
300 static void
301 install_signal_handlers (int sigterm)
303 struct sigaction sa;
304 sigemptyset (&sa.sa_mask); /* Allow concurrent calls to handler */
305 sa.sa_handler = cleanup;
306 sa.sa_flags = SA_RESTART; /* Restart syscalls if possible, as that's
307 more likely to work cleanly. */
309 sigaction (SIGALRM, &sa, NULL); /* our timeout. */
310 sigaction (SIGINT, &sa, NULL); /* Ctrl-C at terminal for example. */
311 sigaction (SIGQUIT, &sa, NULL); /* Ctrl-\ at terminal for example. */
312 sigaction (SIGHUP, &sa, NULL); /* terminal closed for example. */
313 sigaction (SIGTERM, &sa, NULL); /* if we're killed, stop monitored proc. */
314 sigaction (sigterm, &sa, NULL); /* user specified termination signal. */
318 main (int argc, char **argv)
320 double timeout;
321 char signame[SIG2STR_MAX];
322 int c;
324 initialize_main (&argc, &argv);
325 set_program_name (argv[0]);
326 setlocale (LC_ALL, "");
327 bindtextdomain (PACKAGE, LOCALEDIR);
328 textdomain (PACKAGE);
330 initialize_exit_failure (EXIT_CANCELED);
331 atexit (close_stdout);
333 while ((c = getopt_long (argc, argv, "+k:s:", long_options, NULL)) != -1)
335 switch (c)
337 case 'k':
338 kill_after = parse_duration (optarg);
339 break;
341 case 's':
342 term_signal = operand2sig (optarg, signame);
343 if (term_signal == -1)
344 usage (EXIT_CANCELED);
345 break;
347 case FOREGROUND_OPTION:
348 foreground = true;
349 break;
351 case_GETOPT_HELP_CHAR;
353 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
355 default:
356 usage (EXIT_CANCELED);
357 break;
361 if (argc - optind < 2)
362 usage (EXIT_CANCELED);
364 timeout = parse_duration (argv[optind++]);
366 argv += optind;
368 /* Ensure we're in our own group so all subprocesses can be killed.
369 Note we don't just put the child in a separate group as
370 then we would need to worry about foreground and background groups
371 and propagating signals between them. */
372 if (!foreground)
373 setpgid (0, 0);
375 /* Setup handlers before fork() so that we
376 handle any signals caused by child, without races. */
377 install_signal_handlers (term_signal);
378 signal (SIGTTIN, SIG_IGN); /* Don't stop if background child needs tty. */
379 signal (SIGTTOU, SIG_IGN); /* Don't stop if background child needs tty. */
380 signal (SIGCHLD, SIG_DFL); /* Don't inherit CHLD handling from parent. */
382 monitored_pid = fork ();
383 if (monitored_pid == -1)
385 error (0, errno, _("fork system call failed"));
386 return EXIT_CANCELED;
388 else if (monitored_pid == 0)
389 { /* child */
390 int exit_status;
392 /* exec doesn't reset SIG_IGN -> SIG_DFL. */
393 signal (SIGTTIN, SIG_DFL);
394 signal (SIGTTOU, SIG_DFL);
396 execvp (argv[0], argv); /* FIXME: should we use "sh -c" ... here? */
398 /* exit like sh, env, nohup, ... */
399 exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
400 error (0, errno, _("failed to run command %s"), quote (argv[0]));
401 return exit_status;
403 else
405 pid_t wait_result;
406 int status;
408 settimeout (timeout);
410 while ((wait_result = waitpid (monitored_pid, &status, 0)) < 0
411 && errno == EINTR)
412 continue;
414 if (wait_result < 0)
416 /* shouldn't happen. */
417 error (0, errno, _("error waiting for command"));
418 status = EXIT_CANCELED;
420 else
422 if (WIFEXITED (status))
423 status = WEXITSTATUS (status);
424 else if (WIFSIGNALED (status))
426 int sig = WTERMSIG (status);
427 #if HAVE_SETRLIMIT && defined RLIMIT_CORE
428 if (!timed_out)
430 /* exit with the signal flag set, but avoid core files. */
431 if (setrlimit (RLIMIT_CORE, &(struct rlimit) {0,0}) == 0)
433 signal (sig, SIG_DFL);
434 raise (sig);
436 else
437 error (0, errno, _("warning: disabling core dumps failed"));
439 #endif
440 status = sig + 128; /* what sh returns for signaled processes. */
442 else
444 /* shouldn't happen. */
445 error (0, 0, _("unknown status from command (0x%X)"), status);
446 status = EXIT_FAILURE;
450 if (timed_out)
451 return EXIT_TIMEDOUT;
452 else
453 return status;