/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2008 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: ProcessExecutor.java,v 1.1 2008/11/22 02:19:58 ak138937 Exp $ * */ package com.sun.identity.diagnostic.base.core.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; public class ProcessExecutor { private static final String DEFAULT_STDOUT_FILE = "stdout"; private static final String DEFAULT_STDERR_FILE = "stderr"; private String stdoutFileName = DEFAULT_STDOUT_FILE; private String stderrFileName = DEFAULT_STDERR_FILE; private boolean canDeleteOutputFile = true; private boolean canDeleteErrorFile = true; private static final long DEFAULT_TIMEOUT_SEC = 600; private static final String NEWLINE = System.getProperty("line.separator"); private long mTimeoutMilliseconds = 0; private String[] mCmdStrings = null; private File mOutFile = null; private File mErrFile = null; private String[] mInputLines = null; private int mExitValue = -1; public static final long kSleepTime = 500; /** * Creates new ProcessExecutor */ public ProcessExecutor(String[] cmd) { this(cmd, DEFAULT_TIMEOUT_SEC, null); } /** * Creates new ProcessExecutor */ public ProcessExecutor(String[] cmd, String[] inputLines) { this(cmd, DEFAULT_TIMEOUT_SEC, inputLines); } /** * Creates new ProcessExecutor */ public ProcessExecutor(String[] cmd, long timeoutSeconds) { this(cmd, timeoutSeconds, null); } /** * Creates a new ProcessExecutor that executes the given * command. * * @param cmd String that has command name and its command line arguments * @param timeoutSeconds long integer timeout to be applied in seconds. * After this time if the process to execute does not end, it will * be destroyed. */ public ProcessExecutor( String[] cmd, long timeoutSeconds, String[] inputLines ) { mCmdStrings = cmd; mInputLines = inputLines; char fwdSlashChar = '/'; char backSlashChar = '\\'; for(int i=0; i= mTimeoutMilliseconds; shouldBeDone = timeoutReached || isSubProcessFinished; } if (!isSubProcessFinished) { subProcess.destroy(); mExitValue = -255; } else { mExitValue = subProcess.exitValue(); if (mExitValue != 0) { /* read the error message from error file */ final String errorMessage = getFileBuffer(mErrFile); if (!exceptionOnNonZeroExitVal) { return cmdOp; } } if (bReturnOutputLines) { //inputStream = getRedirectedProcessOutputHandle(); return cmdOp; } else { return null; } } } catch(SecurityException se) { return null; } catch(IOException ioe) { return null; } finally { deleteTempFiles(); } return cmdOp; } /** * Executes the command. * * @return An array containing the output of the command */ public String[] execute( boolean bReturnOutputLines, boolean exceptionOnNonZeroExitVal ) { init(); try { Process subProcess = Runtime.getRuntime().exec(mCmdStrings); InputStream inputStream = null; if (mInputLines != null) addInputLinesToProcessInput(subProcess); if (!bReturnOutputLines) { redirectProcessOutput(subProcess); } else { inputStream = subProcess.getInputStream(); } redirectProcessError(subProcess); long timeBefore = System.currentTimeMillis(); boolean timeoutReached = false; boolean isSubProcessFinished = false; boolean shouldBeDone = false; String[] cmdOp = null; if (bReturnOutputLines) { cmdOp = getInputStrings(inputStream); } while (! shouldBeDone) { try { mExitValue = subProcess.exitValue(); isSubProcessFinished = true; break; } catch(IllegalThreadStateException itse) { isSubProcessFinished = false; sleep(kSleepTime); //ignore exception } long timeAfter = System.currentTimeMillis(); timeoutReached = (timeAfter - timeBefore) >= mTimeoutMilliseconds; shouldBeDone = timeoutReached || isSubProcessFinished; } if (!isSubProcessFinished) { subProcess.destroy(); mExitValue = -255; return null; } else { mExitValue = subProcess.exitValue(); if (mExitValue != 0) { /* read the error message from error file */ final String errorMessage = getFileBuffer(mErrFile); if(!exceptionOnNonZeroExitVal){ return cmdOp; } } if (bReturnOutputLines) { return cmdOp; } else { return null; } } } catch(SecurityException se) { return null; } catch(IOException ioe) { return null; } finally { deleteTempFiles(); } } public String[] execute(boolean bReturnOutputLines) { return execute(bReturnOutputLines,true); } private void addInputLinesToProcessInput(Process subProcess) { if (mInputLines == null) { return; } PrintWriter out = null; try { out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(subProcess.getOutputStream()))); for (int i=0; i