1 2 3 4 16 package net.nutch.util; 17 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.OutputStream ; 21 22 import EDU.oswego.cs.dl.util.concurrent.BrokenBarrierException; 23 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier; 24 import EDU.oswego.cs.dl.util.concurrent.TimeoutException; 25 26 public class CommandRunner { 27 28 private boolean _waitForExit = true; 29 private String _command; 30 private int _timeout = 10; 31 private boolean _destroyOnTimeout = true; 32 33 private InputStream _stdin; 34 private OutputStream _stdout; 35 private OutputStream _stderr; 36 37 private static final int BUF = 4096; 38 39 private int _xit; 40 41 private Throwable _thrownError; 42 43 private CyclicBarrier _barrier; 44 45 public int getExitValue() { 46 return _xit; 47 } 48 49 public void setCommand(String s) { 50 _command = s; 51 } 52 53 public String getCommand() { 54 return _command; 55 } 56 57 public void setInputStream(InputStream is) { 58 _stdin = is; 59 } 60 61 public void setStdOutputStream(OutputStream os) { 62 _stdout = os; 63 } 64 65 public void setStdErrorStream(OutputStream os) { 66 _stderr = os; 67 } 68 69 public void evaluate() throws IOException { 70 Process proc = Runtime.getRuntime().exec(_command); 71 72 _barrier = new CyclicBarrier(3 + ((_stdin != null) ? 1 : 0)); 73 74 PullerThread so = 75 new PullerThread("STDOUT", proc.getInputStream(), _stdout); 76 so.start(); 77 78 PullerThread se = 79 new PullerThread("STDERR", proc.getErrorStream(), _stderr); 80 se.start(); 81 82 PusherThread si = null; 83 if (_stdin != null) { 84 si = new PusherThread("STDIN", _stdin, proc.getOutputStream()); 85 si.start(); 86 } 87 88 boolean _timedout = false; 89 long end = System.currentTimeMillis() + _timeout * 1000; 90 91 try { 92 if (_timeout == 0) { 93 _barrier.barrier(); 94 } else { 95 _barrier.attemptBarrier(_timeout * 1000); 96 } 97 } catch (TimeoutException ex) { 98 _timedout = true; 99 if (si != null) { 100 si.interrupt(); 101 } 102 so.interrupt(); 103 se.interrupt(); 104 if (_destroyOnTimeout) { 105 proc.destroy(); 106 } 107 } catch (BrokenBarrierException bbe) { 108 109 } catch (InterruptedException e) { 110 111 } 112 113 _xit = -1; 114 115 if (!_timedout) { 116 if (_waitForExit) { 117 do { 118 try { 119 _xit = proc.exitValue(); 120 Thread.sleep(250); 121 } catch (InterruptedException ie) { 122 123 } catch (IllegalThreadStateException iltse) { 124 continue; 125 } 126 break; 127 } while (!(_timedout = (System.currentTimeMillis() > end))); 128 } else { 129 try { 130 _xit = proc.exitValue(); 131 } catch (IllegalThreadStateException iltse) { 132 _timedout = true; 133 } 134 } 135 } 136 137 if (_timedout) { 138 if (_destroyOnTimeout) { 139 proc.destroy(); 140 } 141 } 142 } 143 144 public Throwable getThrownError() { 145 return _thrownError; 146 } 147 148 private class PumperThread extends Thread { 149 150 private OutputStream _os; 151 private InputStream _is; 152 153 private volatile boolean _kaput; 154 155 private boolean _closeInput; 156 157 protected PumperThread( 158 String name, 159 InputStream is, 160 OutputStream os, 161 boolean closeInput) { 162 super(name); 163 _is = is; 164 _os = os; 165 _closeInput = closeInput; 166 } 167 168 public void run() { 169 _kaput = false; 170 try { 171 byte[] buf = new byte[BUF]; 172 int read = 0; 173 while (!isInterrupted() && (read = _is.read(buf)) != -1) { 174 if (read == 0) 175 continue; 176 _os.write(buf, 0, read); 177 _os.flush(); 178 } 179 } catch (Throwable t) { 180 _thrownError = t; 181 return; 182 } finally { 183 try { 184 if (_closeInput) { 185 _is.close(); 186 } else { 187 _os.close(); 188 } 189 } catch (IOException ioe) { 190 191 } 192 } 193 try { 194 _barrier.barrier(); 195 } catch (InterruptedException ie) { 196 197 } catch (BrokenBarrierException bbe) { 198 199 } 200 } 201 } 202 203 private class PusherThread extends PumperThread { 204 PusherThread(String name, InputStream is, OutputStream os) { 205 super(name, is, os, false); 206 } 207 } 208 209 private class PullerThread extends PumperThread { 210 PullerThread(String name, InputStream is, OutputStream os) { 211 super(name, is, os, true); 212 } 213 } 214 215 public int getTimeout() { 216 return _timeout; 217 } 218 219 public void setTimeout(int timeout) { 220 _timeout = timeout; 221 } 222 223 public boolean getDestroyOnTimeout() { 224 return _destroyOnTimeout; 225 } 226 227 public void setDestroyOnTimeout(boolean destroyOnTimeout) { 228 _destroyOnTimeout = destroyOnTimeout; 229 } 230 231 public boolean getWaitForExit() { 232 return _waitForExit; 233 } 234 235 public void setWaitForExit(boolean waitForExit) { 236 _waitForExit = waitForExit; 237 } 238 239 public static void main(String [] args) throws Exception { 240 String commandPath = null; 241 String filePath = null; 242 int timeout = 10; 243 244 String usage = "Usage: CommandRunner [-timeout timeout] commandPath filePath"; 245 246 if (args.length < 2) { 247 System.err.println(usage); 248 System.exit(-1); 249 } 250 251 for (int i = 0; i < args.length; i++) { 252 if (args[i].equals("-timeout")) { 253 timeout = Integer.parseInt(args[++i]);; 254 } else if (i != args.length-2) { 255 System.err.println(usage); 256 System.exit(-1); 257 } else { 258 commandPath = args[i]; 259 filePath = args[++i]; 260 } 261 } 262 263 CommandRunner cr = new CommandRunner(); 264 265 cr.setCommand(commandPath); 266 cr.setInputStream(new java.io.FileInputStream (filePath)); 267 cr.setStdErrorStream(System.err); 268 cr.setStdOutputStream(System.out); 269 270 cr.setTimeout(timeout); 271 272 cr.evaluate(); 273 274 System.err.println("output value: "+cr.getExitValue()); 275 } 276 } 277 | Popular Tags |