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);
}
}
}
}