The branch stable/14 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1fe93549714d01e16e76af0d279bd05c5a7e0c7d

commit 1fe93549714d01e16e76af0d279bd05c5a7e0c7d
Author:     Aaron LI <a...@aaronly.me>
AuthorDate: 2025-04-03 01:07:52 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-06-16 08:51:53 +0000

    timeout(1): Fix the inheritance of signal dispositions
    
    (cherry picked from commit 2390cbfe55f55916eca25e8ba94a3320535e01c9)
---
 bin/timeout/timeout.1 | 10 +++++++++-
 bin/timeout/timeout.c | 50 ++++++++++++++++++++++++++++++--------------------
 2 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/bin/timeout/timeout.1 b/bin/timeout/timeout.1
index 14fc19292684..371a167d19f3 100644
--- a/bin/timeout/timeout.1
+++ b/bin/timeout/timeout.1
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 2, 2025
+.Dd April 3, 2025
 .Dt TIMEOUT 1
 .Os
 .Sh NAME
@@ -65,6 +65,14 @@ Therefore, a signal is never sent if
 .Ar duration
 is 0.
 .Pp
+The signal dispositions inherited by the
+.Ar command
+are the same as the dispositions that
+.Nm
+inherited, except for the signal that will be sent upon timeout,
+which is reset to take the default action and should terminate
+the process.
+.Pp
 The options are as follows:
 .Bl -tag -width indent
 .It Fl f , Fl -foreground
diff --git a/bin/timeout/timeout.c b/bin/timeout/timeout.c
index 8a2f0faecd83..1c4cfa6e017d 100644
--- a/bin/timeout/timeout.c
+++ b/bin/timeout/timeout.c
@@ -224,6 +224,7 @@ main(int argc, char **argv)
        bool timedout = false;
        bool do_second_kill = false;
        bool child_done = false;
+       sigset_t zeromask, allmask, oldmask;
        struct sigaction signals;
        struct procctl_reaper_status info;
        int signums[] = {
@@ -288,6 +289,33 @@ main(int argc, char **argv)
                        err(EXIT_FAILURE, "procctl(PROC_REAP_ACQUIRE)");
        }
 
+       /* Block all signals to avoid racing against the child. */
+       sigfillset(&allmask);
+       if (sigprocmask(SIG_BLOCK, &allmask, &oldmask) == -1)
+               err(EXIT_FAILURE, "sigprocmask()");
+
+       pid = fork();
+       if (pid == -1) {
+               err(EXIT_FAILURE, "fork()");
+       } else if (pid == 0) {
+               /*
+                * child process
+                *
+                * POSIX.1-2024 requires that the child process inherit the
+                * same signal dispositions as the timeout(1) utility
+                * inherited, except for the signal to be sent upon timeout.
+                */
+               signal(killsig, SIG_DFL);
+               if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1)
+                       err(EXIT_FAILURE, "sigprocmask(oldmask)");
+
+               execvp(argv[0], argv);
+               warn("exec(%s)", argv[0]);
+               _exit(errno == ENOENT ? EXIT_CMD_NOENT : EXIT_CMD_ERROR);
+       }
+
+       /* parent continues here */
+
        memset(&signals, 0, sizeof(signals));
        sigemptyset(&signals.sa_mask);
 
@@ -310,29 +338,11 @@ main(int argc, char **argv)
        signal(SIGTTIN, SIG_IGN);
        signal(SIGTTOU, SIG_IGN);
 
-       pid = fork();
-       if (pid == -1) {
-               err(EXIT_FAILURE, "fork()");
-       } else if (pid == 0) {
-               /* child process */
-               signal(SIGTTIN, SIG_DFL);
-               signal(SIGTTOU, SIG_DFL);
-
-               execvp(argv[0], argv);
-               warn("exec(%s)", argv[0]);
-               _exit(errno == ENOENT ? EXIT_CMD_NOENT : EXIT_CMD_ERROR);
-       }
-
-       /* parent continues here */
-
-       if (sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL) == -1)
-               err(EXIT_FAILURE, "sigprocmask()");
-
        set_interval(first_kill);
-       sigemptyset(&signals.sa_mask);
+       sigemptyset(&zeromask);
 
        for (;;) {
-               sigsuspend(&signals.sa_mask);
+               sigsuspend(&zeromask);
 
                if (sig_chld) {
                        sig_chld = 0;

Reply via email to