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

Reply via email to