package org.python.pydev.debug.processfactory; import java.io.InputStream; import java.io.OutputStream; import java.util.Map; 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; public class PyProcessFactory implements IProcessFactory { public static final String PROCESS_FACTORY_ID = "org.python.pydev.debug.processfactory.PyProcessFactory"; @Override public IProcess newProcess(ILaunch launch, Process process, String label, Map attributes) { return new RuntimeProcess(launch, new ProcessWrapper(process), label, attributes); } static class ProcessWrapper extends Process { private Process process; public ProcessWrapper(Process process) { this.process = process; } @Override public OutputStream getOutputStream() { return process.getOutputStream(); } @Override public InputStream getInputStream() { return process.getInputStream(); } @Override public InputStream getErrorStream() { return process.getErrorStream(); } @Override public int waitFor() throws InterruptedException { return process.waitFor(); } @Override public int exitValue() { return process.exitValue(); } @Override 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). p.killRecursively(); } catch (Exception e) { Log.log(e); } } try { process.destroy(); } catch (Exception e) { Log.log(e); } } } }