Blob Blame History Raw
diff --git a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
index 4610781..e08767f 100644
--- a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
+++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
@@ -8,8 +8,6 @@ import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.IProcessFactory;
 import org.eclipse.debug.core.model.IProcess;
 import org.eclipse.debug.core.model.RuntimeProcess;
-import org.jvnet.process_factory.AbstractProcess;
-import org.jvnet.process_factory.ProcessFactory;
 import org.python.pydev.core.log.Log;
 import org.python.pydev.debug.ui.RunPreferencesPage;
 
@@ -59,10 +57,10 @@ public class PyProcessFactory implements
         public void destroy() {
             if (RunPreferencesPage.getKillSubprocessesWhenTerminatingProcess()) {
                 try {
-                    AbstractProcess p = ProcessFactory.CreateProcess(process);
-                    //I.e.: this is the real change in this wrapper: when killing a process, we'll kill the children 
-                    //processes too, not only the main process (i.e.: so that we don't have zombie processes alive for 
-                    //Django, etc).
+                	UnixProcessKiller p = new UnixProcessKiller(process);
+                	//I.e.: this is the real change in this wrapper: when killing a process, we'll kill the children
+                	//processes too, not only the main process (i.e.: so that we don't have zombie processes alive for
+                	//Django, etc).
                     p.killRecursively();
                 } catch (Exception e) {
                     Log.log(e);
diff --git a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java
new file mode 100644
index 0000000..c8ec14f
--- /dev/null
+++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java
@@ -0,0 +1,108 @@
+package org.python.pydev.debug.processfactory;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.util.LinkedHashSet;
+import java.util.StringTokenizer;
+
+public class UnixProcessKiller {
+    private final int pid;
+
+    private static class Output {
+
+        public final String stdout;
+        public final String stderr;
+
+        public Output(String stdout, String stderr) {
+            this.stdout = stdout;
+            this.stderr = stderr;
+        }
+    }
+
+    public UnixProcessKiller(Process p)
+            throws Exception {
+        this.pid = getPid(p);
+    }
+
+    private static int getPid(Process process)
+            throws Exception {
+        try {
+            Field f = process.getClass().getDeclaredField("pid");
+            f.setAccessible(true);
+            return f.getInt(process);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void killRecursively()
+            throws IOException {
+        LinkedHashSet<Integer> listed = new LinkedHashSet<>();
+        killRecursively(pid, listed);
+    }
+
+    private static void killRecursively(int pid, LinkedHashSet<Integer> listed)
+            throws IOException {
+        listed.add(Integer.valueOf(pid));
+        Runtime.getRuntime().exec(new String[] {
+                "kill", "-stop", Integer.toString(pid)
+        }, null, null);
+        Process createProcess = Runtime.getRuntime().exec(new String[] {
+                "pgrep", "-P", Integer.toString(pid)
+        }, null, null);
+        Output outputPGrep = getProcessOutput(createProcess);
+        if (outputPGrep.stderr != null && outputPGrep.stderr.length() > 0) {
+            throw new RuntimeException(outputPGrep.stderr);
+        }
+        Runtime.getRuntime().exec(new String[] {
+                "kill", "-KILL", Integer.toString(pid)
+        }, null, null);
+        String ids = outputPGrep.stdout;
+        StringTokenizer strTok = new StringTokenizer(ids);
+        do {
+            if (!strTok.hasMoreTokens()) {
+                break;
+            }
+            String nextToken = strTok.nextToken();
+            int found = Integer.parseInt(nextToken);
+            if (!listed.contains(Integer.valueOf(found))) {
+                killRecursively(found, listed);
+            }
+        } while (true);
+    }
+
+    private static Output getProcessOutput(Process process)
+            throws IOException {
+        try {
+            process.getOutputStream().close();
+        } catch (IOException e2) {
+        }
+        InputStreamReader inputStream = new InputStreamReader(new BufferedInputStream(process.getInputStream()));
+        InputStreamReader errorStream = new InputStreamReader(new BufferedInputStream(process.getErrorStream()));
+        try {
+            process.waitFor();
+        } catch (InterruptedException e1) {
+        }
+        try {
+            Object sync = new Object();
+            synchronized (sync) {
+                sync.wait(10L);
+            }
+        } catch (Exception e) {
+        }
+        return new Output(readInputStream(inputStream), readInputStream(errorStream));
+    }
+
+    private static String readInputStream(InputStreamReader in)
+            throws IOException {
+        StringBuffer contents = new StringBuffer();
+        char buf[] = new char[80];
+        int c;
+        while ((c = in.read(buf)) != -1) {
+            contents.append(buf, 0, c);
+        }
+        return contents.toString();
+    }
+}
diff --git a/plugins/org.python.pydev.debug/build.properties b/plugins/org.python.pydev.debug/build.properties
index 0704b04..bf249fa 100644
--- a/plugins/org.python.pydev.debug/build.properties
+++ b/plugins/org.python.pydev.debug/build.properties
@@ -1,5 +1,4 @@
 bin.includes = plugin.xml,\
-               libs/winp-1.19.jar,\
                META-INF/,\
                schema/,\
                icons/,\
diff --git a/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF b/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
index e4ea072..12fd1ce 100644
--- a/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
+++ b/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
@@ -3,8 +3,7 @@ Bundle-ManifestVersion: 2
 Bundle-Name: Pydev debug
 Bundle-SymbolicName: org.python.pydev.debug; singleton:=true
 Bundle-Version: 5.6.0.qualifier
-Bundle-ClassPath: pydev-debug.jar,
- libs/winp-1.19.jar
+Bundle-ClassPath: pydev-debug.jar
 Bundle-Activator: org.python.pydev.debug.core.PydevDebugPlugin
 Bundle-Vendor: Aptana
 Bundle-Localization: plugin