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);
 | |
|   }
 | |
| }
 |