[PATCH] Cygwin: kill(1): skip kill(2) call if '-f -s -' is used

Christian Franke Christian.Franke@t-online.de
Fri Apr 11 14:46:07 GMT 2025


In rare cases, '/bin/kill -f PID' hangs because kill(2) is always tried 
first. With this patch, this could be prevented with '/bin/kill -f -s - 
PID'.

-- 
Regards,
Christian

-------------- next part --------------
From cb07ca02a856be378a2435f2095835c264b62bd9 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.franke@t-online.de>
Date: Fri, 11 Apr 2025 16:34:48 +0200
Subject: [PATCH] Cygwin: kill(1): skip kill(2) call if '-f -s -' is used

If a process does not process signals including SIGKILL, a kill(2)
call may also hang.  If '-' is specified instead of a signal, the
win32 interface is used without trying kill(2) first.

Signed-off-by: Christian Franke <christian.franke@t-online.de>
---
 winsup/utils/kill.cc | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc
index bcabcd47c..b2d3c6709 100644
--- a/winsup/utils/kill.cc
+++ b/winsup/utils/kill.cc
@@ -44,6 +44,7 @@ usage (FILE *where = stderr)
 	"Send signals to processes\n"
 	"\n"
 	" -f, --force     force, using win32 interface if necessary\n"
+	"                 (add '-s -' to always use win32 interface)\n"
 	" -l, --list      print a list of signal names\n"
 	" -L, --table     print a formatted table of signal names\n"
 	" -s, --signal    send signal (use %1$s --list for a list)\n"
@@ -312,6 +313,7 @@ main (int argc, char **argv)
 {
   int sig = SIGTERM;
   int force = 0;
+  int force_no_sig = 0;
   int winpids = 0;
   int ret = 0;
   char *gotasig = NULL;
@@ -335,7 +337,9 @@ main (int argc, char **argv)
 	{
 	case 's':
 	  gotasig = optarg;
-	  sig = getsig (gotasig);
+	  force_no_sig = !strcmp (gotasig, "-");
+	  sig = (!force_no_sig ? getsig (gotasig) :
+		SIGKILL /* for exit status */);
 	  break;
 	case 'l':
 	  if (!optarg)
@@ -387,6 +391,11 @@ main (int argc, char **argv)
     }
 
 out:
+  if (force_no_sig && !force)
+    {
+      fprintf (stderr, "%s: signal '-' requires '-f'\n", prog_name);
+      return 1;
+    }
   test_for_unknown_sig (sig, gotasig);
 
   argv += optind;
@@ -410,9 +419,10 @@ out:
       if (winpids)
 	{
 	  dwpid = pid;
-	  pid = (pid_t) cygwin_internal (CW_WINPID_TO_CYGWIN_PID, dwpid);
+	  if (!force_no_sig)
+	    pid = (pid_t) cygwin_internal (CW_WINPID_TO_CYGWIN_PID, dwpid);
 	}
-      if (kill ((pid_t) pid, sig) == 0)
+      if (!force_no_sig && kill ((pid_t) pid, sig) == 0)
 	{
 	  if (force)
 	    forcekill ((pid_t) pid, dwpid, sig, 1);
-- 
2.45.1



More information about the Cygwin-patches mailing list