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
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. */
50 #include <sys/types.h>
57 #include "operand2sig.h"
61 #define PROGRAM_NAME "timeout"
63 #define AUTHORS proper_name_utf8 ("Padraig Brady", "P\303\241draig Brady")
66 static int term_signal = SIGTERM; /* same default as kill command. */
67 static int monitored_pid;
68 static int sigs_to_ignore[NSIG]; /* so monitor can ignore sigs it resends. */
69 static unsigned long kill_after;
70 static bool foreground; /* whether to use another program group. */
72 /* for long options with no corresponding short option, use enum */
75 FOREGROUND_OPTION = CHAR_MAX + 1
78 static struct option const long_options[] =
80 {"kill-after", required_argument, NULL, 'k'},
81 {"signal", required_argument, NULL, 's'},
82 {"foreground", no_argument, NULL, FOREGROUND_OPTION},
83 {GETOPT_HELP_OPTION_DECL},
84 {GETOPT_VERSION_OPTION_DECL},
88 /* send sig to group but not ourselves.
89 * FIXME: Is there a better way to achieve this? */
91 send_sig (int where, int sig)
93 sigs_to_ignore[sig] = 1;
94 return kill (where, sig);
107 int where = foreground ? monitored_pid : 0;
109 if (sigs_to_ignore[sig])
111 sigs_to_ignore[sig] = 0;
116 /* Start a new timeout after which we'll send SIGKILL. */
117 term_signal = SIGKILL;
119 kill_after = 0; /* Don't let later signals reset kill alarm. */
122 send_sig (where, sig);
123 if (sig != SIGKILL && sig != SIGCONT)
124 send_sig (where, SIGCONT);
126 else /* we're the child or the child is not exec'd yet. */
133 if (status != EXIT_SUCCESS)
134 fprintf (stderr, _("Try `%s --help' for more information.\n"),
139 Usage: %s [OPTION] DURATION COMMAND [ARG]...\n\
140 or: %s [OPTION]\n"), program_name, program_name);
143 Start COMMAND, and kill it if still running after DURATION.\n\
145 Mandatory arguments to long options are mandatory for short options too.\n\
149 When not running timeout directly from a shell prompt,\n\
150 allow COMMAND to read from the TTY and receive TTY signals.\n\
151 In this mode, children of COMMAND will not be timed out.\n\
152 -k, --kill-after=DURATION\n\
153 also send a KILL signal if COMMAND is still running\n\
154 this long after the initial signal was sent.\n\
155 -s, --signal=SIGNAL\n\
156 specify the signal to be sent on timeout.\n\
157 SIGNAL may be a name like `HUP' or a number.\n\
158 See `kill -l` for a list of signals\n"), stdout);
160 fputs (HELP_OPTION_DESCRIPTION, stdout);
161 fputs (VERSION_OPTION_DESCRIPTION, stdout);
164 DURATION is an integer with an optional suffix:\n\
165 `s' for seconds (the default), `m' for minutes, `h' for hours \
166 or `d' for days.\n"), stdout);
169 If the command times out, then exit with status 124. Otherwise, exit\n\
170 with the status of COMMAND. If no signal is specified, send the TERM\n\
171 signal upon timeout. The TERM signal kills any process that does not\n\
172 block or catch that signal. For other processes, it may be necessary to\n\
173 use the KILL (9) signal, since this signal cannot be caught.\n"), stdout);
174 emit_ancillary_info ();
179 /* Given a long integer value *X, and a suffix character, SUFFIX_CHAR,
180 scale *X by the multiplier implied by SUFFIX_CHAR. SUFFIX_CHAR may
181 be the NUL byte or `s' to denote seconds, `m' for minutes, `h' for
182 hours, or `d' for days. If SUFFIX_CHAR is invalid, don't modify *X
183 and return false. If *X would overflow an integer, don't modify *X
184 and return false. Otherwise return true. */
187 apply_time_suffix (unsigned long *x, char suffix_char)
189 unsigned int multiplier = 1;
201 if (multiplier > UINT_MAX / 60) /* 16 bit overflow */
209 if (*x > UINT_MAX / multiplier)
218 parse_duration (const char* str)
220 unsigned long duration;
223 if (xstrtoul (str, &ep, 10, &duration, NULL)
224 /* Invalid interval. Note 0 disables timeout */
225 || (duration > UINT_MAX)
226 /* Extra chars after the number and an optional s,m,h,d char. */
227 || (*ep && *(ep + 1))
228 /* Check any suffix char and update timeout based on the suffix. */
229 || !apply_time_suffix (&duration, *ep))
231 error (0, 0, _("invalid time interval %s"), quote (str));
232 usage (EXIT_CANCELED);
239 install_signal_handlers (int sigterm)
242 sigemptyset (&sa.sa_mask); /* Allow concurrent calls to handler */
243 sa.sa_handler = cleanup;
244 sa.sa_flags = SA_RESTART; /* restart syscalls (like wait() below) */
246 sigaction (SIGALRM, &sa, NULL); /* our timeout. */
247 sigaction (SIGINT, &sa, NULL); /* Ctrl-C at terminal for example. */
248 sigaction (SIGQUIT, &sa, NULL); /* Ctrl-\ at terminal for example. */
249 sigaction (SIGHUP, &sa, NULL); /* terminal closed for example. */
250 sigaction (SIGTERM, &sa, NULL); /* if we're killed, stop monitored proc. */
251 sigaction (sigterm, &sa, NULL); /* user specified termination signal. */
255 main (int argc, char **argv)
257 unsigned long timeout;
258 char signame[SIG2STR_MAX];
261 initialize_main (&argc, &argv);
262 set_program_name (argv[0]);
263 setlocale (LC_ALL, "");
264 bindtextdomain (PACKAGE, LOCALEDIR);
265 textdomain (PACKAGE);
267 initialize_exit_failure (EXIT_CANCELED);
268 atexit (close_stdout);
270 while ((c = getopt_long (argc, argv, "+k:s:", long_options, NULL)) != -1)
275 kill_after = parse_duration (optarg);
279 term_signal = operand2sig (optarg, signame);
280 if (term_signal == -1)
281 usage (EXIT_CANCELED);
284 case FOREGROUND_OPTION:
288 case_GETOPT_HELP_CHAR;
290 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
293 usage (EXIT_CANCELED);
298 if (argc - optind < 2)
299 usage (EXIT_CANCELED);
301 timeout = parse_duration (argv[optind++]);
305 /* Ensure we're in our own group so all subprocesses can be killed.
306 Note we don't just put the child in a separate group as
307 then we would need to worry about foreground and background groups
308 and propagating signals between them. */
312 /* Setup handlers before fork() so that we
313 handle any signals caused by child, without races. */
314 install_signal_handlers (term_signal);
315 signal (SIGTTIN, SIG_IGN); /* don't sTop if background child needs tty. */
316 signal (SIGTTOU, SIG_IGN); /* don't sTop if background child needs tty. */
317 signal (SIGCHLD, SIG_DFL); /* Don't inherit CHLD handling from parent. */
319 monitored_pid = fork ();
320 if (monitored_pid == -1)
322 error (0, errno, _("fork system call failed"));
323 return EXIT_CANCELED;
325 else if (monitored_pid == 0)
329 /* exec doesn't reset SIG_IGN -> SIG_DFL. */
330 signal (SIGTTIN, SIG_DFL);
331 signal (SIGTTOU, SIG_DFL);
333 execvp (argv[0], argv); /* FIXME: should we use "sh -c" ... here? */
335 /* exit like sh, env, nohup, ... */
336 exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
337 error (0, errno, _("failed to run command %s"), quote (argv[0]));
346 /* We're just waiting for a single process here, so wait() suffices.
347 Note the signal() calls above on GNU/Linux and BSD at least,
348 essentially call the lower level sigaction() with the SA_RESTART flag
349 set, which ensures the following wait call will only return if the
350 child exits, not on this process receiving a signal. Also we're not
351 passing WUNTRACED | WCONTINUED to a waitpid() call and so will not get
352 indication that the child has stopped or continued. */
353 if (wait (&status) == -1)
355 /* shouldn't happen. */
356 error (0, errno, _("error waiting for command"));
357 status = EXIT_CANCELED;
361 if (WIFEXITED (status))
362 status = WEXITSTATUS (status);
363 else if (WIFSIGNALED (status))
364 status = WTERMSIG (status) + 128; /* what sh does at least. */
367 /* shouldn't happen. */
368 error (0, 0, _("unknown status from command (0x%X)"), status);
369 status = EXIT_FAILURE;
374 return EXIT_TIMEDOUT;