123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /* ProcessBuilder.java - Represent spawned system process
- Copyright (C) 2005 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath 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 2, or (at your option)
- any later version.
- GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package java.lang;
- import java.io.File;
- import java.io.IOException;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Map;
- /**
- * <p>
- * This class is used to construct new operating system processes.
- * A <code>ProcessBuilder</code> instance basically represent a
- * template for a new process. Actual processes are generated from
- * this template via use of the <code>start()</code> method, which
- * may be invoked multiple times, with each invocation spawning a
- * new process with the current attributes of the
- * <code>ProcessBuilder</code> object. Each spawned process is
- * independent of the <code>ProcessBuilder</code> object, and is
- * unaffected by changes in its attributes.
- * </p>
- * <p>
- * The following attributes define a process:
- * </p>
- * <ul>
- * <li>The <emphasis>working directory</emphasis>; the activities of a
- * process begin with the current directory set to this. By default,
- * this is the working directory of the current process, as defined
- * by the <code>user.dir</code> property.</li>
- * <li>The <emphasis>command</emphasis> which invokes the process. This
- * usually consists of the name of the program binary followed by an
- * arbitrary number of arguments. For example, <code>find -type f</code>
- * invokes the <code>find</code> binary with the arguments "-type" and "f".
- * The command is provided a list, the elements of which are defined in a
- * system dependent manner; the layout is affected by expected operating
- * system conventions. A common method is to split the command on each
- * space within the string. Thus, <code>find -type f</code> forms a
- * three element list. However, in some cases, the expectation is that
- * this split is performed by the program itself; thus, the list consists
- * of only two elements (the program name and its arguments).</li>
- * <li>The <emphasis>environment map</emphasis>, which links environment
- * variables to their corresponding values. The initial contents of the map
- * are the current environment values i.e. it contains the contents of the
- * map returned by <code>System.getenv()</code>.</li>
- * <li>The <emphasis>redirection flag</emphasis>, which specifies whether
- * or not the contents of the error stream should be redirected to standard
- * output. By default, this is false, and there are two output streams, one
- * for normal data ({@link Process#getOutputStream()}) and one for error data
- * ({@link Process#getErrorStream()}). When set to true, the two are merged,
- * which simplifies the interleaving of the two streams. Data is read using
- * the stream returned by {@link Process#getOutputStream()}, and the
- * stream returned by {@link Process#getErrorStream()} throws an immediate
- * end-of-file exception.</li>
- * </ul>
- * <p>
- * All checks on attribute validity are delayed until <code>start()</code>
- * is called. <code>ProcessBuilder</code> objects are <strong>not
- * synchronized</strong>; the user must provide external synchronization
- * where multiple threads may interact with the same
- * <code>ProcessBuilder</code> object.
- * </p>
- *
- * @author Tom Tromey (tromey@redhat.com)
- * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
- * @see Process
- * @see System#getenv()
- * @since 1.5
- */
- public final class ProcessBuilder
- {
- /**
- * The working directory of the process.
- */
- private File directory = new File(System.getProperty("user.dir"));
- /**
- * The command line syntax for invoking the process.
- */
- private List<String> command;
- /**
- * The mapping of environment variables to values.
- */
- private Map<String, String> environment =
- new System.EnvironmentMap(System.getenv());
- /**
- * A flag indicating whether to redirect the error stream to standard
- * output.
- */
- private boolean redirect = false;
- /**
- * Constructs a new <code>ProcessBuilder</code> with the specified
- * command being used to invoke the process. The list is used directly;
- * external changes are reflected in the <code>ProcessBuilder</code>.
- *
- * @param command the name of the program followed by its arguments.
- */
- public ProcessBuilder(List<String> command)
- {
- this.command = command;
- }
- /**
- * Constructs a new <code>ProcessBuilder</code> with the specified
- * command being used to invoke the process. This constructor
- * simplifies creating a new <code>ProcessBuilder</code> by
- * converting the provided series of constructor arguments into a
- * list of command-line arguments.
- *
- * @param command the name of the program followed by its arguments.
- */
- public ProcessBuilder(String... command)
- {
- this.command = Arrays.asList(command);
- }
- /**
- * Returns the current command line, used to invoke the process.
- * The return value is simply a reference to the list of command
- * line arguments used by the <code>ProcessBuilder</code> object;
- * any changes made to it will be reflected in the operation of
- * the <code>ProcessBuilder</code>.
- *
- * @return the list of command-line arguments.
- */
- public List<String> command()
- {
- return command;
- }
- /**
- * Sets the command-line arguments to those specified. The list is
- * used directly; external changes are reflected in the
- * <code>ProcessBuilder</code>.
- *
- * @param command the name of the program followed by its arguments.
- * @return a reference to this process builder.
- */
- public ProcessBuilder command(List<String> command)
- {
- this.command = command;
- return this;
- }
- /**
- * Sets the command-line arguments to those specified.
- * This simplifies modifying the arguments by converting
- * the provided series of constructor arguments into a
- * list of command-line arguments.
- *
- * @param command the name of the program followed by its arguments.
- * @return a reference to this process builder.
- */
- public ProcessBuilder command(String... command)
- {
- this.command = Arrays.asList(command);
- return this;
- }
- /**
- * Returns the working directory of the process. The
- * returned value may be <code>null</code>; this
- * indicates that the default behaviour of using the
- * working directory of the current process should
- * be adopted.
- *
- * @return the working directory.
- */
- public File directory()
- {
- return directory;
- }
- /**
- * Sets the working directory to that specified.
- * The supplied argument may be <code>null</code>,
- * which indicates the default value should be used.
- * The default is the working directory of the current
- * process.
- *
- * @param directory the new working directory.
- * @return a reference to this process builder.
- */
- public ProcessBuilder directory(File directory)
- {
- this.directory = directory;
- return this;
- }
- /**
- * <p>
- * Returns the system environment variables of the process.
- * If the underlying system does not support environment variables,
- * an empty map is returned.
- * </p>
- * <p>
- * The returned map does not accept queries using
- * null keys or values, or those of a type other than
- * <code>String</code>. Attempts to pass in a null value will
- * throw a <code>NullPointerException</code>. Types other than
- * <code>String</code> throw a <code>ClassCastException</code>.
- * </p>
- * <p>
- * As the returned map is generated using data from the underlying
- * platform, it may not comply with the <code>equals()</code>
- * and <code>hashCode()</code> contracts. It is also likely that
- * the keys of this map will be case-sensitive.
- * </p>
- * <p>
- * Modification of the map is reliant on the underlying platform;
- * some may not allow any changes to the environment variables or
- * may prevent certain values being used. Attempts to do so will
- * throw an <code>UnsupportedOperationException</code> or
- * <code>IllegalArgumentException</code>, respectively.
- * </p>
- * <p>
- * Use of this method may require a security check for the
- * RuntimePermission "getenv.*".
- * </p>
- *
- * @return a map of the system environment variables for the process.
- * @throws SecurityException if the checkPermission method of
- * an installed security manager prevents access to
- * the system environment variables.
- * @since 1.5
- */
- public Map<String, String> environment()
- {
- return environment;
- }
- /**
- * Returns true if the output stream and error stream of the
- * process will be merged to form one composite stream. The
- * default return value is <code>false</code>.
- *
- * @return true if the output stream and error stream are to
- * be merged.
- */
- public boolean redirectErrorStream()
- {
- return redirect;
- }
- /**
- * Sets the error stream redirection flag. If set, the output
- * and error streams are merged to form one composite stream.
- *
- * @param redirect the new value of the redirection flag.
- * @return a reference to this process builder.
- */
- public ProcessBuilder redirectErrorStream(boolean redirect)
- {
- this.redirect = redirect;
- return this;
- }
- /**
- * <p>
- * Starts execution of a new process, based on the attributes of
- * this <code>ProcessBuilder</code> object. This is the point
- * at which the command-line arguments are checked. The list
- * must be non-empty and contain only non-null string objects.
- * The other attributes have default values which are used in
- * cases where their values are not explicitly specified.
- * </p>
- * <p>
- * If a security manager is in place, then the
- * {@link SecurityManager#checkExec()} method is called to
- * ensure that permission is given to execute the process.
- * </p>
- * <p>
- * The execution of the process is system-dependent. Various
- * exceptions may result, due to problems at the operating system
- * level. These are all returned as a form of {@link IOException}.
- * </p>
- *
- * @return a <code>Process</code> object, representing the spawned
- * subprocess.
- * @throws IOException if a problem occurs with executing the process
- * at the operating system level.
- * @throws IndexOutOfBoundsException if the command to execute is
- * actually an empty list.
- * @throws NullPointerException if the command to execute is null
- * or the list contains null elements.
- * @throws SecurityException if a security manager exists and prevents
- * execution of the subprocess.
- */
- public Process start() throws IOException
- {
- SecurityManager sm = SecurityManager.current; // Be thread-safe!
- if (sm != null)
- sm.checkExec(command.get(0));
- return VMProcess.exec(command, environment, directory, redirect);
- }
- }
|