* @throws IOException
* An Exception from the underlying Process.
*/
public int launch(IProgressMonitor monitor) throws IOException {
Process process = null;
final MessageConsoleStream defaultConsoleStream;
final MessageConsoleStream stdoutConsoleStream;
final MessageConsoleStream stderrConsoleStream;
// Init the console output if a console has been set
// This will set the low / high water marks,
// get three MessageStreams for the console
// (default in black, stdout in dark green, stderr in dark red)
// and print a small header (incl. command name and all args)
if (fConsole != null) {
// Limit the size of the console
fConsole.setWaterMarks(8192, 16384);
// and get the output streams
defaultConsoleStream = fConsole.newMessageStream();
stdoutConsoleStream = fConsole.newMessageStream();
stderrConsoleStream = fConsole.newMessageStream();
// Set colors for the streams. This needs to be done in the UI
// thread (in which we may not be)
Display display = PlatformUI.getWorkbench().getDisplay();
if (display != null && !display.isDisposed()) {
display.syncExec(new Runnable() {
@Override
public void run() {
stdoutConsoleStream.setColor(PlatformUI.getWorkbench().getDisplay().getSystemColor(COLOR_STDOUT));
stderrConsoleStream.setColor(PlatformUI.getWorkbench().getDisplay().getSystemColor(COLOR_STDERR));
}
});
}
// Now print the Command line before any output is written to
// the console.
defaultConsoleStream.println();
defaultConsoleStream.println();
defaultConsoleStream.print("Launching ");
List<String> commandAndOptions = fProcessBuilder.command();
for (String str : commandAndOptions) {
defaultConsoleStream.print(str + " ");
}
defaultConsoleStream.println();
defaultConsoleStream.println("Output:");
} else {
// No console output requested, set all streams to null
defaultConsoleStream = null;
stdoutConsoleStream = null;
stderrConsoleStream = null;
}
// Get the name of the command (without the path)
// This is used upon exit to print a nice exit message
String command = fProcessBuilder.command().get(0);
String commandname = command.substring(command.lastIndexOf(File.separatorChar) + 1);
// After the setup we can now start the command
try {
monitor.beginTask("Launching " + fProcessBuilder.command().get(0), 100);
fStdOut = new ArrayList<String>();
fStdErr = new ArrayList<String>();
fProcessBuilder.directory(ArduinoInstancePreferences.getArduinoPath().toFile());
process = fProcessBuilder.start();
Thread stdoutRunner = new Thread(new LogStreamRunner(process.getInputStream(), fStdOut, stdoutConsoleStream));
Thread stderrRunner = new Thread(new LogStreamRunner(process.getErrorStream(), fStdErr, stderrConsoleStream));
synchronized (fRunLock) {
// Wait either for the logrunners to terminate or the user to
// cancel the job.
// The monitor is polled 10 times / sec.
stdoutRunner.start();
stderrRunner.start();
monitor.worked(5);
while (stdoutRunner.isAlive() || stderrRunner.isAlive()) {
fRunLock.wait(100);
if (monitor.isCanceled() == true) {
process.destroy();
process.waitFor();
if (defaultConsoleStream != null) {
// Write an Abort Message to the console (if active)
defaultConsoleStream.println(commandname + " execution aborted");
}
return -1;
}
}
}
// external process finished normally
monitor.worked(95);
if (defaultConsoleStream != null) {
defaultConsoleStream.println(commandname + " finished");
}
} catch (InterruptedException e) {
// This thread was interrupted from outside
// consider this to be a failure of the external programm
if (defaultConsoleStream != null) {
// Write an Abort Message to the console (if active)
defaultConsoleStream.println(commandname + " execution interrupted");
}
return -1;
} finally {
monitor.done();
if (defaultConsoleStream != null)
defaultConsoleStream.close();
if (stdoutConsoleStream != null)
stdoutConsoleStream.close();
if (stderrConsoleStream != null)
stderrConsoleStream.close();
}
// if we make it to here, the process has run without any Exceptions
// Wait for the process to finish and then get the return value.
try {
process.waitFor();