On 10/29/2012 11:10 AM, Pádraig Brady wrote:
On 10/29/2012 10:07 AM, Jim Meyering wrote:
These days, I prefer more expressive option names. As long as a short
prefix is unique, length doesn't really matter. Here, --p is enough.
However, --preserve-status seems ok, too. There is precedent for
using "status" to mean "exit status" with md5sum's --status option.
Your call.
I've a slight preference for --preserve-status so.
I'm pushing the attached so marking this done.
cheers,
Pádraig.
>From de2397fece839ce90f71e0624f5435755ad9ea01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81ngel=20Gonz=C3=A1lez?= <[email protected]>
Date: Mon, 29 Oct 2012 00:36:08 +0000
Subject: [PATCH] timeout: add --preserve-status to always propagate the exit
status
It's useful for commands that support running for an indeterminite
amount of time, to not return a specific timeout exit status (124),
and instead let the command handle the timeout signal and return
a status for the work done so far.
* doc/coreutils.texi (timeout invocation): Describe the new option.
* src/timeout.c (preserve_status): A new global boolean to
enable the --preserve-status behavior.
(usage): Describe the new option.
(main): Don't return EXIT_TIMEOUT of preserve_status is set.
* tests/misc/timeout.sh: Add a test for the new option.
---
doc/coreutils.texi | 6 ++++++
src/timeout.c | 28 +++++++++++++++++++---------
tests/misc/timeout.sh | 5 +++++
3 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index e2b1059..767a31e 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -15890,6 +15890,12 @@ The program accepts the following options. Also see @ref{Common options}.
Options must precede operands.
@table @samp
+@item --preserve-status
+@opindex --preserve-status
+Return the exit status of the managed @var{command} on timeout, rather than
+a specific exit status indicating a timeout. This is useful if the
+managed @var{command} supports running for an indeterminite amount of time.
+
@item --foreground
@opindex --foreground
Don't create a separate background program group, so that
diff --git a/src/timeout.c b/src/timeout.c
index 4ce18ad..02d21c5 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -81,12 +81,14 @@ static int timed_out;
static int term_signal = SIGTERM; /* same default as kill command. */
static int monitored_pid;
static double kill_after;
-static bool foreground; /* whether to use another program group. */
+static bool foreground; /* whether to use another program group. */
+static bool preserve_status; /* whether to use a timeout status or not. */
/* for long options with no corresponding short option, use enum */
enum
{
- FOREGROUND_OPTION = CHAR_MAX + 1
+ FOREGROUND_OPTION = CHAR_MAX + 1,
+ PRESERVE_STATUS_OPTION
};
static struct option const long_options[] =
@@ -94,6 +96,7 @@ static struct option const long_options[] =
{"kill-after", required_argument, NULL, 'k'},
{"signal", required_argument, NULL, 's'},
{"foreground", no_argument, NULL, FOREGROUND_OPTION},
+ {"preserve-status", no_argument, NULL, PRESERVE_STATUS_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -214,6 +217,9 @@ 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 (_("\
+ --preserve-status\n\
+ exit with the same status as COMMAND, even when the\n\
+ command times out\n\
--foreground\n\
When not running timeout directly from a shell prompt,\n\
allow COMMAND to read from the TTY and receive TTY signals.\n\
@@ -235,12 +241,12 @@ DURATION is a floating point number with an optional suffix:\n\
or 'd' for days.\n"), stdout);
fputs (_("\n\
-If the command times out, then exit with status 124. Otherwise, exit\n\
-with the status of COMMAND. If no signal is specified, send the TERM\n\
-signal upon timeout. The TERM signal kills any process that does not\n\
-block or catch that signal. For other processes, it may be necessary to\n\
-use the KILL (9) signal, since this signal cannot be caught. If the\n\
-KILL (9) signal is sent, the exit status is 128+9 rather than 124.\n"), stdout);
+If the command times out, and --preserve-status is not set, then exit with\n\
+status 124. Otherwise, exit with the status of COMMAND. If no signal\n\
+is specified, send the TERM signal upon timeout. The TERM signal kills\n\
+any process that does not block or catch that signal. It may be necessary\n\
+to use the KILL (9) signal, since this signal cannot be caught, in which\n\
+case the exit status is 128+9 rather than 124.\n"), stdout);
emit_ancillary_info ();
}
exit (status);
@@ -376,6 +382,10 @@ main (int argc, char **argv)
foreground = true;
break;
+ case PRESERVE_STATUS_OPTION:
+ preserve_status = true;
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -470,7 +480,7 @@ main (int argc, char **argv)
}
}
- if (timed_out)
+ if (timed_out && !preserve_status)
return EXIT_TIMEDOUT;
else
return status;
diff --git a/tests/misc/timeout.sh b/tests/misc/timeout.sh
index 57a4e15..66d6956 100755
--- a/tests/misc/timeout.sh
+++ b/tests/misc/timeout.sh
@@ -36,6 +36,11 @@ test $? = 2 || fail=1
timeout 1 sleep 10
test $? = 124 || fail=1
+# exit status propagation even on timeout
+timeout --preserve-status 1 sleep 10
+# exit status should be 128+TERM
+test $? = 124 && fail=1
+
# kill delay. Note once the initial timeout triggers,
# the exit status will be 124 even if the command
# exits on its own accord.
--
1.7.6.4