/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.process; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mucommander.commons.runtime.JavaVersion; /** * Process running on the local computer. * @author Nicolas Rinaudo */ class LocalProcess extends AbstractProcess { private static final Logger LOGGER = LoggerFactory.getLogger(LocalProcess.class); // - Instance fields ------------------------------------------------------- // ------------------------------------------------------------------------- /** Underlying system process. */ private Process process; // - Initialisation -------------------------------------------------------- // ------------------------------------------------------------------------- /** * Creates a new local process running the specified command. * @param tokens command to run and its parameters. * @param dir directory in which to start the command. * @throws IOException if the process could not be created. */ public LocalProcess(String[] tokens, File dir) throws IOException { ProcessBuilder pb = new ProcessBuilder(tokens); // Set the process' working directory pb.directory(dir); // Merge the process' stdout and stderr pb.redirectErrorStream(true); process = pb.start(); // Safeguard: makes sure that an exception is raised if the process could not be created. // This might not be strictly necessary, but the Runtime.exec documentation is not very precise // on what happens in case of an error. if(process == null) throw new IOException(); } // - Implementation -------------------------------------------------------- // ------------------------------------------------------------------------- /** * Returns <code>true</code> if the current JRE version supports merged <code>java.lang.Process</code> streams. * @return <code>true</code> if the current JRE version supports merged <code>java.lang.Process</code> streams, <code>false</code> otherwise. */ @Override public boolean usesMergedStreams() {return JavaVersion.JAVA_1_5.isCurrentOrHigher();} /** * Waits for the process to die. * @return the process' exit code. * @throws InterruptedException if the thread was interrupted while waiting on the process to die. */ @Override public int waitFor() throws InterruptedException {return process.waitFor();} /** * Destroys the process. */ @Override protected void destroyProcess() {process.destroy();} /** * Returns the process' exit value. * @return the process' exit value. */ @Override public int exitValue() {return process.exitValue();} /** * Returns the process' output stream. * @return the process' output stream. */ @Override public OutputStream getOutputStream() {return process.getOutputStream();} /** * Returns the process' error stream. * <p> * On Java 1.5 or higher, this will throw an <code>java.io.IOException</code>, as we're using * merged output streams. Developers should protect themselves against this by checking * {@link #usesMergedStreams()} before accessing streams. * </p> * @return the process' error stream. * @throws IOException if this process is using merged streams. */ @Override public InputStream getErrorStream() throws IOException { if(usesMergedStreams()) { LOGGER.debug("Tried to access the error stream of a merged streams process."); throw new IOException(); } return process.getErrorStream(); } /** * Returns the process' input stream. * @return the process' input stream. */ @Override public InputStream getInputStream() {return process.getInputStream();} }