From nobody Mon Jun 16 08:54:07 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bLP1r351nz5VprY; Mon, 16 Jun 2025 08:54:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bLP1q4n5Jz3wpD; Mon, 16 Jun 2025 08:54:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1750064047; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZK3/bvBzQLX/NYdsrk44RvJCiYw88asK7yGZgXiNdj4=; b=l4aiyz+IRoVxF5ZrfYY9216vWwWzsDG5dq6faXDkOCegMGOPmVpdNlb5KWABl3nKBKZfMz oww7UtbFfOfHkZ11iDENS/bLpBB4QbuKmMZbQrUa4SEUNCDMKXQLlvYf6EfWjuffRadGES Yp30QiawB3HV7FvMYUrGmxk2OrN5LCH88ZVXQebIoOXd37PUVEtN94P17C2CD0n/2A/Sdk Bsdf1n1eZBOLCnYlHOlBjncT7AnYJyTbniQXADGK/wmWUL/Wff70Kwyr0+vNAytZlSvIQf /JO0etqKMNezlfKbRrHcR0kcmA39jfY53rd9sN9iPxP2ruH2zPFL2WY57yiEfA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1750064047; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZK3/bvBzQLX/NYdsrk44RvJCiYw88asK7yGZgXiNdj4=; b=b1UWRuOw6bBCi1XloB0HJJFJrXQzsRSIQ/+yK3ArvyjWfqYA95PiDezZZTu5OZBlgYsPDD TZvl63LfJ+frlsdl1P/WQ0pP9bQeHYVGleEMLBCb3tnIaNlzLGRAX9DfEU1LFBs+s7WI9r O7qbWgbvxflcVJInVmgvLkYQBlr5dTEvaWpphIL6pXQPZdlrnGzWJl0tEHK6ZxwUl+ZSpU OhRVSHJ8VspBu1JuZn7YFL05yPVJCCivM5SRr+H5mCYQ1M72I1u5o18fi+ey+gjwyUp3PC IBd2ZAHuhbFG02jyd868MPBLHHE5pSXIDcf3yrWg/9nPfn2r9MqYx3gMrh6ekw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1750064047; a=rsa-sha256; cv=none; b=FSgyWoVNPsR8rbzrXOYl8nWnXMBpNFyl24U3akKYCUEGRSS4cgozqP+9hsvDgUspODp9te cfWagZ5/LwCsVUB/3zlkQTo8B0FAo6XdKlFy2cf0OdZ1/nfT0IG1e7EQrxJJnT8nw4pKXI /y73qgLZpDqapoEBQaxblpX5I/xM82yEdaNVQL3B9Hhd6U+UBHrklv3HzzTlmGtWxToDm7 w2Q4UPvJXnBh/I3g+pDqz6CYAsCyg32bqlI1h84mGZUFaYGlPtQ0lVRw4pbDEkvX6uoOX6 AFpk3KRnwU1yIpvBUx2AH/YGceW9efoZspadzP17URAj3q1eHZpYuNScVj97yQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bLP1q41gczrkL; Mon, 16 Jun 2025 08:54:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 55G8s7A3043419; Mon, 16 Jun 2025 08:54:07 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 55G8s7wg043416; Mon, 16 Jun 2025 08:54:07 GMT (envelope-from git) Date: Mon, 16 Jun 2025 08:54:07 GMT Message-Id: <202506160854.55G8s7wg043416@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 795153bda6da - stable/14 - timeout(1): Catch all signals and propagate them List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 795153bda6dae27ceac4a7298106c00ca706b0ec Auto-Submitted: auto-generated The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=795153bda6dae27ceac4a7298106c00ca706b0ec commit 795153bda6dae27ceac4a7298106c00ca706b0ec Author: Aaron LI AuthorDate: 2025-04-03 01:20:01 +0000 Commit: Konstantin Belousov CommitDate: 2025-06-16 08:51:53 +0000 timeout(1): Catch all signals and propagate them (cherry picked from commit 844cef26e810d903e11bf83cc6f6fd2e22a299f1) --- bin/timeout/timeout.1 | 22 ++++++++++++ bin/timeout/timeout.c | 92 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/bin/timeout/timeout.1 b/bin/timeout/timeout.1 index 371a167d19f3..44525daaec59 100644 --- a/bin/timeout/timeout.1 +++ b/bin/timeout/timeout.1 @@ -73,6 +73,28 @@ 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 +If +.Nm +receives the +.Dv SIGALRM +signal, it will behave as if the time limit has been reached +and send the specified signal to +.Ar command . +For any other signals delivered to +.Nm , +it will propagate them to +.Ar command , +with the exception of +.Dv SIGKILL +and +.Dv SIGSTOP . +If you want to prevent the +.Ar command +from being timed out, send +.Dv SIGKILL +to +.Nm . +.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 1c4cfa6e017d..6e93e9e2911c 100644 --- a/bin/timeout/timeout.c +++ b/bin/timeout/timeout.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2014 Baptiste Daroussin * Copyright (c) 2014 Vsevolod Stakhov + * Copyright (c) 2025 Aaron LI * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,8 +48,10 @@ #define EXIT_CMD_NOENT 127 static volatile sig_atomic_t sig_chld = 0; -static volatile sig_atomic_t sig_term = 0; static volatile sig_atomic_t sig_alrm = 0; +static volatile sig_atomic_t sig_term = 0; /* signal to terminate children */ +static volatile sig_atomic_t sig_other = 0; /* signal to propagate */ +static int killsig = SIGTERM; /* signal to kill children */ static const char *command = NULL; static bool verbose = false; @@ -137,19 +140,46 @@ parse_signal(const char *str) static void sig_handler(int signo) { - switch (signo) { - case SIGINT: - case SIGHUP: - case SIGQUIT: - case SIGTERM: + if (signo == killsig) { sig_term = signo; - break; + return; + } + + switch (signo) { case SIGCHLD: sig_chld = 1; break; case SIGALRM: sig_alrm = 1; break; + case SIGHUP: + case SIGINT: + case SIGQUIT: + case SIGILL: + case SIGTRAP: + case SIGABRT: + case SIGEMT: + case SIGFPE: + case SIGBUS: + case SIGSEGV: + case SIGSYS: + case SIGPIPE: + case SIGTERM: + case SIGXCPU: + case SIGXFSZ: + case SIGVTALRM: + case SIGPROF: + case SIGUSR1: + case SIGUSR2: + /* + * Signals with default action to terminate the process. + * See the sigaction(2) man page. + */ + sig_term = signo; + break; + default: + sig_other = signo; + break; } } @@ -214,8 +244,6 @@ main(int argc, char **argv) { int ch, status, sig; int pstat = 0; - int killsig = SIGTERM; - size_t i; pid_t pid, cpid; double first_kill; double second_kill = 0; @@ -225,17 +253,8 @@ main(int argc, char **argv) bool do_second_kill = false; bool child_done = false; sigset_t zeromask, allmask, oldmask; - struct sigaction signals; + struct sigaction sa; struct procctl_reaper_status info; - int signums[] = { - -1, - SIGTERM, - SIGINT, - SIGHUP, - SIGCHLD, - SIGALRM, - SIGQUIT, - }; const char optstr[] = "+fhk:ps:v"; const struct option longopts[] = { @@ -316,22 +335,17 @@ main(int argc, char **argv) /* parent continues here */ - memset(&signals, 0, sizeof(signals)); - sigemptyset(&signals.sa_mask); - - if (killsig != SIGKILL && killsig != SIGSTOP) - signums[0] = killsig; - - for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i++) - sigaddset(&signals.sa_mask, signums[i]); - - signals.sa_handler = sig_handler; - signals.sa_flags = SA_RESTART; - - for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i++) { - if (signums[i] > 0 && - sigaction(signums[i], &signals, NULL) == -1) - err(EXIT_FAILURE, "sigaction()"); + /* Catch all signals in order to propagate them. */ + memset(&sa, 0, sizeof(sa)); + sigfillset(&sa.sa_mask); + sa.sa_handler = sig_handler; + sa.sa_flags = SA_RESTART; + for (sig = 1; sig < sys_nsig; sig++) { + if (sig == SIGKILL || sig == SIGSTOP || sig == SIGCONT || + sig == SIGTTIN || sig == SIGTTOU) + continue; + if (sigaction(sig, &sa, NULL) == -1) + err(EXIT_FAILURE, "sigaction(%d)", sig); } /* Don't stop if background child needs TTY */ @@ -399,6 +413,14 @@ main(int argc, char **argv) do_second_kill = false; killsig = SIGKILL; } + + } else if (sig_other) { + /* Propagate any other signals. */ + sig = sig_other; + sig_other = 0; + logv("received signal %s(%d)", sys_signame[sig], sig); + + send_sig(pid, sig, foreground); } }