git: 8a9927ecd4b6 - main - timeout(1): Add -f and -p options as per POSIX.1-2024

From: Baptiste Daroussin <bapt_at_FreeBSD.org>
Date: Wed, 16 Apr 2025 19:46:30 UTC
The branch main has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=8a9927ecd4b6e8cb306e4b940201b4efbfbc5dcb

commit 8a9927ecd4b6e8cb306e4b940201b4efbfbc5dcb
Author:     Aaron LI <aly@aaronly.me>
AuthorDate: 2025-04-02 15:29:57 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2025-04-16 19:45:38 +0000

    timeout(1): Add -f and -p options as per POSIX.1-2024
    
    POSIX.1-2024 first defined the timeout(1) utility and specified the '-f'
    and '-p' options, which are the short versions of '--foreground' and
    '--preserve-status' options, respectively.  Add the short versions to
    comply with the Standard.
    
    Obtained-from: DragonFly BSD
    Reference: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/timeout.html
---
 bin/timeout/timeout.1 |  8 ++++----
 bin/timeout/timeout.c | 35 ++++++++++++++++++++---------------
 2 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/bin/timeout/timeout.1 b/bin/timeout/timeout.1
index b81ce2f74625..3eacdd768410 100644
--- a/bin/timeout/timeout.1
+++ b/bin/timeout/timeout.1
@@ -32,11 +32,11 @@
 .Nd run a command with a time limit
 .Sh SYNOPSIS
 .Nm
+.Op Fl f | Fl -foreground
 .Op Fl k Ar time | Fl -kill-after Ar time
+.Op Fl p | Fl -preserve-status
 .Op Fl s Ar signal | Fl -signal Ar signal
 .Op Fl v | Fl -verbose
-.Op Fl -foreground
-.Op Fl -preserve-status
 .Ar duration
 .Ar command
 .Op Ar arg ...
@@ -67,7 +67,7 @@ is 0.
 .Pp
 The options are as follows:
 .Bl -tag -width indent
-.It Fl -foreground
+.It Fl f , Fl -foreground
 Only time out the
 .Ar command
 itself, but do not propagate signals to its descendants.
@@ -79,7 +79,7 @@ signal if
 is still running after
 .Ar time
 since the first signal was sent.
-.It Fl -preserve-status
+.It Fl p , Fl -preserve-status
 Always exit with the same status as
 .Ar command ,
 even if the timeout was reached.
diff --git a/bin/timeout/timeout.c b/bin/timeout/timeout.c
index 4c81b64cd2b6..7e4009f8ac8a 100644
--- a/bin/timeout/timeout.c
+++ b/bin/timeout/timeout.c
@@ -56,8 +56,8 @@ static void __dead2
 usage(void)
 {
 	fprintf(stderr,
-		"Usage: %s [--foreground] [-k time | --kill-after time]"
-		" [--preserve-status] [-s signal | --signal signal] "
+		"Usage: %s [-f | --foreground] [-k time | --kill-after time]"
+		" [-p | --preserve-status] [-s signal | --signal signal] "
 		" [-v | --verbose] <duration> <command> [arg ...]\n",
 		getprogname());
 	exit(EXIT_FAILURE);
@@ -175,13 +175,14 @@ int
 main(int argc, char **argv)
 {
 	int ch, status, sig;
-	int foreground, preserve;
 	int pstat = 0;
 	int killsig = SIGTERM;
 	size_t i;
 	pid_t pid, cpid;
 	double first_kill;
-	double second_kill;
+	double second_kill = 0;
+	bool foreground = false;
+	bool preserve = false;
 	bool timedout = false;
 	bool do_second_kill = false;
 	bool child_done = false;
@@ -198,25 +199,29 @@ main(int argc, char **argv)
 		SIGQUIT,
 	};
 
-	foreground = preserve = 0;
-	second_kill = 0;
-
+	const char optstr[] = "+fhk:ps:v";
 	const struct option longopts[] = {
-		{ "foreground",      no_argument,       &foreground,  1  },
-		{ "help",            no_argument,       NULL,        'h' },
-		{ "kill-after",      required_argument, NULL,        'k' },
-		{ "preserve-status", no_argument,       &preserve,    1  },
-		{ "signal",          required_argument, NULL,        's' },
-		{ "verbose",         no_argument,       NULL,        'v' },
-		{ NULL,              0,                 NULL,         0  },
+		{ "foreground",      no_argument,       NULL, 'f' },
+		{ "help",            no_argument,       NULL, 'h' },
+		{ "kill-after",      required_argument, NULL, 'k' },
+		{ "preserve-status", no_argument,       NULL, 'p' },
+		{ "signal",          required_argument, NULL, 's' },
+		{ "verbose",         no_argument,       NULL, 'v' },
+		{ NULL,              0,                 NULL,  0  },
 	};
 
-	while ((ch = getopt_long(argc, argv, "+k:s:vh", longopts, NULL)) != -1) {
+	while ((ch = getopt_long(argc, argv, optstr, longopts, NULL)) != -1) {
 		switch (ch) {
+		case 'f':
+			foreground = true;
+			break;
 		case 'k':
 			do_second_kill = true;
 			second_kill = parse_duration(optarg);
 			break;
+		case 'p':
+			preserve = true;
+			break;
 		case 's':
 			killsig = parse_signal(optarg);
 			break;