about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libutil/util.cc11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 16f4b232e6c5..6bf4b3d91805 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -724,8 +724,15 @@ int Pid::kill()
     /* Send the requested signal to the child.  If it has its own
        process group, send the signal to every process in the child
        process group (which hopefully includes *all* its children). */
-    if (::kill(separatePG ? -pid : pid, killSignal) != 0)
-        printError((SysError(format("killing process %1%") % pid).msg()));
+    if (::kill(separatePG ? -pid : pid, killSignal) != 0) {
+        /* On BSDs, killing a process group will return EPERM if all
+           processes in the group are zombies (or something like
+           that). So try to detect and ignore that situation. */
+#if __FreeBSD__ || __APPLE__
+        if (errno != EPERM || ::kill(pid, 0) != 0)
+#endif
+            printError((SysError("killing process %d", pid).msg()));
+    }
 
     return wait();
 }