1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir package helper; 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir import java.io.BufferedReader; 30*cdf0e10cSrcweir import java.io.InputStream; 31*cdf0e10cSrcweir import java.io.File; 32*cdf0e10cSrcweir import java.io.PrintWriter; 33*cdf0e10cSrcweir import java.io.PrintStream; 34*cdf0e10cSrcweir import java.io.LineNumberReader; 35*cdf0e10cSrcweir import java.io.InputStreamReader; 36*cdf0e10cSrcweir import java.io.OutputStreamWriter; 37*cdf0e10cSrcweir import java.io.Writer; 38*cdf0e10cSrcweir import java.util.Calendar; 39*cdf0e10cSrcweir import java.util.Date; 40*cdf0e10cSrcweir import java.util.GregorianCalendar; 41*cdf0e10cSrcweir import lib.TestParameters; 42*cdf0e10cSrcweir import share.LogWriter; 43*cdf0e10cSrcweir import util.PropertyName; 44*cdf0e10cSrcweir import util.utils; 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir /** 47*cdf0e10cSrcweir * Class collect information from input stream in 48*cdf0e10cSrcweir * background (sparate thread) and outputs it to 49*cdf0e10cSrcweir * some log stream. I helps to avoid buffer overflow 50*cdf0e10cSrcweir * when output stream has small buffer size (e.g. 51*cdf0e10cSrcweir * in case when handling stdout from external 52*cdf0e10cSrcweir * <code>Process</code>) 53*cdf0e10cSrcweir * 54*cdf0e10cSrcweir * This class is currently used by ProcesHandler 55*cdf0e10cSrcweir * internally only. 56*cdf0e10cSrcweir */ 57*cdf0e10cSrcweir class Pump extends Thread 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir private LineNumberReader reader; 61*cdf0e10cSrcweir private String pref; 62*cdf0e10cSrcweir private StringBuffer buf = new StringBuffer(256); 63*cdf0e10cSrcweir private PrintWriter log; 64*cdf0e10cSrcweir private boolean bOutput; 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir /** 67*cdf0e10cSrcweir * Creates Pump for specified <code>InputStream</code>. 68*cdf0e10cSrcweir * This Pump also synchronously output text read to 69*cdf0e10cSrcweir * log by prefixed lines. Constructor immediately 70*cdf0e10cSrcweir * starts reading in a separate thread. 71*cdf0e10cSrcweir * 72*cdf0e10cSrcweir * @param is Stream which requires permanent reading. 73*cdf0e10cSrcweir * @param log Writer where prefixed text lines to be output 74*cdf0e10cSrcweir * @param outPrefix A prefix which is printed at the 75*cdf0e10cSrcweir * beginning of each output line. 76*cdf0e10cSrcweir */ 77*cdf0e10cSrcweir public Pump(InputStream is, PrintWriter log, String outPrefix, boolean _bOutput) 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir this.pref = (outPrefix == null) ? "" : outPrefix; 80*cdf0e10cSrcweir reader = new LineNumberReader(new InputStreamReader(is)); 81*cdf0e10cSrcweir this.log = log; 82*cdf0e10cSrcweir this.bOutput = _bOutput; 83*cdf0e10cSrcweir start(); 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir public void run() 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir try 89*cdf0e10cSrcweir { 90*cdf0e10cSrcweir String line = reader.readLine(); 91*cdf0e10cSrcweir while (line != null) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir if (bOutput) 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir log.println(pref + line); 96*cdf0e10cSrcweir log.flush(); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir buf.append(line).append('\n'); 99*cdf0e10cSrcweir line = reader.readLine(); 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir catch (java.io.IOException e) 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir log.println(pref + "Exception occured: " + e); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir /** 109*cdf0e10cSrcweir * Returns the text collected from input stream. 110*cdf0e10cSrcweir */ 111*cdf0e10cSrcweir public String getStringBuffer() 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir return buf.toString(); 114*cdf0e10cSrcweir } 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir /** 118*cdf0e10cSrcweir * Class provides convenient way for running external program 119*cdf0e10cSrcweir * handle its standard streams, control execution and check results. 120*cdf0e10cSrcweir * Instance of this class must be created only for a single 121*cdf0e10cSrcweir * execution. If you need to execute the same command again you 122*cdf0e10cSrcweir * should create a new instance for this. 123*cdf0e10cSrcweir */ 124*cdf0e10cSrcweir public class ProcessHandler 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir private String cmdLine; 128*cdf0e10cSrcweir private String[] cmdLineArray; 129*cdf0e10cSrcweir private String[] envVars = null; 130*cdf0e10cSrcweir private File workDir = null; 131*cdf0e10cSrcweir private PrintWriter log; 132*cdf0e10cSrcweir private int exitValue = -1; 133*cdf0e10cSrcweir private boolean isFinished = false; 134*cdf0e10cSrcweir private boolean isStarted = false; 135*cdf0e10cSrcweir private boolean mbTimedOut = false; 136*cdf0e10cSrcweir private long mTimeOut = 0; 137*cdf0e10cSrcweir private String stdInBuff = ""; 138*cdf0e10cSrcweir private Pump stdout = null; 139*cdf0e10cSrcweir private Pump stderr = null; 140*cdf0e10cSrcweir private PrintStream stdIn = null; 141*cdf0e10cSrcweir private Process m_aProcess = null; 142*cdf0e10cSrcweir private TestParameters param = null; 143*cdf0e10cSrcweir private boolean debug = false; 144*cdf0e10cSrcweir private boolean bUseOutput = true; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir private int m_nProcessTimeout = 0; 147*cdf0e10cSrcweir private String m_sProcessKiller; 148*cdf0e10cSrcweir private ProcessWatcher m_aWatcher; 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir /** 151*cdf0e10cSrcweir * Creates instance with specified external command. 152*cdf0e10cSrcweir * Debug info and output 153*cdf0e10cSrcweir * of external command is printed to stdout. 154*cdf0e10cSrcweir * @param cmdLine 155*cdf0e10cSrcweir */ 156*cdf0e10cSrcweir public ProcessHandler(String cmdLine) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir this(cmdLine, null, null, null, 0); 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir /** 162*cdf0e10cSrcweir * Creates instance with specified external command 163*cdf0e10cSrcweir * including parameters as an array. 164*cdf0e10cSrcweir * Debug info and output 165*cdf0e10cSrcweir * of external command is printed to stdout. 166*cdf0e10cSrcweir * @param cmdLines 167*cdf0e10cSrcweir */ 168*cdf0e10cSrcweir public ProcessHandler(String[] cmdLines) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir this(null, null, null, null, 0); 171*cdf0e10cSrcweir cmdLineArray = cmdLines; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir /** 175*cdf0e10cSrcweir * Creates instance with specified external command 176*cdf0e10cSrcweir * including parameters as an array, with environment 177*cdf0e10cSrcweir * variables. 178*cdf0e10cSrcweir * Debug info and output 179*cdf0e10cSrcweir * of external command is printed to stdout. 180*cdf0e10cSrcweir * @param cmdLines 181*cdf0e10cSrcweir * @param envVars 182*cdf0e10cSrcweir * @see java.lang.Runtime exec(String[], String[]) 183*cdf0e10cSrcweir */ 184*cdf0e10cSrcweir public ProcessHandler(String[] cmdLines, String[] envVars) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir this(null, null, null, envVars, 0); 187*cdf0e10cSrcweir cmdLineArray = cmdLines; 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir /** 191*cdf0e10cSrcweir * Creates instance with specified external command 192*cdf0e10cSrcweir * including parameters as an array, with environment 193*cdf0e10cSrcweir * variables. The command will be started in workDir. 194*cdf0e10cSrcweir * Debug info and output 195*cdf0e10cSrcweir * of external command is printed to stdout. 196*cdf0e10cSrcweir * @param cmdLines 197*cdf0e10cSrcweir * @param workDir 198*cdf0e10cSrcweir */ 199*cdf0e10cSrcweir public ProcessHandler(String[] cmdLines, File workDir) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir this(null, null, workDir, null, 0); 202*cdf0e10cSrcweir cmdLineArray = cmdLines; 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir /** 207*cdf0e10cSrcweir * Creates instance with specified external command and 208*cdf0e10cSrcweir * log stream where debug info and output 209*cdf0e10cSrcweir * of external command is printed out. The command will be started in workDir. 210*cdf0e10cSrcweir * @param cmdLines 211*cdf0e10cSrcweir * @param log 212*cdf0e10cSrcweir * @param workDir 213*cdf0e10cSrcweir */ 214*cdf0e10cSrcweir public ProcessHandler(String[] cmdLines, PrintWriter log, File workDir) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir this(null, log, workDir, null, 0); 217*cdf0e10cSrcweir cmdLineArray = cmdLines; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir /** 221*cdf0e10cSrcweir * Creates instance with specified external command and 222*cdf0e10cSrcweir * log stream where debug info and output 223*cdf0e10cSrcweir * of external command is printed out. 224*cdf0e10cSrcweir * @param cmdLine 225*cdf0e10cSrcweir * @param log 226*cdf0e10cSrcweir */ 227*cdf0e10cSrcweir public ProcessHandler(String cmdLine, PrintWriter log) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir this(cmdLine, log, null, null, 0); 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir /** 233*cdf0e10cSrcweir * Creates instance with specified external command and set the time out for the command. 234*cdf0e10cSrcweir * @param cmdLine 235*cdf0e10cSrcweir * @param timeOut 236*cdf0e10cSrcweir */ 237*cdf0e10cSrcweir public ProcessHandler(String cmdLine, int timeOut) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir this(cmdLine, null, null, null, timeOut); 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir /** 243*cdf0e10cSrcweir * Creates instance with specified external command which 244*cdf0e10cSrcweir * will be executed in the some work directory. 245*cdf0e10cSrcweir * Debug info and output 246*cdf0e10cSrcweir * of external commandis printed to stdout. 247*cdf0e10cSrcweir * @param cmdLine 248*cdf0e10cSrcweir * @param workDir 249*cdf0e10cSrcweir */ 250*cdf0e10cSrcweir public ProcessHandler(String cmdLine, File workDir) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir this(cmdLine, null, workDir, null, 0); 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir /** 256*cdf0e10cSrcweir * Creates instance with specified external command which 257*cdf0e10cSrcweir * will be executed in the some work directory. 258*cdf0e10cSrcweir * Debug info and output printed in log stream. 259*cdf0e10cSrcweir * @param cmdLine 260*cdf0e10cSrcweir * @param log 261*cdf0e10cSrcweir * @param workDir 262*cdf0e10cSrcweir */ 263*cdf0e10cSrcweir public ProcessHandler(String cmdLine, PrintWriter log, File workDir) 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir this(cmdLine, log, workDir, null, 0); 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir /** 269*cdf0e10cSrcweir * Creates instance with specified external command which 270*cdf0e10cSrcweir * will be executed in the some work directory and 271*cdf0e10cSrcweir * log stream where debug info and output 272*cdf0e10cSrcweir * of external command is printed . 273*cdf0e10cSrcweir * The specified environment variables are set for the new process. 274*cdf0e10cSrcweir * If log stream is null, logging is printed to stdout. 275*cdf0e10cSrcweir * @param cmdLine 276*cdf0e10cSrcweir * @param log 277*cdf0e10cSrcweir * @param workDir 278*cdf0e10cSrcweir * @param envVars 279*cdf0e10cSrcweir */ 280*cdf0e10cSrcweir public ProcessHandler(String cmdLine, PrintWriter log, File workDir, String[] envVars) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir this(cmdLine, log, workDir, envVars, 0); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir /** 286*cdf0e10cSrcweir * Creates instance with specified external command which 287*cdf0e10cSrcweir * will be executed in the some work directory and 288*cdf0e10cSrcweir * 289*cdf0e10cSrcweir * @param cmdLine the command to be executed 290*cdf0e10cSrcweir * @param log log stream where debug info and output 291*cdf0e10cSrcweir * of external command is printed . 292*cdf0e10cSrcweir * @param workDir The working directory of the new process 293*cdf0e10cSrcweir * @param envVars The specified environment variables are 294*cdf0e10cSrcweir * set for the new process. 295*cdf0e10cSrcweir * If log stream is null, logging is printed to stdout. 296*cdf0e10cSrcweir * @param timeOut When started sychronisly, the maximum time the 297*cdf0e10cSrcweir * process will live. When the process being destroyed 298*cdf0e10cSrcweir * a log will be written out. It can be asked on 299*cdf0e10cSrcweir * <code>isTimedOut()</code> if it has been terminated. 300*cdf0e10cSrcweir * 301*cdf0e10cSrcweir * timeOut > 0 302*cdf0e10cSrcweir * Waits specified time in miliSeconds for 303*cdf0e10cSrcweir * process to exit and return its status. 304*cdf0e10cSrcweir * 305*cdf0e10cSrcweir * timeOut = 0 306*cdf0e10cSrcweir * Waits for the process to end regulary 307*cdf0e10cSrcweir * 308*cdf0e10cSrcweir * timeOut < 0 309*cdf0e10cSrcweir * Kills the process immediately 310*cdf0e10cSrcweir * 311*cdf0e10cSrcweir * 312*cdf0e10cSrcweir */ 313*cdf0e10cSrcweir public ProcessHandler(String cmdLine, PrintWriter log, File workDir, String[] envVars, long timeOut) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir this.cmdLine = cmdLine; 316*cdf0e10cSrcweir this.workDir = workDir; 317*cdf0e10cSrcweir this.log = log; 318*cdf0e10cSrcweir this.cmdLine = cmdLine; 319*cdf0e10cSrcweir this.envVars = envVars; 320*cdf0e10cSrcweir if (log == null) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir this.log = new PrintWriter(new OutputStreamWriter(System.out)); 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir else 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir this.log = log; 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir this.mTimeOut = timeOut; 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir /** 332*cdf0e10cSrcweir * Creates instance with specified external command which 333*cdf0e10cSrcweir * will be executed in the some work directory and 334*cdf0e10cSrcweir * log stream where debug info and output of external command is printed. 335*cdf0e10cSrcweir * If log stream is null, logging is printed to stdout. 336*cdf0e10cSrcweir * From the <CODE>TestParameters</CODE> the <CODE>OfficeWachter</CODE> get a ping. 337*cdf0e10cSrcweir * @param commands 338*cdf0e10cSrcweir * @param log 339*cdf0e10cSrcweir * @param workDir 340*cdf0e10cSrcweir * @param shortWait If this parameter is ture the <CODE>mTimeOut</CODE> is set to 5000 ms, else it is set to 341*cdf0e10cSrcweir * half of time out from parameter timeout. 342*cdf0e10cSrcweir * @param param the TestParameters 343*cdf0e10cSrcweir * @see lib.TestParameters 344*cdf0e10cSrcweir * @see helper.OfficeWatcher 345*cdf0e10cSrcweir */ 346*cdf0e10cSrcweir public ProcessHandler(String[] commands, PrintWriter log, File workDir, int shortWait, TestParameters param) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir this(null, log, workDir, null, 0); 349*cdf0e10cSrcweir this.cmdLineArray = commands; 350*cdf0e10cSrcweir this.param = param; 351*cdf0e10cSrcweir if (shortWait != 0) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir this.mTimeOut = shortWait; 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir else 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir this.mTimeOut = (long) (param.getInt(PropertyName.TIME_OUT) / 1.3); 358*cdf0e10cSrcweir } 359*cdf0e10cSrcweir debug = param.getBool(PropertyName.DEBUG_IS_ACTIVE); 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir /** 364*cdf0e10cSrcweir * If not equal 0, the time to maximal wait. 365*cdf0e10cSrcweir * @param _n 366*cdf0e10cSrcweir */ 367*cdf0e10cSrcweir public void setProcessTimeout(int _n) 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir m_nProcessTimeout = _n; 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir /** 373*cdf0e10cSrcweir * This command will call after ProcessTimeout is arrived. 374*cdf0e10cSrcweir * @param _s 375*cdf0e10cSrcweir */ 376*cdf0e10cSrcweir public void setProcessKiller(String _s) 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir m_sProcessKiller = _s; 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir /** 382*cdf0e10cSrcweir * This method do an asynchronous execution of the commands. To avoid a interruption on long running processes 383*cdf0e10cSrcweir * caused by <CODE>OfficeWatcher</CODE>, the OfficeWatcher get frequently a ping. 384*cdf0e10cSrcweir * @see helper.OfficeWatcher 385*cdf0e10cSrcweir */ 386*cdf0e10cSrcweir public void runCommand() 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir boolean changedText = true; 390*cdf0e10cSrcweir int count = 0; 391*cdf0e10cSrcweir String memText = ""; 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir this.executeAsynchronously(); 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir OfficeWatcher ow = null; 396*cdf0e10cSrcweir if (param != null) 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir ow = (OfficeWatcher) param.get(PropertyName.OFFICE_WATCHER); 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir if (ow != null) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir ow.ping(); 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir int hangcheck = 10; 406*cdf0e10cSrcweir while (!this.isFinished() && changedText) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir count++; 409*cdf0e10cSrcweir // dbg("runCommand: waiting " + mTimeOut / 1000 + " seconds while command execution is ongoing... " + count); 410*cdf0e10cSrcweir // shortWait(mTimeOut); 411*cdf0e10cSrcweir // shortWait(2000); // wait 2 seconds. 412*cdf0e10cSrcweir //waitFor(mTimeOut); 413*cdf0e10cSrcweir waitFor(2000, false); // wait but don't kill 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir if (ow != null) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir ow.ping(); 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir // check for changes in the output stream. If there are no changes, the process maybe hangs 420*cdf0e10cSrcweir if (!this.isFinished()) 421*cdf0e10cSrcweir { 422*cdf0e10cSrcweir hangcheck--; 423*cdf0e10cSrcweir if (hangcheck < 0) 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir String sOutputText = getOutputText(); 426*cdf0e10cSrcweir if (sOutputText.length() == memText.length()) 427*cdf0e10cSrcweir { 428*cdf0e10cSrcweir changedText = false; 429*cdf0e10cSrcweir // dbg("runCommand Could not detect changes in output stream!!!"); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir hangcheck = 10; 432*cdf0e10cSrcweir memText = this.getOutputText(); 433*cdf0e10cSrcweir } 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir if (!this.isFinished()) 438*cdf0e10cSrcweir { 439*cdf0e10cSrcweir dbg("runCommand Process ist not finished but there are no changes in output stream."); 440*cdf0e10cSrcweir this.kill(); 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir public boolean isTimedOut() 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir return mbTimedOut; 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir private void setTimedOut(boolean bTimedOut) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir mbTimedOut = bTimedOut; 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir /** 455*cdf0e10cSrcweir * Executes the command and returns only when the process 456*cdf0e10cSrcweir * exits. 457*cdf0e10cSrcweir * 458*cdf0e10cSrcweir * @return <code>true</code> if process was successfully 459*cdf0e10cSrcweir * started and correcly exits (exit code doesn't affect 460*cdf0e10cSrcweir * to this result). 461*cdf0e10cSrcweir */ 462*cdf0e10cSrcweir public boolean executeSynchronously() 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir execute(); 465*cdf0e10cSrcweir return waitFor(mTimeOut); 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir /** 469*cdf0e10cSrcweir * Executes the command immediately returns. The process 470*cdf0e10cSrcweir * remains in running state. Control of its state should 471*cdf0e10cSrcweir * be made by <code>waitFor</code> methods. 472*cdf0e10cSrcweir * 473*cdf0e10cSrcweir * @return <code>true</code> if process was successfully 474*cdf0e10cSrcweir * started. 475*cdf0e10cSrcweir */ 476*cdf0e10cSrcweir public boolean executeAsynchronously() 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir execute(); 479*cdf0e10cSrcweir return isStarted(); 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir 482*cdf0e10cSrcweir public synchronized void kill() 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir if (!isStarted()) 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir return; 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir boolean exit = false; 489*cdf0e10cSrcweir int counter = 1; 490*cdf0e10cSrcweir while (counter < 3 && !exit) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir m_aProcess.destroy(); 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir try 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir Thread.sleep(1000 * counter); // 5000 497*cdf0e10cSrcweir } 498*cdf0e10cSrcweir catch (java.lang.InterruptedException e) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir try 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir final int exit_Value = m_aProcess.exitValue(); 504*cdf0e10cSrcweir if (exit_Value < 1) 505*cdf0e10cSrcweir { 506*cdf0e10cSrcweir exit = true; 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir else 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir counter++; 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir dbg("kill: process closed with exit code " + exit_Value); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir catch (java.lang.IllegalThreadStateException e) 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir if (counter < 3) 517*cdf0e10cSrcweir { 518*cdf0e10cSrcweir dbg("kill: Couldn't close process after " + counter + " attempts, trying again"); 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir counter++; 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir } 523*cdf0e10cSrcweir isStarted = false; 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir /** 527*cdf0e10cSrcweir * Returns the time in seconds since 1st January 1970 528*cdf0e10cSrcweir * @return 529*cdf0e10cSrcweir */ 530*cdf0e10cSrcweir public static long getSystemTime() 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir // Calendar cal = new GregorianCalendar(); 533*cdf0e10cSrcweir // final long nTime = cal.getTimeInMillis(); 534*cdf0e10cSrcweir final long nTime = System.currentTimeMillis(); 535*cdf0e10cSrcweir return nTime; 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir private long m_nExactStartTimeInMillisec; 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir private void initialExactStartTime() 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir m_nExactStartTimeInMillisec = getSystemTime(); 542*cdf0e10cSrcweir } 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir public long getProcessStartTime() 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir return m_nExactStartTimeInMillisec; 547*cdf0e10cSrcweir } 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir private void showEnvVars() 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir if (envVars != null) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir for (int i = 0; i < envVars.length; i++) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir log.println("env: " + envVars[i]); 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir else 559*cdf0e10cSrcweir { 560*cdf0e10cSrcweir log.println("env: null"); 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir protected void execute() 565*cdf0e10cSrcweir { 566*cdf0e10cSrcweir if (isStarted()) 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir throw new RuntimeException( 569*cdf0e10cSrcweir "The process handler has already been executed."); 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir final Runtime runtime = Runtime.getRuntime(); 572*cdf0e10cSrcweir try 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir if (cmdLine == null) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir log.println(utils.getDateTime() + "execute: Starting command from array: "); 577*cdf0e10cSrcweir for (int i = 0; i < cmdLineArray.length; i++) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir log.println(cmdLineArray[i]); 580*cdf0e10cSrcweir // log.print(" "); 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir showEnvVars(); 583*cdf0e10cSrcweir log.println(""); 584*cdf0e10cSrcweir initialExactStartTime(); 585*cdf0e10cSrcweir initializeProcessKiller(); 586*cdf0e10cSrcweir m_aProcess = runtime.exec(cmdLineArray, envVars); 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir else 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir if (workDir != null) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir log.println(utils.getDateTime() + "execute: Starting command: "); 593*cdf0e10cSrcweir log.println(cmdLine + " path=" + workDir.getAbsolutePath()); 594*cdf0e10cSrcweir showEnvVars(); 595*cdf0e10cSrcweir m_aProcess = runtime.exec(cmdLine, envVars, workDir); 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir else 598*cdf0e10cSrcweir { 599*cdf0e10cSrcweir log.println(utils.getDateTime() + "execute: Starting command: "); 600*cdf0e10cSrcweir log.println(cmdLine); 601*cdf0e10cSrcweir showEnvVars(); 602*cdf0e10cSrcweir m_aProcess = runtime.exec(cmdLine, envVars); 603*cdf0e10cSrcweir } 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir isStarted = true; 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir catch (java.io.IOException e) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir if (cmdLine == null) 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir log.println(utils.getDateTime() + "execute: The command array can't be started: " + e); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir else 614*cdf0e10cSrcweir { 615*cdf0e10cSrcweir log.println(utils.getDateTime() + "execute: The command " + cmdLine + " can't be started: " + e); 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir return; 618*cdf0e10cSrcweir } 619*cdf0e10cSrcweir dbg("execute: pump io-streams"); 620*cdf0e10cSrcweir stdout = new Pump(m_aProcess.getInputStream(), log, "out > ", bUseOutput); 621*cdf0e10cSrcweir stderr = new Pump(m_aProcess.getErrorStream(), log, "err > ", bUseOutput); 622*cdf0e10cSrcweir stdIn = new PrintStream(m_aProcess.getOutputStream()); 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir // int nExitValue = m_aProcess.exitValue(); 625*cdf0e10cSrcweir // int dummy = 0; 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir dbg("execute: flush io-streams"); 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir flushInput(); 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir /** 633*cdf0e10cSrcweir * This method is useful when the process was executed 634*cdf0e10cSrcweir * asynchronously. Waits for process to exit and return 635*cdf0e10cSrcweir * its result. 636*cdf0e10cSrcweir * 637*cdf0e10cSrcweir * @return <code>true</code> if process correctly exited 638*cdf0e10cSrcweir * (exit code doesn't affect to this result). 639*cdf0e10cSrcweir */ 640*cdf0e10cSrcweir public boolean waitFor() 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir return waitFor(0); 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir /** 646*cdf0e10cSrcweir * This method is useful when the process was executed 647*cdf0e10cSrcweir * asynchronously. Waits during specified time for process 648*cdf0e10cSrcweir * to exit and return its status. 649*cdf0e10cSrcweir * 650*cdf0e10cSrcweir * @param timeout > 0 651*cdf0e10cSrcweir * Waits specified time in miliSeconds for 652*cdf0e10cSrcweir * process to exit and return its status. 653*cdf0e10cSrcweir * 654*cdf0e10cSrcweir * = 0 655*cdf0e10cSrcweir * Waits for the process to end regulary 656*cdf0e10cSrcweir * 657*cdf0e10cSrcweir * < 0 658*cdf0e10cSrcweir * Kills the process immediately 659*cdf0e10cSrcweir * 660*cdf0e10cSrcweir * @return <code>true</code> if process correctly exited 661*cdf0e10cSrcweir * (exit code doesn't affect to this result). 662*cdf0e10cSrcweir */ 663*cdf0e10cSrcweir public boolean waitFor(long timeout) 664*cdf0e10cSrcweir { 665*cdf0e10cSrcweir return waitFor(timeout, true); 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir private boolean waitFor(long timeout, boolean bKillProcessAfterTimeout) 669*cdf0e10cSrcweir { 670*cdf0e10cSrcweir if (isFinished()) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir return true; 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir if (!isStarted()) 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir return false; 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir if (timeout == 0) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir try 682*cdf0e10cSrcweir { 683*cdf0e10cSrcweir m_aProcess.waitFor(); 684*cdf0e10cSrcweir } 685*cdf0e10cSrcweir catch (InterruptedException e) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir log.println("The process was interrupted: " + e); 688*cdf0e10cSrcweir } 689*cdf0e10cSrcweir isFinished = true; 690*cdf0e10cSrcweir try 691*cdf0e10cSrcweir { 692*cdf0e10cSrcweir exitValue = m_aProcess.exitValue(); 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir catch (IllegalThreadStateException e) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir else 699*cdf0e10cSrcweir { 700*cdf0e10cSrcweir try 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir while (!isFinished && timeout > 0) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir isFinished = true; 705*cdf0e10cSrcweir Thread.sleep(1000); 706*cdf0e10cSrcweir timeout -= 1000; 707*cdf0e10cSrcweir try 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir exitValue = m_aProcess.exitValue(); // throws exception if not finished 710*cdf0e10cSrcweir } 711*cdf0e10cSrcweir catch (IllegalThreadStateException e) 712*cdf0e10cSrcweir { 713*cdf0e10cSrcweir isFinished = false; 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir } 716*cdf0e10cSrcweir if (timeout < 0) 717*cdf0e10cSrcweir { 718*cdf0e10cSrcweir setTimedOut(true); 719*cdf0e10cSrcweir log.println("The process has timed out!"); 720*cdf0e10cSrcweir } 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir catch (InterruptedException ex) 723*cdf0e10cSrcweir { 724*cdf0e10cSrcweir log.println("The process was interrupted: " + ex); 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir } 727*cdf0e10cSrcweir 728*cdf0e10cSrcweir if (bKillProcessAfterTimeout == true) 729*cdf0e10cSrcweir { 730*cdf0e10cSrcweir if (!isFinished) 731*cdf0e10cSrcweir { 732*cdf0e10cSrcweir log.println("Going to destroy the process!!"); 733*cdf0e10cSrcweir m_aProcess.destroy(); 734*cdf0e10cSrcweir log.println("Process has been destroyed!"); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir } 737*cdf0e10cSrcweir // Removed as hung up in SDK test 'PathSettings' 738*cdf0e10cSrcweir // try { 739*cdf0e10cSrcweir // stdout.join(); 740*cdf0e10cSrcweir // stderr.join(); 741*cdf0e10cSrcweir // } catch (InterruptedException e) {} 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir return isFinished(); 744*cdf0e10cSrcweir } 745*cdf0e10cSrcweir 746*cdf0e10cSrcweir protected void flushInput() 747*cdf0e10cSrcweir { 748*cdf0e10cSrcweir if (stdIn == null) 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir return; 751*cdf0e10cSrcweir } 752*cdf0e10cSrcweir 753*cdf0e10cSrcweir synchronized(stdInBuff) 754*cdf0e10cSrcweir { 755*cdf0e10cSrcweir stdIn.print(stdInBuff); 756*cdf0e10cSrcweir stdIn.flush(); 757*cdf0e10cSrcweir stdInBuff = ""; 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir } 760*cdf0e10cSrcweir 761*cdf0e10cSrcweir /** 762*cdf0e10cSrcweir * Returns the text output by external command to stdout. 763*cdf0e10cSrcweir * @return the text output by external command to stdout 764*cdf0e10cSrcweir */ 765*cdf0e10cSrcweir public String getOutputText() 766*cdf0e10cSrcweir { 767*cdf0e10cSrcweir if (stdout == null) 768*cdf0e10cSrcweir { 769*cdf0e10cSrcweir return ""; 770*cdf0e10cSrcweir } 771*cdf0e10cSrcweir else 772*cdf0e10cSrcweir { 773*cdf0e10cSrcweir return stdout.getStringBuffer(); 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir } 776*cdf0e10cSrcweir 777*cdf0e10cSrcweir /** 778*cdf0e10cSrcweir * Returns the text output by external command to stderr. 779*cdf0e10cSrcweir * @return the text output by external command to stderr 780*cdf0e10cSrcweir */ 781*cdf0e10cSrcweir public String getErrorText() 782*cdf0e10cSrcweir { 783*cdf0e10cSrcweir if (stderr == null) 784*cdf0e10cSrcweir { 785*cdf0e10cSrcweir return ""; 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir else 788*cdf0e10cSrcweir { 789*cdf0e10cSrcweir return stderr.getStringBuffer(); 790*cdf0e10cSrcweir } 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir /** 794*cdf0e10cSrcweir * Prints the string specified to sdtin of external 795*cdf0e10cSrcweir * command. '\n' is not added so if you need you 796*cdf0e10cSrcweir * should terminate the string with '\n'. <p> 797*cdf0e10cSrcweir * 798*cdf0e10cSrcweir * The method can also be called before the command 799*cdf0e10cSrcweir * starts its execution. Then the text is buffered 800*cdf0e10cSrcweir * and transfered to command when it will be started. 801*cdf0e10cSrcweir * @param str 802*cdf0e10cSrcweir */ 803*cdf0e10cSrcweir public void printInputText(String str) 804*cdf0e10cSrcweir { 805*cdf0e10cSrcweir stdInBuff += str; 806*cdf0e10cSrcweir flushInput(); 807*cdf0e10cSrcweir } 808*cdf0e10cSrcweir 809*cdf0e10cSrcweir /** 810*cdf0e10cSrcweir * Returns information about was the command started or 811*cdf0e10cSrcweir * not. 812*cdf0e10cSrcweir * 813*cdf0e10cSrcweir * @return <code>true</code> if the external command was 814*cdf0e10cSrcweir * found and successfully started. 815*cdf0e10cSrcweir */ 816*cdf0e10cSrcweir public boolean isStarted() 817*cdf0e10cSrcweir { 818*cdf0e10cSrcweir return isStarted; 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir /** 822*cdf0e10cSrcweir * Returns the information about the final state of command 823*cdf0e10cSrcweir * execution. 824*cdf0e10cSrcweir * 825*cdf0e10cSrcweir * @return <code>true</code> if the command correctly starts, 826*cdf0e10cSrcweir * exits and was not interrupted due to timeout. 827*cdf0e10cSrcweir */ 828*cdf0e10cSrcweir public boolean isFinished() 829*cdf0e10cSrcweir { 830*cdf0e10cSrcweir return isFinished; 831*cdf0e10cSrcweir } 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir /** 834*cdf0e10cSrcweir * Returns exit code of the external command. 835*cdf0e10cSrcweir * 836*cdf0e10cSrcweir * @return exit code of command if it was finished, 837*cdf0e10cSrcweir * -1 if not. 838*cdf0e10cSrcweir */ 839*cdf0e10cSrcweir public int getExitCode() 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir try 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir exitValue = m_aProcess.exitValue(); 844*cdf0e10cSrcweir } 845*cdf0e10cSrcweir catch (Exception e) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir //System.out.println("No ExitValue available"); 848*cdf0e10cSrcweir } 849*cdf0e10cSrcweir 850*cdf0e10cSrcweir return exitValue; 851*cdf0e10cSrcweir } 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir /** Causes the thread to sleep some time. 854*cdf0e10cSrcweir * @param milliseconds 855*cdf0e10cSrcweir */ 856*cdf0e10cSrcweir public static void shortWait(long milliseconds) 857*cdf0e10cSrcweir { 858*cdf0e10cSrcweir try 859*cdf0e10cSrcweir { 860*cdf0e10cSrcweir Thread.sleep(milliseconds); 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir catch (InterruptedException e) 863*cdf0e10cSrcweir { 864*cdf0e10cSrcweir System.out.println("While waiting :" + e); 865*cdf0e10cSrcweir } 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir private void dbg(String message) 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir if (debug) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir log.println(utils.getDateTime() + "PH." + message); 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir public void noOutput() 877*cdf0e10cSrcweir { 878*cdf0e10cSrcweir bUseOutput = false; 879*cdf0e10cSrcweir } 880*cdf0e10cSrcweir // ------------------------------------------------------------------------- 881*cdf0e10cSrcweir class ProcessWatcher extends Thread 882*cdf0e10cSrcweir { 883*cdf0e10cSrcweir 884*cdf0e10cSrcweir private int m_nTimeoutInSec; 885*cdf0e10cSrcweir private String m_sProcessToStart; 886*cdf0e10cSrcweir private boolean m_bInterrupt; 887*cdf0e10cSrcweir 888*cdf0e10cSrcweir public ProcessWatcher(int _nTimeOut, String _sProcess) 889*cdf0e10cSrcweir { 890*cdf0e10cSrcweir m_nTimeoutInSec = _nTimeOut; 891*cdf0e10cSrcweir m_sProcessToStart = _sProcess; 892*cdf0e10cSrcweir m_bInterrupt = false; 893*cdf0e10cSrcweir } 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir /** 896*cdf0e10cSrcweir * returns true, if the thread should hold on 897*cdf0e10cSrcweir * @return 898*cdf0e10cSrcweir */ 899*cdf0e10cSrcweir public synchronized boolean isInHoldOn() 900*cdf0e10cSrcweir { 901*cdf0e10cSrcweir return m_bInterrupt; 902*cdf0e10cSrcweir } 903*cdf0e10cSrcweir /** 904*cdf0e10cSrcweir * Marks the thread to hold on, next time 905*cdf0e10cSrcweir * STUPID: The thread must poll this flag itself. 906*cdf0e10cSrcweir * 907*cdf0e10cSrcweir * Reason: interrupt() seems not to work as expected. 908*cdf0e10cSrcweir */ 909*cdf0e10cSrcweir public synchronized void holdOn() 910*cdf0e10cSrcweir { 911*cdf0e10cSrcweir m_bInterrupt = true; 912*cdf0e10cSrcweir interrupt(); 913*cdf0e10cSrcweir } 914*cdf0e10cSrcweir 915*cdf0e10cSrcweir public void run() 916*cdf0e10cSrcweir { 917*cdf0e10cSrcweir while (m_nTimeoutInSec > 0) 918*cdf0e10cSrcweir { 919*cdf0e10cSrcweir m_nTimeoutInSec--; 920*cdf0e10cSrcweir try 921*cdf0e10cSrcweir { 922*cdf0e10cSrcweir sleep(1000); 923*cdf0e10cSrcweir } 924*cdf0e10cSrcweir catch(java.lang.InterruptedException e) 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir // interrupt flag is set back to 'not interrupted' :-( 927*cdf0e10cSrcweir } 928*cdf0e10cSrcweir if (isInHoldOn()) 929*cdf0e10cSrcweir { 930*cdf0e10cSrcweir break; 931*cdf0e10cSrcweir } 932*cdf0e10cSrcweir } 933*cdf0e10cSrcweir if (m_nTimeoutInSec <= 0 && !isInHoldOn()) // not zero, so we are interrupted. 934*cdf0e10cSrcweir { 935*cdf0e10cSrcweir system(m_sProcessToStart); 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir /** 940*cdf0e10cSrcweir * Start an external Process 941*cdf0e10cSrcweir * @param _sProcess 942*cdf0e10cSrcweir */ 943*cdf0e10cSrcweir private void system(String _sProcess) 944*cdf0e10cSrcweir { 945*cdf0e10cSrcweir if (_sProcess == null) 946*cdf0e10cSrcweir { 947*cdf0e10cSrcweir return; 948*cdf0e10cSrcweir } 949*cdf0e10cSrcweir 950*cdf0e10cSrcweir try 951*cdf0e10cSrcweir { 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir // run a _sProcess command 954*cdf0e10cSrcweir // using the Runtime exec method: 955*cdf0e10cSrcweir Process p = Runtime.getRuntime().exec(_sProcess); 956*cdf0e10cSrcweir 957*cdf0e10cSrcweir BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 960*cdf0e10cSrcweir 961*cdf0e10cSrcweir // read the output from the command 962*cdf0e10cSrcweir String s; 963*cdf0e10cSrcweir while ((s = stdInput.readLine()) != null) 964*cdf0e10cSrcweir { 965*cdf0e10cSrcweir System.out.println("out:" + s); 966*cdf0e10cSrcweir } 967*cdf0e10cSrcweir 968*cdf0e10cSrcweir // read any errors from the attempted command 969*cdf0e10cSrcweir while ((s = stdError.readLine()) != null) 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir System.out.println("err:" + s); 972*cdf0e10cSrcweir } 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir } 975*cdf0e10cSrcweir catch (java.io.IOException e) 976*cdf0e10cSrcweir { 977*cdf0e10cSrcweir System.out.println("exception caught: "); 978*cdf0e10cSrcweir e.printStackTrace(); 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir } 982*cdf0e10cSrcweir } 983*cdf0e10cSrcweir 984*cdf0e10cSrcweir /** 985*cdf0e10cSrcweir * If the timeout only given by setProcessTimeout(int seconds) function is != 0, 986*cdf0e10cSrcweir * a extra thread is created and after time has run out, the ProcessKiller string 987*cdf0e10cSrcweir * given by function setProcessKiller(string) will execute. 988*cdf0e10cSrcweir * So it is possible to kill a running office after a given time of seconds. 989*cdf0e10cSrcweir */ 990*cdf0e10cSrcweir private void initializeProcessKiller() 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir if (m_nProcessTimeout != 0) 993*cdf0e10cSrcweir { 994*cdf0e10cSrcweir m_aWatcher = new ProcessWatcher(m_nProcessTimeout, m_sProcessKiller); 995*cdf0e10cSrcweir m_aWatcher.start(); 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir } 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir /** 1000*cdf0e10cSrcweir * to stop the extra thread, before he will kill a running office. This will stop the thread. 1001*cdf0e10cSrcweir */ 1002*cdf0e10cSrcweir public void stopWatcher() 1003*cdf0e10cSrcweir { 1004*cdf0e10cSrcweir if (m_aWatcher != null) 1005*cdf0e10cSrcweir { 1006*cdf0e10cSrcweir m_aWatcher.holdOn(); 1007*cdf0e10cSrcweir shortWait(5000); 1008*cdf0e10cSrcweir } 1009*cdf0e10cSrcweir } 1010*cdf0e10cSrcweir } 1011