1 37 38 package net.sourceforge.cruisecontrol.builders; 39 40 import java.io.File ; 41 import java.io.IOException ; 42 43 import net.sourceforge.cruisecontrol.CruiseControlException; 44 import net.sourceforge.cruisecontrol.util.Commandline; 45 import net.sourceforge.cruisecontrol.util.StreamConsumer; 46 import net.sourceforge.cruisecontrol.util.StreamPumper; 47 48 import org.apache.log4j.Logger; 49 50 54 public class ScriptRunner { 55 private static final Logger LOG = Logger.getLogger(ScriptRunner.class); 56 public static final long NO_TIMEOUT = -1; 57 58 public static class AsyncKiller extends Thread { 59 private final Process p; 60 private final long timeout; 61 private boolean killed; 62 63 AsyncKiller(final Process p, final long timeout) { 64 this.p = p; 65 this.timeout = timeout; 66 } 67 68 public void run() { 69 try { 70 sleep(timeout * 1000L); 71 synchronized (this) { 72 p.destroy(); 73 killed = true; 74 } 75 } catch (InterruptedException expected) { 76 } 77 } 78 79 public synchronized boolean processKilled() { 80 return killed; 81 } 82 } 83 84 91 public boolean runScript(File workingDir, Script script, long timeout) throws CruiseControlException { 92 Commandline commandline = script.buildCommandline(); 93 94 commandline.setWorkingDir(workingDir); 95 96 Process p; 97 int exitCode = -1; 98 99 try { 100 p = commandline.execute(); 101 } catch (IOException e) { 102 throw new CruiseControlException("Encountered an IO exception while attempting to execute '" 103 + script.toString() + "'. CruiseControl cannot continue.", e); 104 } 105 106 StreamPumper errorPumper; 107 StreamPumper outPumper; 108 if (script instanceof StreamConsumer) { 109 errorPumper = new StreamPumper(p.getErrorStream(), (StreamConsumer) script); 110 outPumper = new StreamPumper(p.getInputStream(), (StreamConsumer) script); 111 } else { 112 errorPumper = new StreamPumper(p.getErrorStream()); 113 outPumper = new StreamPumper(p.getInputStream()); 114 } 115 116 117 Thread stderr = new Thread (errorPumper); 118 stderr.start(); 119 Thread stdout = new Thread (outPumper); 120 stdout.start(); 121 AsyncKiller killer = new AsyncKiller(p, timeout); 122 if (timeout > 0) { 123 killer.start(); 124 } 125 126 try { 127 exitCode = p.waitFor(); 128 killer.interrupt(); 129 stderr.join(); 130 stdout.join(); 131 p.getInputStream().close(); 132 p.getOutputStream().close(); 133 p.getErrorStream().close(); 134 } catch (InterruptedException e) { 135 LOG.info("Was interrupted while waiting for script to finish." 136 + " CruiseControl will continue, assuming that it completed"); 137 } catch (IOException ie) { 138 LOG.info("Exception trying to close Process streams.", ie); 139 } 140 141 outPumper.flush(); 142 errorPumper.flush(); 143 144 script.setExitCode(exitCode); 145 146 return !killer.processKilled(); 147 148 } 149 } 150 151 152 153 154 | Popular Tags |