timeout: add --foreground to support interactive commands
[platform/upstream/coreutils.git] / src / timeout.c
1 /* timeout -- run a command with bounded time
2    Copyright (C) 2008-2011 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
18 /* timeout - Start a command, and kill it if the specified timeout expires
19
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
27
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.
31
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.
44
45    Written by Pádraig Brady.  */
46
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>
53
54 #include "system.h"
55 #include "xstrtol.h"
56 #include "sig2str.h"
57 #include "operand2sig.h"
58 #include "error.h"
59 #include "quote.h"
60
61 #define PROGRAM_NAME "timeout"
62
63 #define AUTHORS proper_name_utf8 ("Padraig Brady", "P\303\241draig Brady")
64
65 static int timed_out;
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.  */
71
72 /* for long options with no corresponding short option, use enum */
73 enum
74 {
75       FOREGROUND_OPTION = CHAR_MAX + 1
76 };
77
78 static struct option const long_options[] =
79 {
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},
85   {NULL, 0, NULL, 0}
86 };
87
88 /* send sig to group but not ourselves.
89  * FIXME: Is there a better way to achieve this?  */
90 static int
91 send_sig (int where, int sig)
92 {
93   sigs_to_ignore[sig] = 1;
94   return kill (where, sig);
95 }
96
97 static void
98 cleanup (int sig)
99 {
100   if (sig == SIGALRM)
101     {
102       timed_out = 1;
103       sig = term_signal;
104     }
105   if (monitored_pid)
106     {
107       int where = foreground ? monitored_pid : 0;
108
109       if (sigs_to_ignore[sig])
110         {
111           sigs_to_ignore[sig] = 0;
112           return;
113         }
114       if (kill_after)
115         {
116           /* Start a new timeout after which we'll send SIGKILL.  */
117           term_signal = SIGKILL;
118           alarm (kill_after);
119           kill_after = 0; /* Don't let later signals reset kill alarm.  */
120         }
121
122       send_sig (where, sig);
123       if (sig != SIGKILL && sig != SIGCONT)
124         send_sig (where, SIGCONT);
125     }
126   else /* we're the child or the child is not exec'd yet.  */
127     _exit (128 + sig);
128 }
129
130 void
131 usage (int status)
132 {
133   if (status != EXIT_SUCCESS)
134     fprintf (stderr, _("Try `%s --help' for more information.\n"),
135              program_name);
136   else
137     {
138       printf (_("\
139 Usage: %s [OPTION] DURATION COMMAND [ARG]...\n\
140   or:  %s [OPTION]\n"), program_name, program_name);
141
142       fputs (_("\
143 Start COMMAND, and kill it if still running after DURATION.\n\
144 \n\
145 Mandatory arguments to long options are mandatory for short options too.\n\
146 "), stdout);
147       fputs (_("\
148       --foreground\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);
159
160       fputs (HELP_OPTION_DESCRIPTION, stdout);
161       fputs (VERSION_OPTION_DESCRIPTION, stdout);
162
163       fputs (_("\n\
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);
167
168       fputs (_("\n\
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 ();
175     }
176   exit (status);
177 }
178
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.  */
185
186 static bool
187 apply_time_suffix (unsigned long *x, char suffix_char)
188 {
189   unsigned int multiplier = 1;
190
191   switch (suffix_char)
192     {
193     case 0:
194     case 's':
195       return true;
196     case 'd':
197       multiplier *= 24;
198     case 'h':
199       multiplier *= 60;
200     case 'm':
201       if (multiplier > UINT_MAX / 60) /* 16 bit overflow */
202         return false;
203       multiplier *= 60;
204       break;
205     default:
206       return false;
207     }
208
209   if (*x > UINT_MAX / multiplier)
210     return false;
211
212   *x *= multiplier;
213
214   return true;
215 }
216
217 static unsigned long
218 parse_duration (const char* str)
219 {
220   unsigned long duration;
221   char *ep;
222
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))
230     {
231       error (0, 0, _("invalid time interval %s"), quote (str));
232       usage (EXIT_CANCELED);
233     }
234
235   return duration;
236 }
237
238 static void
239 install_signal_handlers (int sigterm)
240 {
241   struct sigaction sa;
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) */
245
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.  */
252 }
253
254 int
255 main (int argc, char **argv)
256 {
257   unsigned long timeout;
258   char signame[SIG2STR_MAX];
259   int c;
260
261   initialize_main (&argc, &argv);
262   set_program_name (argv[0]);
263   setlocale (LC_ALL, "");
264   bindtextdomain (PACKAGE, LOCALEDIR);
265   textdomain (PACKAGE);
266
267   initialize_exit_failure (EXIT_CANCELED);
268   atexit (close_stdout);
269
270   while ((c = getopt_long (argc, argv, "+k:s:", long_options, NULL)) != -1)
271     {
272       switch (c)
273         {
274         case 'k':
275           kill_after = parse_duration (optarg);
276           break;
277
278         case 's':
279           term_signal = operand2sig (optarg, signame);
280           if (term_signal == -1)
281             usage (EXIT_CANCELED);
282           break;
283
284         case FOREGROUND_OPTION:
285           foreground = true;
286           break;
287
288         case_GETOPT_HELP_CHAR;
289
290         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
291
292         default:
293           usage (EXIT_CANCELED);
294           break;
295         }
296     }
297
298   if (argc - optind < 2)
299     usage (EXIT_CANCELED);
300
301   timeout = parse_duration (argv[optind++]);
302
303   argv += optind;
304
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.  */
309   if (!foreground)
310     setpgid (0, 0);
311
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.   */
318
319   monitored_pid = fork ();
320   if (monitored_pid == -1)
321     {
322       error (0, errno, _("fork system call failed"));
323       return EXIT_CANCELED;
324     }
325   else if (monitored_pid == 0)
326     {                           /* child */
327       int exit_status;
328
329       /* exec doesn't reset SIG_IGN -> SIG_DFL.  */
330       signal (SIGTTIN, SIG_DFL);
331       signal (SIGTTOU, SIG_DFL);
332
333       execvp (argv[0], argv);   /* FIXME: should we use "sh -c" ... here?  */
334
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]));
338       return exit_status;
339     }
340   else
341     {
342       int status;
343
344       alarm (timeout);
345
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)
354         {
355           /* shouldn't happen.  */
356           error (0, errno, _("error waiting for command"));
357           status = EXIT_CANCELED;
358         }
359       else
360         {
361           if (WIFEXITED (status))
362             status = WEXITSTATUS (status);
363           else if (WIFSIGNALED (status))
364             status = WTERMSIG (status) + 128; /* what sh does at least.  */
365           else
366             {
367               /* shouldn't happen.  */
368               error (0, 0, _("unknown status from command (0x%X)"), status);
369               status = EXIT_FAILURE;
370             }
371         }
372
373       if (timed_out)
374         return EXIT_TIMEDOUT;
375       else
376         return status;
377     }
378 }