From 79a6bee6822a37cba33f26f8c592fedb023dca89 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Wed, 8 Mar 2006 11:38:51 -0500
Subject: [PATCH] ENH: Added implementation of process tree killing that runs
 "ps" to traverse the tree.

---
 ProcessUNIX.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/ProcessUNIX.c b/ProcessUNIX.c
index 488e6bc6..d9e6691d 100644
--- a/ProcessUNIX.c
+++ b/ProcessUNIX.c
@@ -1898,6 +1898,22 @@ static pid_t kwsysProcessFork(kwsysProcess* cp,
     }
 }
 
+/*--------------------------------------------------------------------------*/
+/* For systems without the /proc filesystem we try to obtain process
+   information by invoking the ps command.  Here we define the command
+   to call on each platform and the corresponding parsing format
+   string.  The parsing format should have two integers to store: the
+   pid and then the ppid.  */
+#if defined(__linux__) || defined(__APPLE__)
+# define KWSYSPE_PS_COMMAND "ps axo pid,ppid"
+# define KWSYSPE_PS_HEADER  "%*s %*s\n"
+# define KWSYSPE_PS_FORMAT  "%d %d\n"
+#elif defined(__hpux) && 0 /* Disable until tested.  */
+# define KWSYSPE_PS_COMMAND "ps -ef"
+# define KWSYSPE_PS_HEADER  "%*s %*s %*s %*s %*s %*s %*s %*s\n"
+# define KWSYSPE_PS_FORMAT  "%*s %d %d %*s %*s %*s %*s %*s\n"
+#endif
+
 /*--------------------------------------------------------------------------*/
 static void kwsysProcessKill(pid_t process_id)
 {
@@ -1906,8 +1922,8 @@ static void kwsysProcessKill(pid_t process_id)
   /* Suspend the process to be sure it will not create more children.  */
   kill(process_id, SIGSTOP);
 
-  /* Kill all children if we can find them.  Currently this works only
-     on systems that support the proc filesystem.  */
+  /* Kill all children if we can find them.  First try using the /proc
+     filesystem.  */
   if((procdir = opendir("/proc")) != NULL)
     {
 #if defined(MAXPATHLEN)
@@ -1962,6 +1978,31 @@ static void kwsysProcessKill(pid_t process_id)
       }
     closedir(procdir);
     }
+#if defined(KWSYSPE_PS_COMMAND)
+  else
+    {
+    /* Try running "ps" to get the process information.  */
+    FILE* ps = popen(KWSYSPE_PS_COMMAND, "r");
+
+    /* Make sure the process started and provided a valid header.  */
+    if(ps && fscanf(ps, KWSYSPE_PS_HEADER) != EOF)
+      {
+      /* Look for processes whose parent is the process being killed.  */
+      int pid, ppid;
+      while(fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2)
+        {
+        if(ppid == process_id)
+          {
+          /* Recursively kill this child aned its children.  */
+          kwsysProcessKill(pid);
+          }
+        }
+
+      /* We are done with the ps process.  */
+      pclose(ps);
+      }
+    }
+#endif
 
   /* Kill the process.  */
   kill(process_id, SIGKILL);
-- 
GitLab