* src/timeout.c: Support -f and -p short options, corresponding to --foreground and --preserve-status respectively. This adds compatability with POSIX 2024 and OpenBSD. (usage): Separate translations, and reorder the option descriptions. * doc/coreutils.texi (timeout invocation): Adjust accordingly, and also reorder the option descriptions alphabetically. * tests/timeout/timeout.sh: Also test short option variants. --- doc/coreutils.texi | 18 +++++++++------ src/timeout.c | 50 +++++++++++++++++++++------------------- tests/timeout/timeout.sh | 8 +++++-- 3 files changed, 43 insertions(+), 33 deletions(-)
diff --git a/doc/coreutils.texi b/doc/coreutils.texi index d5dd55092..77eed8e7c 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -18810,13 +18810,9 @@ 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 indeterminate amount of time. - -@item --foreground +@item -f +@itemx --foreground +@opindex -f @opindex --foreground Don't create a separate background program group, so that the managed @var{command} can use the foreground TTY normally. @@ -18856,6 +18852,14 @@ either because the signal was blocked or ignored, or if the @var{command} takes too long (e.g. for cleanup work) to terminate itself within a certain amount of time. +@item -p +@itemx --preserve-status +@opindex -p +@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 indeterminate amount of time. + @item -s @var{signal} @itemx --signal=@var{signal} @opindex -s diff --git a/src/timeout.c b/src/timeout.c index c102aff85..0f1afb119 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -85,20 +85,13 @@ static bool preserve_status; /* whether to use a timeout status or not. */ static bool verbose; /* whether to diagnose timeouts or not. */ static char const *command; -/* for long options with no corresponding short option, use enum */ -enum -{ - FOREGROUND_OPTION = CHAR_MAX + 1, - PRESERVE_STATUS_OPTION -}; - static struct option const long_options[] = { + {"foreground", no_argument, nullptr, 'f'}, {"kill-after", required_argument, nullptr, 'k'}, + {"preserve-status", no_argument, nullptr, 'p'}, {"signal", required_argument, nullptr, 's'}, {"verbose", no_argument, nullptr, 'v'}, - {"foreground", no_argument, nullptr, FOREGROUND_OPTION}, - {"preserve-status", no_argument, nullptr, PRESERVE_STATUS_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {nullptr, 0, nullptr, 0} @@ -271,22 +264,30 @@ Start COMMAND, and kill it if still running after DURATION.\n\ emit_mandatory_arg_note (); fputs (_("\ - --preserve-status\n\ - exit with the same status as COMMAND, even when the\n\ - command times out\n\ - --foreground\n\ + -f, --foreground\n\ when not running timeout directly from a shell prompt,\n\ allow COMMAND to read from the TTY and get TTY signals;\n\ in this mode, children of COMMAND will not be timed out\n\ +"), stdout); + fputs (_("\ -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\ +"), stdout); + fputs (_("\ + -p. --preserve-status\n\ + exit with the same status as COMMAND,\n\ + even when the command times out\n\ +"), stdout); + fputs (_("\ -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); + see 'kill -l' for a list of signals\n\ +"), stdout); fputs (_("\ - -v, --verbose diagnose to stderr any signal sent upon timeout\n"), stdout); + -v, --verbose diagnose to stderr any signal sent upon timeout\n\ +"), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); @@ -478,14 +479,23 @@ main (int argc, char **argv) initialize_exit_failure (EXIT_CANCELED); atexit (close_stdout); - while ((c = getopt_long (argc, argv, "+k:s:v", long_options, nullptr)) != -1) + while ((c = getopt_long (argc, argv, "+fk:ps:v", long_options, nullptr)) + != -1) { switch (c) { + case 'f': + foreground = true; + break; + case 'k': kill_after = parse_duration (optarg); break; + case 'p': + preserve_status = true; + break; + case 's': term_signal = operand2sig (optarg); if (term_signal == -1) @@ -496,14 +506,6 @@ main (int argc, char **argv) verbose = true; break; - case FOREGROUND_OPTION: - foreground = true; - break; - - case PRESERVE_STATUS_OPTION: - preserve_status = true; - break; - case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); diff --git a/tests/timeout/timeout.sh b/tests/timeout/timeout.sh index 882d1300d..31af249cd 100755 --- a/tests/timeout/timeout.sh +++ b/tests/timeout/timeout.sh @@ -37,7 +37,9 @@ returns_ 124 timeout .1 sleep 10 || fail=1 # exit status propagation even on timeout # exit status should be 128+TERM -returns_ 124 timeout --preserve-status .1 sleep 10 && fail=1 +for opt in '-p' '--preserve-status'; do + returns_ 124 timeout $opt .1 sleep 10 && fail=1 +done # kill delay. Note once the initial timeout triggers, # the exit status will be 124 even if the command @@ -45,7 +47,9 @@ returns_ 124 timeout --preserve-status .1 sleep 10 && fail=1 # exit status should be 128+KILL returns_ 124 timeout -s0 -k1 .1 sleep 10 && fail=1 # Ensure a consistent exit status with --foreground -returns_ 124 timeout --foreground -s0 -k1 .1 sleep 10 && fail=1 +for opt in '-f' '--foreground'; do + returns_ 124 timeout $opt -s0 -k1 .1 sleep 10 && fail=1 +done # Ensure 'timeout' is immune to parent's SIGCHLD handler # Use a subshell and an exec to work around a bug in FreeBSD 5.0 /bin/sh. -- 2.47.0