summaryrefslogtreecommitdiff
path: root/src/timeout.c
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2011-07-06 23:17:10 +0100
committerPádraig Brady <P@draigBrady.com>2011-07-08 11:23:08 +0100
commit4496c94091f8a6bc95fc1c0868eba632fae99ba3 (patch)
tree44e2b1a618a781abeb02a639387efcf6320abbed /src/timeout.c
parent28a7fb52bc1160ffe1acac2e4fc3fa495d021ec4 (diff)
downloadcoreutils-4496c94091f8a6bc95fc1c0868eba632fae99ba3.tar.xz
timeout: add --foreground to support interactive commands
Or more accurately, commands not started from the shell prompt, that are interactive, or need to receive Ctrl-C etc. from the terminal. * doc/coreutils.texi (timeout invocation): Document --foreground. * src/timeout.c (main): Set the foreground flag and don't create a separate group. (cleanup): Only send a signal directly to the monitored command when the foreground flag is set. (usage): Describe --foreground. * tests/misc/timeout-group: Add a new test. * tests/Makefile.am: Reference new test. NEWS: Mention the new option. Reported by Shay Shimony Analysis by Alan Curry Fix suggested by Paul Eggert
Diffstat (limited to 'src/timeout.c')
-rw-r--r--src/timeout.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/timeout.c b/src/timeout.c
index a6862253d..8f0980b96 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -67,11 +67,19 @@ static int term_signal = SIGTERM; /* same default as kill command. */
static int monitored_pid;
static int sigs_to_ignore[NSIG]; /* so monitor can ignore sigs it resends. */
static unsigned long kill_after;
+static bool foreground; /* whether to use another program group. */
+
+/* for long options with no corresponding short option, use enum */
+enum
+{
+ FOREGROUND_OPTION = CHAR_MAX + 1
+};
static struct option const long_options[] =
{
{"kill-after", required_argument, NULL, 'k'},
{"signal", required_argument, NULL, 's'},
+ {"foreground", no_argument, NULL, FOREGROUND_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -96,6 +104,8 @@ cleanup (int sig)
}
if (monitored_pid)
{
+ int where = foreground ? monitored_pid : 0;
+
if (sigs_to_ignore[sig])
{
sigs_to_ignore[sig] = 0;
@@ -108,9 +118,10 @@ cleanup (int sig)
alarm (kill_after);
kill_after = 0; /* Don't let later signals reset kill alarm. */
}
- send_sig (0, sig);
+
+ send_sig (where, sig);
if (sig != SIGKILL && sig != SIGCONT)
- send_sig (0, SIGCONT);
+ send_sig (where, SIGCONT);
}
else /* we're the child or the child is not exec'd yet. */
_exit (128 + sig);
@@ -134,13 +145,17 @@ Start COMMAND, and kill it if still running after DURATION.\n\
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
+ --foreground\n\
+ When not running timeout directly from a shell prompt,\n\
+ allow COMMAND to read from the TTY and receive TTY signals.\n\
+ In this mode, children of COMMAND will not be timed out.\n\
-k, --kill-after=DURATION\n\
- also send a KILL signal if COMMAND is still running\n\
- this long after the initial signal was sent.\n\
+ also send a KILL signal if COMMAND is still running\n\
+ this long after the initial signal was sent.\n\
-s, --signal=SIGNAL\n\
- specify the signal to be sent on timeout.\n\
- SIGNAL may be a name like `HUP' or a number.\n\
- See `kill -l` for a list of signals\n"), stdout);
+ specify the signal to be sent on timeout.\n\
+ SIGNAL may be a name like `HUP' or a number.\n\
+ See `kill -l` for a list of signals\n"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -266,6 +281,10 @@ main (int argc, char **argv)
usage (EXIT_CANCELED);
break;
+ case FOREGROUND_OPTION:
+ foreground = true;
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -287,7 +306,8 @@ main (int argc, char **argv)
Note we don't just put the child in a separate group as
then we would need to worry about foreground and background groups
and propagating signals between them. */
- setpgid (0, 0);
+ if (!foreground)
+ setpgid (0, 0);
/* Setup handlers before fork() so that we
handle any signals caused by child, without races. */