From bb9f7a9375d7f0bfa08e345d0faf7dfb9a6eb618 Mon Sep 17 00:00:00 2001
From: "joreland@mysql.com" <>
Date: Sun, 9 May 2004 00:48:54 +0200
Subject: [PATCH] Stop entire process group (if child has forked) Impl. to
 handle "angle" process of ndb

---
 ndb/src/cw/cpcd/Process.cpp | 36 +++++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/ndb/src/cw/cpcd/Process.cpp b/ndb/src/cw/cpcd/Process.cpp
index 2c9a74ed20..76639a2a61 100644
--- a/ndb/src/cw/cpcd/Process.cpp
+++ b/ndb/src/cw/cpcd/Process.cpp
@@ -27,6 +27,8 @@
 #include <pwd.h>
 #include <sys/stat.h>
 #include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 void
 CPCD::Process::print(FILE * f){
@@ -103,7 +105,7 @@ bool
 CPCD::Process::isRunning() {
 
   if(m_pid <= 1){
-    logger.critical("isRunning(%d) invalid pid: %d", m_id, m_pid);
+    //logger.critical("isRunning(%d) invalid pid: %d", m_id, m_pid);
     return false;
   }
   /* Check if there actually exists a process with such a pid */
@@ -355,7 +357,7 @@ CPCD::Process::start() {
      */
     switch(pid = fork()) {
     case 0: /* Child */
-      
+      setsid();
       writePid(getpid());
       if(runas(m_runas.c_str()) == 0){
 	do_exec();
@@ -384,11 +386,11 @@ CPCD::Process::start() {
       pid_t pid;
       switch(pid = fork()) {
       case 0: /* Child */
+	setsid();
 	writePid(getpid());
 	if(runas(m_runas.c_str()) != 0){
 	  _exit(1);
 	}
-	setsid();
 	do_exec();
 	_exit(1);
 	/* NOTREACHED */
@@ -423,11 +425,11 @@ CPCD::Process::start() {
   while(readPid() < 0){
     sched_yield();
   }
-
+  
   if(pid != -1 && pid != m_pid){
     logger.error("pid and m_pid don't match: %d %d", pid, m_pid);
   }
-
+  
   if(isRunning()){
     m_status = RUNNING;
     return 0;
@@ -449,28 +451,32 @@ CPCD::Process::stop() {
   }
   m_status = STOPPING;
 
-  int ret = kill((pid_t)m_pid, SIGTERM);
+  const pid_t pgid = - getpgid(m_pid);
+  int ret = kill(pgid, SIGTERM);
   switch(ret) {
   case 0:
-    logger.debug("Sent SIGTERM to pid %d", (int)m_pid);
+    logger.debug("Sent SIGTERM to pid %d", (int)pgid);
     break;
   default:
-    logger.debug("kill pid: %d : %s", (int)m_pid, strerror(errno));
+    logger.debug("kill pid: %d : %s", (int)pgid, strerror(errno));
     break;
   }
-
-  if(isRunning()){
-    ret = kill((pid_t)m_pid, SIGKILL);
+  
+  errno = 0;
+  ret = kill(pgid, 0);
+  if(ret == 0) {
+    errno = 0;
+    ret = kill(pgid, SIGKILL);
     switch(ret) {
     case 0:
-      logger.debug("Sent SIGKILL to pid %d", (int)m_pid);
+      logger.debug("Sent SIGKILL to pid %d", (int)pgid);
       break;
     default:
-      logger.debug("kill pid: %d : %s\n", (int)m_pid, strerror(errno));
+      logger.debug("kill pid: %d : %s\n", (int)pgid, strerror(errno));
       break;
     }
-  }
-
+  } 
+  
   m_pid = -1;
   m_status = STOPPED;
 }
-- 
2.30.9