mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			338 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
/* 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);
 | 
						|
  }
 | 
						|
}
 |