/** * Execute an external process. Note: this is not a command-line command, it is a single program * and arguments. * * @param exec the executable and arguments of the process * @param envVars environment variables of the form name=value. If null, inherits vars from * current process. * @param dir the working directory. If null, uses the working dir from the current process * @param outStreamRedir stdout of the process will be redirected to this stream if not null * @param errStreamRedir stderr of the process will be redirected to this stream if not null */ public Exec( String[] exec, String[] envVars, File dir, OutputStream outStreamRedir, OutputStream errStreamRedir) { this.command = null; this.exec = exec; this.envVars = envVars; this.dir = dir; launcherEnvironment = Environment.getThreadEnvironment(); userInterface = new UserInterfaceExec(); this.outStreamRedir = outStreamRedir; this.errStreamRedir = errStreamRedir; this.processWriter = null; this.finishedListeners = new ArrayList<FinishedListener>(); this.exitVal = -1; setName(exec[0]); }
public void run() { if (Thread.currentThread() == this) { Environment.setThreadEnvironment(launcherEnvironment); Job.setUserInterface(userInterface); } if (outStreamRedir instanceof OutputStreamChecker) { ((OutputStreamChecker) outStreamRedir).setExec(this); } if (errStreamRedir instanceof OutputStreamChecker) { ((OutputStreamChecker) errStreamRedir).setExec(this); } try { Runtime rt = Runtime.getRuntime(); ExecProcessReader outReader = null; ExecProcessReader errReader = null; // run program synchronized (this) { try { if (command != null) p = rt.exec(command, envVars, dir); else p = rt.exec(exec, envVars, dir); } catch (IOException e) { System.out.println("Error running " + command + ": " + e.getMessage()); return; } // eat output (stdout) and stderr from program so it doesn't block outReader = new ExecProcessReader(p.getInputStream(), outStreamRedir); errReader = new ExecProcessReader(p.getErrorStream(), errStreamRedir); outReader.start(); errReader.start(); // attach to input of process processWriter = new PrintWriter(p.getOutputStream()); } // wait for exit status exitVal = p.waitFor(); // also wait for redir threads to die, if doing redir if (outStreamRedir != null) outReader.join(); if (errStreamRedir != null) errReader.join(); StringBuffer com = new StringBuffer(); if (command != null) com.append(command); else { for (int i = 0; i < exec.length; i++) com.append(exec[i] + " "); } // System.out.println("Process finished [exit: "+exitVal+"]: "+com.toString()); synchronized (finishedListeners) { FinishedEvent e = new FinishedEvent(this, com.toString(), dir, exitVal); ArrayList<FinishedListener> copy = new ArrayList<FinishedListener>(); // make copy cause listeners may want to remove themselves if process finished for (FinishedListener l : finishedListeners) { copy.add(l); } for (FinishedListener l : copy) { l.processFinished(e); } } synchronized (this) { if (processWriter != null) { processWriter.close(); processWriter = null; } } } catch (Exception e) { ActivityLogger.logException(e); } }