1 /*
   2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import java.lang.invoke.MethodHandles;
  29 import java.lang.invoke.VarHandle;
  30 import java.io.File;
  31 import java.io.FileDescriptor;
  32 import java.io.IOException;
  33 import java.io.InputStream;
  34 import java.io.OutputStream;
  35 import java.util.Arrays;
  36 import java.util.ArrayList;
  37 import java.util.List;
  38 import java.util.Map;
  39 import sun.security.action.GetPropertyAction;
  40 
  41 /**
  42  * This class is used to create operating system processes.
  43  *
  44  * <p>Each {@code ProcessBuilder} instance manages a collection
  45  * of process attributes.  The {@link #start()} method creates a new
  46  * {@link Process} instance with those attributes.  The {@link
  47  * #start()} method can be invoked repeatedly from the same instance
  48  * to create new subprocesses with identical or related attributes.
  49  * <p>
  50  * The {@link #startPipeline startPipeline} method can be invoked to create
  51  * a pipeline of new processes that send the output of each process
  52  * directly to the next process.  Each process has the attributes of
  53  * its respective ProcessBuilder.
  54  *
  55  * <p>Each process builder manages these process attributes:
  56  *
  57  * <ul>
  58  *
  59  * <li>a <i>command</i>, a list of strings which signifies the
  60  * external program file to be invoked and its arguments, if any.
  61  * Which string lists represent a valid operating system command is
  62  * system-dependent.  For example, it is common for each conceptual
  63  * argument to be an element in this list, but there are operating
  64  * systems where programs are expected to tokenize command line
  65  * strings themselves - on such a system a Java implementation might
  66  * require commands to contain exactly two elements.
  67  *
  68  * <li>an <i>environment</i>, which is a system-dependent mapping from
  69  * <i>variables</i> to <i>values</i>.  The initial value is a copy of
  70  * the environment of the current process (see {@link System#getenv()}).
  71  *
  72  * <li>a <i>working directory</i>.  The default value is the current
  73  * working directory of the current process, usually the directory
  74  * named by the system property {@code user.dir}.
  75  *
  76  * <li><a id="redirect-input">a source of <i>standard input</i></a>.
  77  * By default, the subprocess reads input from a pipe.  Java code
  78  * can access this pipe via the output stream returned by
  79  * {@link Process#getOutputStream()}.  However, standard input may
  80  * be redirected to another source using
  81  * {@link #redirectInput(Redirect) redirectInput}.
  82  * In this case, {@link Process#getOutputStream()} will return a
  83  * <i>null output stream</i>, for which:
  84  *
  85  * <ul>
  86  * <li>the {@link OutputStream#write(int) write} methods always
  87  * throw {@code IOException}
  88  * <li>the {@link OutputStream#close() close} method does nothing
  89  * </ul>
  90  *
  91  * <li><a id="redirect-output">a destination for <i>standard output</i>
  92  * and <i>standard error</i></a>.  By default, the subprocess writes standard
  93  * output and standard error to pipes.  Java code can access these pipes
  94  * via the input streams returned by {@link Process#getInputStream()} and
  95  * {@link Process#getErrorStream()}.  However, standard output and
  96  * standard error may be redirected to other destinations using
  97  * {@link #redirectOutput(Redirect) redirectOutput} and
  98  * {@link #redirectError(Redirect) redirectError}.
  99  * In this case, {@link Process#getInputStream()} and/or
 100  * {@link Process#getErrorStream()} will return a <i>null input
 101  * stream</i>, for which:
 102  *
 103  * <ul>
 104  * <li>the {@link InputStream#read() read} methods always return
 105  * {@code -1}
 106  * <li>the {@link InputStream#available() available} method always returns
 107  * {@code 0}
 108  * <li>the {@link InputStream#close() close} method does nothing
 109  * </ul>
 110  *
 111  * <li>a <i>redirectErrorStream</i> property.  Initially, this property
 112  * is {@code false}, meaning that the standard output and error
 113  * output of a subprocess are sent to two separate streams, which can
 114  * be accessed using the {@link Process#getInputStream()} and {@link
 115  * Process#getErrorStream()} methods.
 116  *
 117  * <p>If the value is set to {@code true}, then:
 118  *
 119  * <ul>
 120  * <li>standard error is merged with the standard output and always sent
 121  * to the same destination (this makes it easier to correlate error
 122  * messages with the corresponding output)
 123  * <li>the common destination of standard error and standard output can be
 124  * redirected using
 125  * {@link #redirectOutput(Redirect) redirectOutput}
 126  * <li>any redirection set by the
 127  * {@link #redirectError(Redirect) redirectError}
 128  * method is ignored when creating a subprocess
 129  * <li>the stream returned from {@link Process#getErrorStream()} will
 130  * always be a <a href="#redirect-output">null input stream</a>
 131  * </ul>
 132  *
 133  * </ul>
 134  *
 135  * <p>Modifying a process builder's attributes will affect processes
 136  * subsequently started by that object's {@link #start()} method, but
 137  * will never affect previously started processes or the Java process
 138  * itself.
 139  *
 140  * <p>Most error checking is performed by the {@link #start()} method.
 141  * It is possible to modify the state of an object so that {@link
 142  * #start()} will fail.  For example, setting the command attribute to
 143  * an empty list will not throw an exception unless {@link #start()}
 144  * is invoked.
 145  *
 146  * <p><strong>Note that this class is not synchronized.</strong>
 147  * If multiple threads access a {@code ProcessBuilder} instance
 148  * concurrently, and at least one of the threads modifies one of the
 149  * attributes structurally, it <i>must</i> be synchronized externally.
 150  *
 151  * <p>Starting a new process which uses the default working directory
 152  * and environment is easy:
 153  *
 154  * <pre> {@code
 155  * Process p = new ProcessBuilder("myCommand", "myArg").start();
 156  * }</pre>
 157  *
 158  * <p>Here is an example that starts a process with a modified working
 159  * directory and environment, and redirects standard output and error
 160  * to be appended to a log file:
 161  *
 162  * <pre> {@code
 163  * ProcessBuilder pb =
 164  *   new ProcessBuilder("myCommand", "myArg1", "myArg2");
 165  * Map<String, String> env = pb.environment();
 166  * env.put("VAR1", "myValue");
 167  * env.remove("OTHERVAR");
 168  * env.put("VAR2", env.get("VAR1") + "suffix");
 169  * pb.directory(new File("myDir"));
 170  * File log = new File("log");
 171  * pb.redirectErrorStream(true);
 172  * pb.redirectOutput(Redirect.appendTo(log));
 173  * Process p = pb.start();
 174  * assert pb.redirectInput() == Redirect.PIPE;
 175  * assert pb.redirectOutput().file() == log;
 176  * assert p.getInputStream().read() == -1;
 177  * }</pre>
 178  *
 179  * <p>To start a process with an explicit set of environment
 180  * variables, first call {@link java.util.Map#clear() Map.clear()}
 181  * before adding environment variables.
 182  *
 183  * <p>
 184  * Unless otherwise noted, passing a {@code null} argument to a constructor
 185  * or method in this class will cause a {@link NullPointerException} to be
 186  * thrown.
 187  *
 188  * @author Martin Buchholz
 189  * @since 1.5
 190  */
 191 
 192 public final class ProcessBuilder
 193 {
 194     private List<String> command;
 195     private File directory;
 196     private Map<String,String> environment;
 197     private boolean redirectErrorStream;
 198     private Redirect[] redirects;
 199 
 200     /**
 201      * Constructs a process builder with the specified operating
 202      * system program and arguments.  This constructor does <i>not</i>
 203      * make a copy of the {@code command} list.  Subsequent
 204      * updates to the list will be reflected in the state of the
 205      * process builder.  It is not checked whether
 206      * {@code command} corresponds to a valid operating system
 207      * command.
 208      *
 209      * @param  command the list containing the program and its arguments
 210      */
 211     public ProcessBuilder(List<String> command) {
 212         if (command == null)
 213             throw new NullPointerException();
 214         COMMAND.setRelease(this, command);
 215     }
 216 
 217     /**
 218      * Constructs a process builder with the specified operating
 219      * system program and arguments.  This is a convenience
 220      * constructor that sets the process builder's command to a string
 221      * list containing the same strings as the {@code command}
 222      * array, in the same order.  It is not checked whether
 223      * {@code command} corresponds to a valid operating system
 224      * command.
 225      *
 226      * @param command a string array containing the program and its arguments
 227      */
 228     public ProcessBuilder(String... command) {
 229         List<String> commandList = new ArrayList<>(command.length);
 230         for (String arg : command)
 231             commandList.add(arg);
 232         COMMAND.setRelease(this, commandList);
 233     }
 234 
 235     /**
 236      * Sets this process builder's operating system program and
 237      * arguments.  This method does <i>not</i> make a copy of the
 238      * {@code command} list.  Subsequent updates to the list will
 239      * be reflected in the state of the process builder.  It is not
 240      * checked whether {@code command} corresponds to a valid
 241      * operating system command.
 242      *
 243      * @param  command the list containing the program and its arguments
 244      * @return this process builder
 245      */
 246     public ProcessBuilder command(List<String> command) {
 247         if (command == null)
 248             throw new NullPointerException();
 249         COMMAND.setRelease(this, command);
 250         return this;
 251     }
 252 
 253     /**
 254      * Sets this process builder's operating system program and
 255      * arguments.  This is a convenience method that sets the command
 256      * to a string list containing the same strings as the
 257      * {@code command} array, in the same order.  It is not
 258      * checked whether {@code command} corresponds to a valid
 259      * operating system command.
 260      *
 261      * @param  command a string array containing the program and its arguments
 262      * @return this process builder
 263      */
 264     public ProcessBuilder command(String... command) {
 265         this.command = new ArrayList<>(command.length);
 266         for (String arg : command)
 267             this.command.add(arg);
 268         return this;
 269     }
 270 
 271     /**
 272      * Returns this process builder's operating system program and
 273      * arguments.  The returned list is <i>not</i> a copy.  Subsequent
 274      * updates to the list will be reflected in the state of this
 275      * process builder.
 276      *
 277      * @return this process builder's program and its arguments
 278      */
 279     public List<String> command() {
 280         return (List<String>) COMMAND.getAcquire(this);
 281     }
 282 
 283     /**
 284      * Returns a string map view of this process builder's environment.
 285      *
 286      * Whenever a process builder is created, the environment is
 287      * initialized to a copy of the current process environment (see
 288      * {@link System#getenv()}).  Subprocesses subsequently started by
 289      * this object's {@link #start()} method will use this map as
 290      * their environment.
 291      *
 292      * <p>The returned object may be modified using ordinary {@link
 293      * java.util.Map Map} operations.  These modifications will be
 294      * visible to subprocesses started via the {@link #start()}
 295      * method.  Two {@code ProcessBuilder} instances always
 296      * contain independent process environments, so changes to the
 297      * returned map will never be reflected in any other
 298      * {@code ProcessBuilder} instance or the values returned by
 299      * {@link System#getenv System.getenv}.
 300      *
 301      * <p>If the system does not support environment variables, an
 302      * empty map is returned.
 303      *
 304      * <p>The returned map does not permit null keys or values.
 305      * Attempting to insert or query the presence of a null key or
 306      * value will throw a {@link NullPointerException}.
 307      * Attempting to query the presence of a key or value which is not
 308      * of type {@link String} will throw a {@link ClassCastException}.
 309      *
 310      * <p>The behavior of the returned map is system-dependent.  A
 311      * system may not allow modifications to environment variables or
 312      * may forbid certain variable names or values.  For this reason,
 313      * attempts to modify the map may fail with
 314      * {@link UnsupportedOperationException} or
 315      * {@link IllegalArgumentException}
 316      * if the modification is not permitted by the operating system.
 317      *
 318      * <p>Since the external format of environment variable names and
 319      * values is system-dependent, there may not be a one-to-one
 320      * mapping between them and Java's Unicode strings.  Nevertheless,
 321      * the map is implemented in such a way that environment variables
 322      * which are not modified by Java code will have an unmodified
 323      * native representation in the subprocess.
 324      *
 325      * <p>The returned map and its collection views may not obey the
 326      * general contract of the {@link Object#equals} and
 327      * {@link Object#hashCode} methods.
 328      *
 329      * <p>The returned map is typically case-sensitive on all platforms.
 330      *
 331      * <p>If a security manager exists, its
 332      * {@link SecurityManager#checkPermission checkPermission} method
 333      * is called with a
 334      * {@link RuntimePermission}{@code ("getenv.*")} permission.
 335      * This may result in a {@link SecurityException} being thrown.
 336      *
 337      * <p>When passing information to a Java subprocess,
 338      * <a href=System.html#EnvironmentVSSystemProperties>system properties</a>
 339      * are generally preferred over environment variables.
 340      *
 341      * @return this process builder's environment
 342      *
 343      * @throws SecurityException
 344      *         if a security manager exists and its
 345      *         {@link SecurityManager#checkPermission checkPermission}
 346      *         method doesn't allow access to the process environment
 347      *
 348      * @see    Runtime#exec(String[],String[],java.io.File)
 349      * @see    System#getenv()
 350      */
 351     public Map<String,String> environment() {
 352         SecurityManager security = System.getSecurityManager();
 353         if (security != null)
 354             security.checkPermission(new RuntimePermission("getenv.*"));
 355 
 356         // Multiple threads may call this method without synchronization
 357         for (;;) {
 358             Map<String,String> environment = (Map<String,String>)
 359                 ENVIRONMENT.getAcquire(this);
 360             if (environment != null)
 361                 return environment;
 362             ENVIRONMENT.compareAndSet(this, null,
 363                                       ProcessEnvironment.environment());
 364         }
 365     }
 366 
 367     // Only for use by Runtime.exec(...envp...)
 368     ProcessBuilder environment(String[] envp) {
 369         assert environment == null;
 370         if (envp != null) {
 371             environment = ProcessEnvironment.emptyEnvironment(envp.length);
 372             assert environment != null;
 373 
 374             for (String envstring : envp) {
 375                 // Before 1.5, we blindly passed invalid envstrings
 376                 // to the child process.
 377                 // We would like to throw an exception, but do not,
 378                 // for compatibility with old broken code.
 379 
 380                 // Silently discard any trailing junk.
 381                 if (envstring.indexOf((int) '\u0000') != -1)
 382                     envstring = envstring.replaceFirst("\u0000.*", "");
 383 
 384                 int eqlsign =
 385                     envstring.indexOf('=', ProcessEnvironment.MIN_NAME_LENGTH);
 386                 // Silently ignore envstrings lacking the required `='.
 387                 if (eqlsign != -1)
 388                     environment.put(envstring.substring(0,eqlsign),
 389                                     envstring.substring(eqlsign+1));
 390             }
 391         }
 392         return this;
 393     }
 394 
 395     /**
 396      * Returns this process builder's working directory.
 397      *
 398      * Subprocesses subsequently started by this object's {@link
 399      * #start()} method will use this as their working directory.
 400      * The returned value may be {@code null} -- this means to use
 401      * the working directory of the current Java process, usually the
 402      * directory named by the system property {@code user.dir},
 403      * as the working directory of the child process.
 404      *
 405      * @return this process builder's working directory
 406      */
 407     public File directory() {
 408         return directory;
 409     }
 410 
 411     /**
 412      * Sets this process builder's working directory.
 413      *
 414      * Subprocesses subsequently started by this object's {@link
 415      * #start()} method will use this as their working directory.
 416      * The argument may be {@code null} -- this means to use the
 417      * working directory of the current Java process, usually the
 418      * directory named by the system property {@code user.dir},
 419      * as the working directory of the child process.
 420      *
 421      * @param  directory the new working directory
 422      * @return this process builder
 423      */
 424     public ProcessBuilder directory(File directory) {
 425         this.directory = directory;
 426         return this;
 427     }
 428 
 429     // ---------------- I/O Redirection ----------------
 430 
 431     /**
 432      * Implements a <a href="#redirect-output">null input stream</a>.
 433      */
 434     static class NullInputStream extends InputStream {
 435         static final NullInputStream INSTANCE = new NullInputStream();
 436         private NullInputStream() {}
 437         public int read()      { return -1; }
 438         public int available() { return 0; }
 439     }
 440 
 441     /**
 442      * Implements a <a href="#redirect-input">null output stream</a>.
 443      */
 444     static class NullOutputStream extends OutputStream {
 445         static final NullOutputStream INSTANCE = new NullOutputStream();
 446         private NullOutputStream() {}
 447         public void write(int b) throws IOException {
 448             throw new IOException("Stream closed");
 449         }
 450     }
 451 
 452     /**
 453      * Represents a source of subprocess input or a destination of
 454      * subprocess output.
 455      *
 456      * Each {@code Redirect} instance is one of the following:
 457      *
 458      * <ul>
 459      * <li>the special value {@link #PIPE Redirect.PIPE}
 460      * <li>the special value {@link #INHERIT Redirect.INHERIT}
 461      * <li>the special value {@link #DISCARD Redirect.DISCARD}
 462      * <li>a redirection to read from a file, created by an invocation of
 463      *     {@link Redirect#from Redirect.from(File)}
 464      * <li>a redirection to write to a file,  created by an invocation of
 465      *     {@link Redirect#to Redirect.to(File)}
 466      * <li>a redirection to append to a file, created by an invocation of
 467      *     {@link Redirect#appendTo Redirect.appendTo(File)}
 468      * </ul>
 469      *
 470      * <p>Each of the above categories has an associated unique
 471      * {@link Type Type}.
 472      *
 473      * @since 1.7
 474      */
 475     public abstract static class Redirect {
 476         private static final File NULL_FILE = new File(
 477                 (GetPropertyAction.privilegedGetProperty("os.name")
 478                         .startsWith("Windows") ? "NUL" : "/dev/null")
 479         );
 480 
 481         /**
 482          * The type of a {@link Redirect}.
 483          */
 484         public enum Type {
 485             /**
 486              * The type of {@link Redirect#PIPE Redirect.PIPE}.
 487              */
 488             PIPE,
 489 
 490             /**
 491              * The type of {@link Redirect#INHERIT Redirect.INHERIT}.
 492              */
 493             INHERIT,
 494 
 495             /**
 496              * The type of redirects returned from
 497              * {@link Redirect#from Redirect.from(File)}.
 498              */
 499             READ,
 500 
 501             /**
 502              * The type of redirects returned from
 503              * {@link Redirect#to Redirect.to(File)}.
 504              */
 505             WRITE,
 506 
 507             /**
 508              * The type of redirects returned from
 509              * {@link Redirect#appendTo Redirect.appendTo(File)}.
 510              */
 511             APPEND
 512         };
 513 
 514         /**
 515          * Returns the type of this {@code Redirect}.
 516          * @return the type of this {@code Redirect}
 517          */
 518         public abstract Type type();
 519 
 520         /**
 521          * Indicates that subprocess I/O will be connected to the
 522          * current Java process over a pipe.
 523          *
 524          * This is the default handling of subprocess standard I/O.
 525          *
 526          * <p>It will always be true that
 527          *  <pre> {@code
 528          * Redirect.PIPE.file() == null &&
 529          * Redirect.PIPE.type() == Redirect.Type.PIPE
 530          * }</pre>
 531          */
 532         public static final Redirect PIPE = new Redirect() {
 533                 public Type type() { return Type.PIPE; }
 534                 public String toString() { return type().toString(); }};
 535 
 536         /**
 537          * Indicates that subprocess I/O source or destination will be the
 538          * same as those of the current process.  This is the normal
 539          * behavior of most operating system command interpreters (shells).
 540          *
 541          * <p>It will always be true that
 542          *  <pre> {@code
 543          * Redirect.INHERIT.file() == null &&
 544          * Redirect.INHERIT.type() == Redirect.Type.INHERIT
 545          * }</pre>
 546          */
 547         public static final Redirect INHERIT = new Redirect() {
 548                 public Type type() { return Type.INHERIT; }
 549                 public String toString() { return type().toString(); }};
 550 
 551 
 552         /**
 553          * Indicates that subprocess output will be discarded.
 554          * A typical implementation discards the output by writing to
 555          * an operating system specific "null file".
 556          *
 557          * <p>It will always be true that
 558          * <pre> {@code
 559          * Redirect.DISCARD.file() is the filename appropriate for the operating system
 560          * and may be null &&
 561          * Redirect.DISCARD.type() == Redirect.Type.WRITE
 562          * }</pre>
 563          * @since 9
 564          */
 565         public static final Redirect DISCARD = new Redirect() {
 566                 public Type type() { return Type.WRITE; }
 567                 public String toString() { return type().toString(); }
 568                 public File file() { return NULL_FILE; }
 569                 boolean append() { return false; }
 570         };
 571 
 572         /**
 573          * Returns the {@link File} source or destination associated
 574          * with this redirect, or {@code null} if there is no such file.
 575          *
 576          * @return the file associated with this redirect,
 577          *         or {@code null} if there is no such file
 578          */
 579         public File file() { return null; }
 580 
 581         /**
 582          * When redirected to a destination file, indicates if the output
 583          * is to be written to the end of the file.
 584          */
 585         boolean append() {
 586             throw new UnsupportedOperationException();
 587         }
 588 
 589         /**
 590          * Returns a redirect to read from the specified file.
 591          *
 592          * <p>It will always be true that
 593          *  <pre> {@code
 594          * Redirect.from(file).file() == file &&
 595          * Redirect.from(file).type() == Redirect.Type.READ
 596          * }</pre>
 597          *
 598          * @param file The {@code File} for the {@code Redirect}.
 599          * @return a redirect to read from the specified file
 600          */
 601         public static Redirect from(final File file) {
 602             if (file == null)
 603                 throw new NullPointerException();
 604             return new Redirect() {
 605                     public Type type() { return Type.READ; }
 606                     public File file() { return file; }
 607                     public String toString() {
 608                         return "redirect to read from file \"" + file + "\"";
 609                     }
 610                 };
 611         }
 612 
 613         /**
 614          * Returns a redirect to write to the specified file.
 615          * If the specified file exists when the subprocess is started,
 616          * its previous contents will be discarded.
 617          *
 618          * <p>It will always be true that
 619          *  <pre> {@code
 620          * Redirect.to(file).file() == file &&
 621          * Redirect.to(file).type() == Redirect.Type.WRITE
 622          * }</pre>
 623          *
 624          * @param file The {@code File} for the {@code Redirect}.
 625          * @return a redirect to write to the specified file
 626          */
 627         public static Redirect to(final File file) {
 628             if (file == null)
 629                 throw new NullPointerException();
 630             return new Redirect() {
 631                     public Type type() { return Type.WRITE; }
 632                     public File file() { return file; }
 633                     public String toString() {
 634                         return "redirect to write to file \"" + file + "\"";
 635                     }
 636                     boolean append() { return false; }
 637                 };
 638         }
 639 
 640         /**
 641          * Returns a redirect to append to the specified file.
 642          * Each write operation first advances the position to the
 643          * end of the file and then writes the requested data.
 644          * Whether the advancement of the position and the writing
 645          * of the data are done in a single atomic operation is
 646          * system-dependent and therefore unspecified.
 647          *
 648          * <p>It will always be true that
 649          *  <pre> {@code
 650          * Redirect.appendTo(file).file() == file &&
 651          * Redirect.appendTo(file).type() == Redirect.Type.APPEND
 652          * }</pre>
 653          *
 654          * @param file The {@code File} for the {@code Redirect}.
 655          * @return a redirect to append to the specified file
 656          */
 657         public static Redirect appendTo(final File file) {
 658             if (file == null)
 659                 throw new NullPointerException();
 660             return new Redirect() {
 661                     public Type type() { return Type.APPEND; }
 662                     public File file() { return file; }
 663                     public String toString() {
 664                         return "redirect to append to file \"" + file + "\"";
 665                     }
 666                     boolean append() { return true; }
 667                 };
 668         }
 669 
 670         /**
 671          * Compares the specified object with this {@code Redirect} for
 672          * equality.  Returns {@code true} if and only if the two
 673          * objects are identical or both objects are {@code Redirect}
 674          * instances of the same type associated with non-null equal
 675          * {@code File} instances.
 676          */
 677         public boolean equals(Object obj) {
 678             if (obj == this)
 679                 return true;
 680             if (! (obj instanceof Redirect))
 681                 return false;
 682             Redirect r = (Redirect) obj;
 683             if (r.type() != this.type())
 684                 return false;
 685             assert this.file() != null;
 686             return this.file().equals(r.file());
 687         }
 688 
 689         /**
 690          * Returns a hash code value for this {@code Redirect}.
 691          * @return a hash code value for this {@code Redirect}
 692          */
 693         public int hashCode() {
 694             File file = file();
 695             if (file == null)
 696                 return super.hashCode();
 697             else
 698                 return file.hashCode();
 699         }
 700 
 701         /**
 702          * No public constructors.  Clients must use predefined
 703          * static {@code Redirect} instances or factory methods.
 704          */
 705         private Redirect() {}
 706     }
 707 
 708     /**
 709      * Private implementation subclass of Redirect that holds a FileDescriptor for the
 710      * output of a previously started Process.
 711      * The FileDescriptor is used as the standard input of the next Process
 712      * to be started.
 713      */
 714     static class RedirectPipeImpl extends Redirect {
 715         final FileDescriptor fd;
 716 
 717         RedirectPipeImpl() {
 718             this.fd = new FileDescriptor();
 719         }
 720         @Override
 721         public Type type() { return Type.PIPE; }
 722 
 723         @Override
 724         public String toString() { return type().toString();}
 725 
 726         FileDescriptor getFd() { return fd; }
 727     }
 728 
 729     /**
 730      * Return the array of redirects, creating the default as needed.
 731      * @return the array of redirects
 732      */
 733     private Redirect[] redirects() {
 734         if (redirects == null) {
 735             redirects = new Redirect[] {
 736                     Redirect.PIPE, Redirect.PIPE, Redirect.PIPE
 737             };
 738         }
 739         return redirects;
 740     }
 741 
 742     /**
 743      * Sets this process builder's standard input source.
 744      *
 745      * Subprocesses subsequently started by this object's {@link #start()}
 746      * method obtain their standard input from this source.
 747      *
 748      * <p>If the source is {@link Redirect#PIPE Redirect.PIPE}
 749      * (the initial value), then the standard input of a
 750      * subprocess can be written to using the output stream
 751      * returned by {@link Process#getOutputStream()}.
 752      * If the source is set to any other value, then
 753      * {@link Process#getOutputStream()} will return a
 754      * <a href="#redirect-input">null output stream</a>.
 755      *
 756      * @param  source the new standard input source
 757      * @return this process builder
 758      * @throws IllegalArgumentException
 759      *         if the redirect does not correspond to a valid source
 760      *         of data, that is, has type
 761      *         {@link Redirect.Type#WRITE WRITE} or
 762      *         {@link Redirect.Type#APPEND APPEND}
 763      * @since  1.7
 764      */
 765     public ProcessBuilder redirectInput(Redirect source) {
 766         if (source.type() == Redirect.Type.WRITE ||
 767             source.type() == Redirect.Type.APPEND)
 768             throw new IllegalArgumentException(
 769                 "Redirect invalid for reading: " + source);
 770         redirects()[0] = source;
 771         return this;
 772     }
 773 
 774     /**
 775      * Sets this process builder's standard output destination.
 776      *
 777      * Subprocesses subsequently started by this object's {@link #start()}
 778      * method send their standard output to this destination.
 779      *
 780      * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
 781      * (the initial value), then the standard output of a subprocess
 782      * can be read using the input stream returned by {@link
 783      * Process#getInputStream()}.
 784      * If the destination is set to any other value, then
 785      * {@link Process#getInputStream()} will return a
 786      * <a href="#redirect-output">null input stream</a>.
 787      *
 788      * @param  destination the new standard output destination
 789      * @return this process builder
 790      * @throws IllegalArgumentException
 791      *         if the redirect does not correspond to a valid
 792      *         destination of data, that is, has type
 793      *         {@link Redirect.Type#READ READ}
 794      * @since  1.7
 795      */
 796     public ProcessBuilder redirectOutput(Redirect destination) {
 797         if (destination.type() == Redirect.Type.READ)
 798             throw new IllegalArgumentException(
 799                 "Redirect invalid for writing: " + destination);
 800         redirects()[1] = destination;
 801         return this;
 802     }
 803 
 804     /**
 805      * Sets this process builder's standard error destination.
 806      *
 807      * Subprocesses subsequently started by this object's {@link #start()}
 808      * method send their standard error to this destination.
 809      *
 810      * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
 811      * (the initial value), then the error output of a subprocess
 812      * can be read using the input stream returned by {@link
 813      * Process#getErrorStream()}.
 814      * If the destination is set to any other value, then
 815      * {@link Process#getErrorStream()} will return a
 816      * <a href="#redirect-output">null input stream</a>.
 817      *
 818      * <p>If the {@link #redirectErrorStream() redirectErrorStream}
 819      * attribute has been set {@code true}, then the redirection set
 820      * by this method has no effect.
 821      *
 822      * @param  destination the new standard error destination
 823      * @return this process builder
 824      * @throws IllegalArgumentException
 825      *         if the redirect does not correspond to a valid
 826      *         destination of data, that is, has type
 827      *         {@link Redirect.Type#READ READ}
 828      * @since  1.7
 829      */
 830     public ProcessBuilder redirectError(Redirect destination) {
 831         if (destination.type() == Redirect.Type.READ)
 832             throw new IllegalArgumentException(
 833                 "Redirect invalid for writing: " + destination);
 834         redirects()[2] = destination;
 835         return this;
 836     }
 837 
 838     /**
 839      * Sets this process builder's standard input source to a file.
 840      *
 841      * <p>This is a convenience method.  An invocation of the form
 842      * {@code redirectInput(file)}
 843      * behaves in exactly the same way as the invocation
 844      * {@link #redirectInput(Redirect) redirectInput}
 845      * {@code (Redirect.from(file))}.
 846      *
 847      * @param  file the new standard input source
 848      * @return this process builder
 849      * @since  1.7
 850      */
 851     public ProcessBuilder redirectInput(File file) {
 852         return redirectInput(Redirect.from(file));
 853     }
 854 
 855     /**
 856      * Sets this process builder's standard output destination to a file.
 857      *
 858      * <p>This is a convenience method.  An invocation of the form
 859      * {@code redirectOutput(file)}
 860      * behaves in exactly the same way as the invocation
 861      * {@link #redirectOutput(Redirect) redirectOutput}
 862      * {@code (Redirect.to(file))}.
 863      *
 864      * @param  file the new standard output destination
 865      * @return this process builder
 866      * @since  1.7
 867      */
 868     public ProcessBuilder redirectOutput(File file) {
 869         return redirectOutput(Redirect.to(file));
 870     }
 871 
 872     /**
 873      * Sets this process builder's standard error destination to a file.
 874      *
 875      * <p>This is a convenience method.  An invocation of the form
 876      * {@code redirectError(file)}
 877      * behaves in exactly the same way as the invocation
 878      * {@link #redirectError(Redirect) redirectError}
 879      * {@code (Redirect.to(file))}.
 880      *
 881      * @param  file the new standard error destination
 882      * @return this process builder
 883      * @since  1.7
 884      */
 885     public ProcessBuilder redirectError(File file) {
 886         return redirectError(Redirect.to(file));
 887     }
 888 
 889     /**
 890      * Returns this process builder's standard input source.
 891      *
 892      * Subprocesses subsequently started by this object's {@link #start()}
 893      * method obtain their standard input from this source.
 894      * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
 895      *
 896      * @return this process builder's standard input source
 897      * @since  1.7
 898      */
 899     public Redirect redirectInput() {
 900         return (redirects == null) ? Redirect.PIPE : redirects[0];
 901     }
 902 
 903     /**
 904      * Returns this process builder's standard output destination.
 905      *
 906      * Subprocesses subsequently started by this object's {@link #start()}
 907      * method redirect their standard output to this destination.
 908      * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
 909      *
 910      * @return this process builder's standard output destination
 911      * @since  1.7
 912      */
 913     public Redirect redirectOutput() {
 914         return (redirects == null) ? Redirect.PIPE : redirects[1];
 915     }
 916 
 917     /**
 918      * Returns this process builder's standard error destination.
 919      *
 920      * Subprocesses subsequently started by this object's {@link #start()}
 921      * method redirect their standard error to this destination.
 922      * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
 923      *
 924      * @return this process builder's standard error destination
 925      * @since  1.7
 926      */
 927     public Redirect redirectError() {
 928         return (redirects == null) ? Redirect.PIPE : redirects[2];
 929     }
 930 
 931     /**
 932      * Sets the source and destination for subprocess standard I/O
 933      * to be the same as those of the current Java process.
 934      *
 935      * <p>This is a convenience method.  An invocation of the form
 936      *  <pre> {@code
 937      * pb.inheritIO()
 938      * }</pre>
 939      * behaves in exactly the same way as the invocation
 940      *  <pre> {@code
 941      * pb.redirectInput(Redirect.INHERIT)
 942      *   .redirectOutput(Redirect.INHERIT)
 943      *   .redirectError(Redirect.INHERIT)
 944      * }</pre>
 945      *
 946      * This gives behavior equivalent to most operating system
 947      * command interpreters, or the standard C library function
 948      * {@code system()}.
 949      *
 950      * @return this process builder
 951      * @since  1.7
 952      */
 953     public ProcessBuilder inheritIO() {
 954         Arrays.fill(redirects(), Redirect.INHERIT);
 955         return this;
 956     }
 957 
 958     /**
 959      * Tells whether this process builder merges standard error and
 960      * standard output.
 961      *
 962      * <p>If this property is {@code true}, then any error output
 963      * generated by subprocesses subsequently started by this object's
 964      * {@link #start()} method will be merged with the standard
 965      * output, so that both can be read using the
 966      * {@link Process#getInputStream()} method.  This makes it easier
 967      * to correlate error messages with the corresponding output.
 968      * The initial value is {@code false}.
 969      *
 970      * @return this process builder's {@code redirectErrorStream} property
 971      */
 972     public boolean redirectErrorStream() {
 973         return redirectErrorStream;
 974     }
 975 
 976     /**
 977      * Sets this process builder's {@code redirectErrorStream} property.
 978      *
 979      * <p>If this property is {@code true}, then any error output
 980      * generated by subprocesses subsequently started by this object's
 981      * {@link #start()} method will be merged with the standard
 982      * output, so that both can be read using the
 983      * {@link Process#getInputStream()} method.  This makes it easier
 984      * to correlate error messages with the corresponding output.
 985      * The initial value is {@code false}.
 986      *
 987      * @param  redirectErrorStream the new property value
 988      * @return this process builder
 989      */
 990     public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
 991         this.redirectErrorStream = redirectErrorStream;
 992         return this;
 993     }
 994 
 995     /**
 996      * Starts a new process using the attributes of this process builder.
 997      *
 998      * <p>The new process will
 999      * invoke the command and arguments given by {@link #command()},
1000      * in a working directory as given by {@link #directory()},
1001      * with a process environment as given by {@link #environment()}.
1002      *
1003      * <p>This method checks that the command is a valid operating
1004      * system command.  Which commands are valid is system-dependent,
1005      * but at the very least the command must be a non-empty list of
1006      * non-null strings.
1007      *
1008      * <p>A minimal set of system dependent environment variables may
1009      * be required to start a process on some operating systems.
1010      * As a result, the subprocess may inherit additional environment variable
1011      * settings beyond those in the process builder's {@link #environment()}.
1012      *
1013      * <p>If there is a security manager, its
1014      * {@link SecurityManager#checkExec checkExec}
1015      * method is called with the first component of this object's
1016      * {@code command} array as its argument. This may result in
1017      * a {@link SecurityException} being thrown.
1018      *
1019      * <p>Starting an operating system process is highly system-dependent.
1020      * Among the many things that can go wrong are:
1021      * <ul>
1022      * <li>The operating system program file was not found.
1023      * <li>Access to the program file was denied.
1024      * <li>The working directory does not exist.
1025      * <li>Invalid character in command argument, such as NUL.
1026      * </ul>
1027      *
1028      * <p>In such cases an exception will be thrown.  The exact nature
1029      * of the exception is system-dependent, but it will always be a
1030      * subclass of {@link IOException}.
1031      *
1032      * <p>If the operating system does not support the creation of
1033      * processes, an {@link UnsupportedOperationException} will be thrown.
1034      *
1035      * <p>Subsequent modifications to this process builder will not
1036      * affect the returned {@link Process}.
1037      *
1038      * @return a new {@link Process} object for managing the subprocess
1039      *
1040      * @throws NullPointerException
1041      *         if an element of the command list is null
1042      *
1043      * @throws IndexOutOfBoundsException
1044      *         if the command is an empty list (has size {@code 0})
1045      *
1046      * @throws SecurityException
1047      *         if a security manager exists and
1048      *         <ul>
1049      *
1050      *         <li>its
1051      *         {@link SecurityManager#checkExec checkExec}
1052      *         method doesn't allow creation of the subprocess, or
1053      *
1054      *         <li>the standard input to the subprocess was
1055      *         {@linkplain #redirectInput redirected from a file}
1056      *         and the security manager's
1057      *         {@link SecurityManager#checkRead(String) checkRead} method
1058      *         denies read access to the file, or
1059      *
1060      *         <li>the standard output or standard error of the
1061      *         subprocess was
1062      *         {@linkplain #redirectOutput redirected to a file}
1063      *         and the security manager's
1064      *         {@link SecurityManager#checkWrite(String) checkWrite} method
1065      *         denies write access to the file
1066      *
1067      *         </ul>
1068      *
1069      * @throws  UnsupportedOperationException
1070      *          If the operating system does not support the creation of processes.
1071      *
1072      * @throws IOException if an I/O error occurs
1073      *
1074      * @see Runtime#exec(String[], String[], java.io.File)
1075      */
1076     public Process start() throws IOException {
1077         return start(redirects);
1078     }
1079 
1080     /**
1081      * Start a new Process using an explicit array of redirects.
1082      * See {@link #start} for details of starting each Process.
1083      *
1084      * @param redirect array of redirects for stdin, stdout, stderr
1085      * @return the new Process
1086      * @throws IOException if an I/O error occurs
1087      */
1088     private Process start(Redirect[] redirects) throws IOException {
1089         // Must convert to array first -- a malicious user-supplied
1090         // list might try to circumvent the security check.
1091         String[] cmdarray = command.toArray(new String[command.size()]);
1092         cmdarray = cmdarray.clone();
1093 
1094         for (String arg : cmdarray)
1095             if (arg == null)
1096                 throw new NullPointerException();
1097         // Throws IndexOutOfBoundsException if command is empty
1098         String prog = cmdarray[0];
1099 
1100         SecurityManager security = System.getSecurityManager();
1101         if (security != null)
1102             security.checkExec(prog);
1103 
1104         String dir = directory == null ? null : directory.toString();
1105 
1106         for (int i = 1; i < cmdarray.length; i++) {
1107             if (cmdarray[i].indexOf('\u0000') >= 0) {
1108                 throw new IOException("invalid null character in command");
1109             }
1110         }
1111 
1112         try {
1113             return ProcessImpl.start(cmdarray,
1114                                      environment,
1115                                      dir,
1116                                      redirects,
1117                                      redirectErrorStream);
1118         } catch (IOException | IllegalArgumentException e) {
1119             String exceptionInfo = ": " + e.getMessage();
1120             Throwable cause = e;
1121             if ((e instanceof IOException) && security != null) {
1122                 // Can not disclose the fail reason for read-protected files.
1123                 try {
1124                     security.checkRead(prog);
1125                 } catch (SecurityException se) {
1126                     exceptionInfo = "";
1127                     cause = se;
1128                 }
1129             }
1130             // It's much easier for us to create a high-quality error
1131             // message than the low-level C code which found the problem.
1132             throw new IOException(
1133                 "Cannot run program \"" + prog + "\""
1134                 + (dir == null ? "" : " (in directory \"" + dir + "\")")
1135                 + exceptionInfo,
1136                 cause);
1137         }
1138     }
1139 
1140     /**
1141      * Starts a Process for each ProcessBuilder, creating a pipeline of
1142      * processes linked by their standard output and standard input streams.
1143      * The attributes of each ProcessBuilder are used to start the respective
1144      * process except that as each process is started, its standard output
1145      * is directed to the standard input of the next.  The redirects for standard
1146      * input of the first process and standard output of the last process are
1147      * initialized using the redirect settings of the respective ProcessBuilder.
1148      * All other {@code ProcessBuilder} redirects should be
1149      * {@link Redirect#PIPE Redirect.PIPE}.
1150      * <p>
1151      * All input and output streams between the intermediate processes are
1152      * not accessible.
1153      * The {@link Process#getOutputStream standard input} of all processes
1154      * except the first process are <i>null output streams</i>
1155      * The {@link Process#getInputStream standard output} of all processes
1156      * except the last process are <i>null input streams</i>.
1157      * <p>
1158      * The {@link #redirectErrorStream()} of each ProcessBuilder applies to the
1159      * respective process.  If set to {@code true}, the error stream is written
1160      * to the same stream as standard output.
1161      * <p>
1162      * If starting any of the processes throws an Exception, all processes
1163      * are forcibly destroyed.
1164      * <p>
1165      * The {@code startPipeline} method performs the same checks on
1166      * each ProcessBuilder as does the {@link #start} method. Each new process
1167      * invokes the command and arguments given by the respective process builder's
1168      * {@link #command()}, in a working directory as given by its {@link #directory()},
1169      * with a process environment as given by its {@link #environment()}.
1170      * <p>
1171      * Each process builder's command is checked to be a valid operating
1172      * system command.  Which commands are valid is system-dependent,
1173      * but at the very least the command must be a non-empty list of
1174      * non-null strings.
1175      * <p>
1176      * A minimal set of system dependent environment variables may
1177      * be required to start a process on some operating systems.
1178      * As a result, the subprocess may inherit additional environment variable
1179      * settings beyond those in the process builder's {@link #environment()}.
1180      * <p>
1181      * If there is a security manager, its
1182      * {@link SecurityManager#checkExec checkExec}
1183      * method is called with the first component of each process builder's
1184      * {@code command} array as its argument. This may result in
1185      * a {@link SecurityException} being thrown.
1186      * <p>
1187      * Starting an operating system process is highly system-dependent.
1188      * Among the many things that can go wrong are:
1189      * <ul>
1190      * <li>The operating system program file was not found.
1191      * <li>Access to the program file was denied.
1192      * <li>The working directory does not exist.
1193      * <li>Invalid character in command argument, such as NUL.
1194      * </ul>
1195      * <p>
1196      * In such cases an exception will be thrown.  The exact nature
1197      * of the exception is system-dependent, but it will always be a
1198      * subclass of {@link IOException}.
1199      * <p>
1200      * If the operating system does not support the creation of
1201      * processes, an {@link UnsupportedOperationException} will be thrown.
1202      * <p>
1203      * Subsequent modifications to any of the specified builders
1204      * will not affect the returned {@link Process}.
1205      * @apiNote
1206      * For example to count the unique imports for all the files in a file hierarchy
1207      * on a Unix compatible platform:
1208      * <pre>{@code
1209      * String directory = "/home/duke/src";
1210      * ProcessBuilder[] builders = {
1211      *              new ProcessBuilder("find", directory, "-type", "f"),
1212                     new ProcessBuilder("xargs", "grep", "-h", "^import "),
1213                     new ProcessBuilder("awk", "{print $2;}"),
1214                     new ProcessBuilder("sort", "-u")};
1215      * List<Process> processes = ProcessBuilder.startPipeline(
1216      *         Arrays.asList(builders));
1217      * Process last = processes.get(processes.size()-1);
1218      * try (InputStream is = last.getInputStream();
1219      *         Reader isr = new InputStreamReader(is);
1220      *         BufferedReader r = new BufferedReader(isr)) {
1221      *     long count = r.lines().count();
1222      * }
1223      * }</pre>
1224      *
1225      * @param builders a List of ProcessBuilders
1226      * @return a {@code List<Process>}es started from the corresponding
1227      *         ProcessBuilder
1228      * @throws IllegalArgumentException any of the redirects except the
1229      *          standard input of the first builder and the standard output of
1230      *          the last builder are not {@link Redirect#PIPE}.
1231      * @throws NullPointerException
1232      *         if an element of the command list is null or
1233      *         if an element of the ProcessBuilder list is null or
1234      *         the builders argument is null
1235      * @throws IndexOutOfBoundsException
1236      *         if the command is an empty list (has size {@code 0})
1237      * @throws SecurityException
1238      *         if a security manager exists and
1239      *         <ul>
1240      *         <li>its
1241      *         {@link SecurityManager#checkExec checkExec}
1242      *         method doesn't allow creation of the subprocess, or
1243      *         <li>the standard input to the subprocess was
1244      *         {@linkplain #redirectInput redirected from a file}
1245      *         and the security manager's
1246      *         {@link SecurityManager#checkRead(String) checkRead} method
1247      *         denies read access to the file, or
1248      *         <li>the standard output or standard error of the
1249      *         subprocess was
1250      *         {@linkplain #redirectOutput redirected to a file}
1251      *         and the security manager's
1252      *         {@link SecurityManager#checkWrite(String) checkWrite} method
1253      *         denies write access to the file
1254      *         </ul>
1255      *
1256      * @throws  UnsupportedOperationException
1257      *          If the operating system does not support the creation of processes
1258      *
1259      * @throws IOException if an I/O error occurs
1260      * @since 9
1261      */
1262     public static List<Process> startPipeline(List<ProcessBuilder> builders) throws IOException {
1263         // Accumulate and check the builders
1264         final int numBuilders = builders.size();
1265         List<Process> processes = new ArrayList<>(numBuilders);
1266         try {
1267             Redirect prevOutput = null;
1268             for (int index = 0; index < builders.size(); index++) {
1269                 ProcessBuilder builder = builders.get(index);
1270                 Redirect[] redirects = builder.redirects();
1271                 if (index > 0) {
1272                     // check the current Builder to see if it can take input from the previous
1273                     if (builder.redirectInput() != Redirect.PIPE) {
1274                         throw new IllegalArgumentException("builder redirectInput()" +
1275                                 " must be PIPE except for the first builder: "
1276                                 + builder.redirectInput());
1277                     }
1278                     redirects[0] = prevOutput;
1279                 }
1280                 if (index < numBuilders - 1) {
1281                     // check all but the last stage has output = PIPE
1282                     if (builder.redirectOutput() != Redirect.PIPE) {
1283                         throw new IllegalArgumentException("builder redirectOutput()" +
1284                                 " must be PIPE except for the last builder: "
1285                                 + builder.redirectOutput());
1286                     }
1287                     redirects[1] = new RedirectPipeImpl();  // placeholder for new output
1288                 }
1289                 processes.add(builder.start(redirects));
1290                 prevOutput = redirects[1];
1291             }
1292         } catch (Exception ex) {
1293             // Cleanup processes already started
1294             processes.forEach(Process::destroyForcibly);
1295             processes.forEach(p -> {
1296                 try {
1297                     p.waitFor();        // Wait for it to exit
1298                 } catch (InterruptedException ie) {
1299                     // If interrupted; continue with next Process
1300                     Thread.currentThread().interrupt();
1301                 }
1302             });
1303             throw ex;
1304         }
1305         return processes;
1306     }
1307 
1308     // VarHandle mechanics
1309     private static final VarHandle COMMAND;
1310     private static final VarHandle ENVIRONMENT;
1311     static {
1312         try {
1313             MethodHandles.Lookup l = MethodHandles.lookup();
1314             COMMAND = l.findVarHandle(
1315                     ProcessBuilder.class, "command", List.class);
1316             ENVIRONMENT = l.findVarHandle(
1317                     ProcessBuilder.class, "environment", Map.class);
1318         } catch (ReflectiveOperationException e) {
1319             throw new ExceptionInInitializerError(e);
1320         }
1321     }
1322 }