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
From cb07ca02a856be378a2435f2095835c264b62bd9 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.fra...@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.fra...@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