Add support for GNU coreutils "-k" parameter to timeout applet.
This patch moves the timing and process checking code into a separate reusable function and adds a optional second timeout which will send a SIGKILL to the process if it's still alive.
The patch introduces a compiler warning about mismatched "const char *" and "char *". I've left a FIXME.
-- Matthew Slowe
From 8f508628564604a8f0d3fad27bac8981f8798f34 Mon Sep 17 00:00:00 2001 From: Matthew Slowe <[email protected]> Date: Sat, 9 Oct 2021 12:26:40 +0100 Subject: [PATCH] timeout: add support for "timeout -k KILL_SECS" --- coreutils/timeout.c | 47 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/coreutils/timeout.c b/coreutils/timeout.c index 8485e1e7d..9ca699aeb 100644 --- a/coreutils/timeout.c +++ b/coreutils/timeout.c @@ -39,13 +39,27 @@ //kbuild:lib-$(CONFIG_TIMEOUT) += timeout.o //usage:#define timeout_trivial_usage -//usage: "[-s SIG] SECS PROG ARGS" +//usage: "[-s SIG] [-k KILL_SECS] SECS PROG ARGS" //usage:#define timeout_full_usage "\n\n" -//usage: "Run PROG. Send SIG to it if it is not gone in SECS seconds.\n" +//usage: "Run PROG. Send SIG to it if it is not gone in SECS seconds. If it is still not going in KILL_SECS seconds then send KILL to it.\n" //usage: "Default SIG: TERM." #include "libbb.h" +int timeout_wait(int timeout, pid_t pid); +int timeout_wait(int timeout, pid_t pid) { + while (1) { + sleep1(); + if (--timeout <= 0) + break; + if (kill(pid, 0)) { + /* process is gone */ + return EXIT_SUCCESS; + } + } + return EXIT_FAILURE; +} + int timeout_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int timeout_main(int argc UNUSED_PARAM, char **argv) { @@ -53,23 +67,34 @@ int timeout_main(int argc UNUSED_PARAM, char **argv) int status; int parent = 0; int timeout; + int kill_timeout; pid_t pid; #if !BB_MMU char *sv1, *sv2; #endif const char *opt_s = "TERM"; + const char *opt_k = "0"; /* -p option is not documented, it is needed to support NOMMU. */ /* -t SECONDS; -p PARENT_PID */ /* '+': stop at first non-option */ - getopt32(argv, "+s:" USE_FOR_NOMMU("p:+"), &opt_s, &parent); + getopt32(argv, "+s:k:" USE_FOR_NOMMU("p:+"), &opt_s, &opt_k, &parent); /*argv += optind; - no, wait for bb_daemonize_or_rexec! */ signo = get_signum(opt_s); if (signo < 0) bb_error_msg_and_die("unknown signal '%s'", opt_s); + kill_timeout = 0; + { + int opt_k_i; + /* FIXME: opt_k Declared const char* but discarded here */ + opt_k_i = parse_duration_str(opt_k); + if(opt_k_i > 0) + kill_timeout = opt_k_i; + } + if (!argv[optind]) bb_show_usage(); timeout = parse_duration_str(argv[optind++]); @@ -104,16 +129,16 @@ int timeout_main(int argc UNUSED_PARAM, char **argv) /* Here we are grandchild. Sleep, then kill grandparent */ grandchild: /* Just sleep(HUGE_NUM); kill(parent) may kill wrong process! */ - while (1) { - sleep1(); - if (--timeout <= 0) - break; - if (kill(parent, 0)) { - /* process is gone */ + if(timeout_wait(timeout, pid) == EXIT_SUCCESS) + return EXIT_SUCCESS; + kill(parent, signo); + + if(kill_timeout > 0) { + if(timeout_wait(kill_timeout, pid) == EXIT_SUCCESS) return EXIT_SUCCESS; - } + kill(parent, SIGKILL); } - kill(parent, signo); + return EXIT_SUCCESS; } -- 2.30.1 (Apple Git-130)
_______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
