ProcessBuilder.java revision 12745:f068a4ffddd2
1/* 2 * Copyright (c) 2003, 2013, 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 26package java.lang; 27 28import java.io.File; 29import java.io.IOException; 30import java.io.InputStream; 31import java.io.OutputStream; 32import java.util.Arrays; 33import java.util.ArrayList; 34import java.util.List; 35import java.util.Map; 36 37/** 38 * This class is used to create operating system processes. 39 * 40 * <p>Each {@code ProcessBuilder} instance manages a collection 41 * of process attributes. The {@link #start()} method creates a new 42 * {@link Process} instance with those attributes. The {@link 43 * #start()} method can be invoked repeatedly from the same instance 44 * to create new subprocesses with identical or related attributes. 45 * 46 * <p>Each process builder manages these process attributes: 47 * 48 * <ul> 49 * 50 * <li>a <i>command</i>, a list of strings which signifies the 51 * external program file to be invoked and its arguments, if any. 52 * Which string lists represent a valid operating system command is 53 * system-dependent. For example, it is common for each conceptual 54 * argument to be an element in this list, but there are operating 55 * systems where programs are expected to tokenize command line 56 * strings themselves - on such a system a Java implementation might 57 * require commands to contain exactly two elements. 58 * 59 * <li>an <i>environment</i>, which is a system-dependent mapping from 60 * <i>variables</i> to <i>values</i>. The initial value is a copy of 61 * the environment of the current process (see {@link System#getenv()}). 62 * 63 * <li>a <i>working directory</i>. The default value is the current 64 * working directory of the current process, usually the directory 65 * named by the system property {@code user.dir}. 66 * 67 * <li><a name="redirect-input">a source of <i>standard input</i></a>. 68 * By default, the subprocess reads input from a pipe. Java code 69 * can access this pipe via the output stream returned by 70 * {@link Process#getOutputStream()}. However, standard input may 71 * be redirected to another source using 72 * {@link #redirectInput(Redirect) redirectInput}. 73 * In this case, {@link Process#getOutputStream()} will return a 74 * <i>null output stream</i>, for which: 75 * 76 * <ul> 77 * <li>the {@link OutputStream#write(int) write} methods always 78 * throw {@code IOException} 79 * <li>the {@link OutputStream#close() close} method does nothing 80 * </ul> 81 * 82 * <li><a name="redirect-output">a destination for <i>standard output</i> 83 * and <i>standard error</i></a>. By default, the subprocess writes standard 84 * output and standard error to pipes. Java code can access these pipes 85 * via the input streams returned by {@link Process#getOutputStream()} and 86 * {@link Process#getErrorStream()}. However, standard output and 87 * standard error may be redirected to other destinations using 88 * {@link #redirectOutput(Redirect) redirectOutput} and 89 * {@link #redirectError(Redirect) redirectError}. 90 * In this case, {@link Process#getInputStream()} and/or 91 * {@link Process#getErrorStream()} will return a <i>null input 92 * stream</i>, for which: 93 * 94 * <ul> 95 * <li>the {@link InputStream#read() read} methods always return 96 * {@code -1} 97 * <li>the {@link InputStream#available() available} method always returns 98 * {@code 0} 99 * <li>the {@link InputStream#close() close} method does nothing 100 * </ul> 101 * 102 * <li>a <i>redirectErrorStream</i> property. Initially, this property 103 * is {@code false}, meaning that the standard output and error 104 * output of a subprocess are sent to two separate streams, which can 105 * be accessed using the {@link Process#getInputStream()} and {@link 106 * Process#getErrorStream()} methods. 107 * 108 * <p>If the value is set to {@code true}, then: 109 * 110 * <ul> 111 * <li>standard error is merged with the standard output and always sent 112 * to the same destination (this makes it easier to correlate error 113 * messages with the corresponding output) 114 * <li>the common destination of standard error and standard output can be 115 * redirected using 116 * {@link #redirectOutput(Redirect) redirectOutput} 117 * <li>any redirection set by the 118 * {@link #redirectError(Redirect) redirectError} 119 * method is ignored when creating a subprocess 120 * <li>the stream returned from {@link Process#getErrorStream()} will 121 * always be a <a href="#redirect-output">null input stream</a> 122 * </ul> 123 * 124 * </ul> 125 * 126 * <p>Modifying a process builder's attributes will affect processes 127 * subsequently started by that object's {@link #start()} method, but 128 * will never affect previously started processes or the Java process 129 * itself. 130 * 131 * <p>Most error checking is performed by the {@link #start()} method. 132 * It is possible to modify the state of an object so that {@link 133 * #start()} will fail. For example, setting the command attribute to 134 * an empty list will not throw an exception unless {@link #start()} 135 * is invoked. 136 * 137 * <p><strong>Note that this class is not synchronized.</strong> 138 * If multiple threads access a {@code ProcessBuilder} instance 139 * concurrently, and at least one of the threads modifies one of the 140 * attributes structurally, it <i>must</i> be synchronized externally. 141 * 142 * <p>Starting a new process which uses the default working directory 143 * and environment is easy: 144 * 145 * <pre> {@code 146 * Process p = new ProcessBuilder("myCommand", "myArg").start(); 147 * }</pre> 148 * 149 * <p>Here is an example that starts a process with a modified working 150 * directory and environment, and redirects standard output and error 151 * to be appended to a log file: 152 * 153 * <pre> {@code 154 * ProcessBuilder pb = 155 * new ProcessBuilder("myCommand", "myArg1", "myArg2"); 156 * Map<String, String> env = pb.environment(); 157 * env.put("VAR1", "myValue"); 158 * env.remove("OTHERVAR"); 159 * env.put("VAR2", env.get("VAR1") + "suffix"); 160 * pb.directory(new File("myDir")); 161 * File log = new File("log"); 162 * pb.redirectErrorStream(true); 163 * pb.redirectOutput(Redirect.appendTo(log)); 164 * Process p = pb.start(); 165 * assert pb.redirectInput() == Redirect.PIPE; 166 * assert pb.redirectOutput().file() == log; 167 * assert p.getInputStream().read() == -1; 168 * }</pre> 169 * 170 * <p>To start a process with an explicit set of environment 171 * variables, first call {@link java.util.Map#clear() Map.clear()} 172 * before adding environment variables. 173 * 174 * <p> 175 * Unless otherwise noted, passing a {@code null} argument to a constructor 176 * or method in this class will cause a {@link NullPointerException} to be 177 * thrown. 178 * 179 * @author Martin Buchholz 180 * @since 1.5 181 */ 182 183public final class ProcessBuilder 184{ 185 private List<String> command; 186 private File directory; 187 private Map<String,String> environment; 188 private boolean redirectErrorStream; 189 private Redirect[] redirects; 190 191 /** 192 * Constructs a process builder with the specified operating 193 * system program and arguments. This constructor does <i>not</i> 194 * make a copy of the {@code command} list. Subsequent 195 * updates to the list will be reflected in the state of the 196 * process builder. It is not checked whether 197 * {@code command} corresponds to a valid operating system 198 * command. 199 * 200 * @param command the list containing the program and its arguments 201 */ 202 public ProcessBuilder(List<String> command) { 203 if (command == null) 204 throw new NullPointerException(); 205 this.command = command; 206 } 207 208 /** 209 * Constructs a process builder with the specified operating 210 * system program and arguments. This is a convenience 211 * constructor that sets the process builder's command to a string 212 * list containing the same strings as the {@code command} 213 * array, in the same order. It is not checked whether 214 * {@code command} corresponds to a valid operating system 215 * command. 216 * 217 * @param command a string array containing the program and its arguments 218 */ 219 public ProcessBuilder(String... command) { 220 this.command = new ArrayList<>(command.length); 221 for (String arg : command) 222 this.command.add(arg); 223 } 224 225 /** 226 * Sets this process builder's operating system program and 227 * arguments. This method does <i>not</i> make a copy of the 228 * {@code command} list. Subsequent updates to the list will 229 * be reflected in the state of the process builder. It is not 230 * checked whether {@code command} corresponds to a valid 231 * operating system command. 232 * 233 * @param command the list containing the program and its arguments 234 * @return this process builder 235 */ 236 public ProcessBuilder command(List<String> command) { 237 if (command == null) 238 throw new NullPointerException(); 239 this.command = command; 240 return this; 241 } 242 243 /** 244 * Sets this process builder's operating system program and 245 * arguments. This is a convenience method that sets the command 246 * to a string list containing the same strings as the 247 * {@code command} array, in the same order. It is not 248 * checked whether {@code command} corresponds to a valid 249 * operating system command. 250 * 251 * @param command a string array containing the program and its arguments 252 * @return this process builder 253 */ 254 public ProcessBuilder command(String... command) { 255 this.command = new ArrayList<>(command.length); 256 for (String arg : command) 257 this.command.add(arg); 258 return this; 259 } 260 261 /** 262 * Returns this process builder's operating system program and 263 * arguments. The returned list is <i>not</i> a copy. Subsequent 264 * updates to the list will be reflected in the state of this 265 * process builder. 266 * 267 * @return this process builder's program and its arguments 268 */ 269 public List<String> command() { 270 return command; 271 } 272 273 /** 274 * Returns a string map view of this process builder's environment. 275 * 276 * Whenever a process builder is created, the environment is 277 * initialized to a copy of the current process environment (see 278 * {@link System#getenv()}). Subprocesses subsequently started by 279 * this object's {@link #start()} method will use this map as 280 * their environment. 281 * 282 * <p>The returned object may be modified using ordinary {@link 283 * java.util.Map Map} operations. These modifications will be 284 * visible to subprocesses started via the {@link #start()} 285 * method. Two {@code ProcessBuilder} instances always 286 * contain independent process environments, so changes to the 287 * returned map will never be reflected in any other 288 * {@code ProcessBuilder} instance or the values returned by 289 * {@link System#getenv System.getenv}. 290 * 291 * <p>If the system does not support environment variables, an 292 * empty map is returned. 293 * 294 * <p>The returned map does not permit null keys or values. 295 * Attempting to insert or query the presence of a null key or 296 * value will throw a {@link NullPointerException}. 297 * Attempting to query the presence of a key or value which is not 298 * of type {@link String} will throw a {@link ClassCastException}. 299 * 300 * <p>The behavior of the returned map is system-dependent. A 301 * system may not allow modifications to environment variables or 302 * may forbid certain variable names or values. For this reason, 303 * attempts to modify the map may fail with 304 * {@link UnsupportedOperationException} or 305 * {@link IllegalArgumentException} 306 * if the modification is not permitted by the operating system. 307 * 308 * <p>Since the external format of environment variable names and 309 * values is system-dependent, there may not be a one-to-one 310 * mapping between them and Java's Unicode strings. Nevertheless, 311 * the map is implemented in such a way that environment variables 312 * which are not modified by Java code will have an unmodified 313 * native representation in the subprocess. 314 * 315 * <p>The returned map and its collection views may not obey the 316 * general contract of the {@link Object#equals} and 317 * {@link Object#hashCode} methods. 318 * 319 * <p>The returned map is typically case-sensitive on all platforms. 320 * 321 * <p>If a security manager exists, its 322 * {@link SecurityManager#checkPermission checkPermission} method 323 * is called with a 324 * {@link RuntimePermission}{@code ("getenv.*")} permission. 325 * This may result in a {@link SecurityException} being thrown. 326 * 327 * <p>When passing information to a Java subprocess, 328 * <a href=System.html#EnvironmentVSSystemProperties>system properties</a> 329 * are generally preferred over environment variables. 330 * 331 * @return this process builder's environment 332 * 333 * @throws SecurityException 334 * if a security manager exists and its 335 * {@link SecurityManager#checkPermission checkPermission} 336 * method doesn't allow access to the process environment 337 * 338 * @see Runtime#exec(String[],String[],java.io.File) 339 * @see System#getenv() 340 */ 341 public Map<String,String> environment() { 342 SecurityManager security = System.getSecurityManager(); 343 if (security != null) 344 security.checkPermission(new RuntimePermission("getenv.*")); 345 346 if (environment == null) 347 environment = ProcessEnvironment.environment(); 348 349 assert environment != null; 350 351 return environment; 352 } 353 354 // Only for use by Runtime.exec(...envp...) 355 ProcessBuilder environment(String[] envp) { 356 assert environment == null; 357 if (envp != null) { 358 environment = ProcessEnvironment.emptyEnvironment(envp.length); 359 assert environment != null; 360 361 for (String envstring : envp) { 362 // Before 1.5, we blindly passed invalid envstrings 363 // to the child process. 364 // We would like to throw an exception, but do not, 365 // for compatibility with old broken code. 366 367 // Silently discard any trailing junk. 368 if (envstring.indexOf((int) '\u0000') != -1) 369 envstring = envstring.replaceFirst("\u0000.*", ""); 370 371 int eqlsign = 372 envstring.indexOf('=', ProcessEnvironment.MIN_NAME_LENGTH); 373 // Silently ignore envstrings lacking the required `='. 374 if (eqlsign != -1) 375 environment.put(envstring.substring(0,eqlsign), 376 envstring.substring(eqlsign+1)); 377 } 378 } 379 return this; 380 } 381 382 /** 383 * Returns this process builder's working directory. 384 * 385 * Subprocesses subsequently started by this object's {@link 386 * #start()} method will use this as their working directory. 387 * The returned value may be {@code null} -- this means to use 388 * the working directory of the current Java process, usually the 389 * directory named by the system property {@code user.dir}, 390 * as the working directory of the child process. 391 * 392 * @return this process builder's working directory 393 */ 394 public File directory() { 395 return directory; 396 } 397 398 /** 399 * Sets this process builder's working directory. 400 * 401 * Subprocesses subsequently started by this object's {@link 402 * #start()} method will use this as their working directory. 403 * The argument may be {@code null} -- this means to use the 404 * working directory of the current Java process, usually the 405 * directory named by the system property {@code user.dir}, 406 * as the working directory of the child process. 407 * 408 * @param directory the new working directory 409 * @return this process builder 410 */ 411 public ProcessBuilder directory(File directory) { 412 this.directory = directory; 413 return this; 414 } 415 416 // ---------------- I/O Redirection ---------------- 417 418 /** 419 * Implements a <a href="#redirect-output">null input stream</a>. 420 */ 421 static class NullInputStream extends InputStream { 422 static final NullInputStream INSTANCE = new NullInputStream(); 423 private NullInputStream() {} 424 public int read() { return -1; } 425 public int available() { return 0; } 426 } 427 428 /** 429 * Implements a <a href="#redirect-input">null output stream</a>. 430 */ 431 static class NullOutputStream extends OutputStream { 432 static final NullOutputStream INSTANCE = new NullOutputStream(); 433 private NullOutputStream() {} 434 public void write(int b) throws IOException { 435 throw new IOException("Stream closed"); 436 } 437 } 438 439 /** 440 * Represents a source of subprocess input or a destination of 441 * subprocess output. 442 * 443 * Each {@code Redirect} instance is one of the following: 444 * 445 * <ul> 446 * <li>the special value {@link #PIPE Redirect.PIPE} 447 * <li>the special value {@link #INHERIT Redirect.INHERIT} 448 * <li>a redirection to read from a file, created by an invocation of 449 * {@link Redirect#from Redirect.from(File)} 450 * <li>a redirection to write to a file, created by an invocation of 451 * {@link Redirect#to Redirect.to(File)} 452 * <li>a redirection to append to a file, created by an invocation of 453 * {@link Redirect#appendTo Redirect.appendTo(File)} 454 * </ul> 455 * 456 * <p>Each of the above categories has an associated unique 457 * {@link Type Type}. 458 * 459 * @since 1.7 460 */ 461 public abstract static class Redirect { 462 /** 463 * The type of a {@link Redirect}. 464 */ 465 public enum Type { 466 /** 467 * The type of {@link Redirect#PIPE Redirect.PIPE}. 468 */ 469 PIPE, 470 471 /** 472 * The type of {@link Redirect#INHERIT Redirect.INHERIT}. 473 */ 474 INHERIT, 475 476 /** 477 * The type of redirects returned from 478 * {@link Redirect#from Redirect.from(File)}. 479 */ 480 READ, 481 482 /** 483 * The type of redirects returned from 484 * {@link Redirect#to Redirect.to(File)}. 485 */ 486 WRITE, 487 488 /** 489 * The type of redirects returned from 490 * {@link Redirect#appendTo Redirect.appendTo(File)}. 491 */ 492 APPEND 493 }; 494 495 /** 496 * Returns the type of this {@code Redirect}. 497 * @return the type of this {@code Redirect} 498 */ 499 public abstract Type type(); 500 501 /** 502 * Indicates that subprocess I/O will be connected to the 503 * current Java process over a pipe. 504 * 505 * This is the default handling of subprocess standard I/O. 506 * 507 * <p>It will always be true that 508 * <pre> {@code 509 * Redirect.PIPE.file() == null && 510 * Redirect.PIPE.type() == Redirect.Type.PIPE 511 * }</pre> 512 */ 513 public static final Redirect PIPE = new Redirect() { 514 public Type type() { return Type.PIPE; } 515 public String toString() { return type().toString(); }}; 516 517 /** 518 * Indicates that subprocess I/O source or destination will be the 519 * same as those of the current process. This is the normal 520 * behavior of most operating system command interpreters (shells). 521 * 522 * <p>It will always be true that 523 * <pre> {@code 524 * Redirect.INHERIT.file() == null && 525 * Redirect.INHERIT.type() == Redirect.Type.INHERIT 526 * }</pre> 527 */ 528 public static final Redirect INHERIT = new Redirect() { 529 public Type type() { return Type.INHERIT; } 530 public String toString() { return type().toString(); }}; 531 532 /** 533 * Returns the {@link File} source or destination associated 534 * with this redirect, or {@code null} if there is no such file. 535 * 536 * @return the file associated with this redirect, 537 * or {@code null} if there is no such file 538 */ 539 public File file() { return null; } 540 541 /** 542 * When redirected to a destination file, indicates if the output 543 * is to be written to the end of the file. 544 */ 545 boolean append() { 546 throw new UnsupportedOperationException(); 547 } 548 549 /** 550 * Returns a redirect to read from the specified file. 551 * 552 * <p>It will always be true that 553 * <pre> {@code 554 * Redirect.from(file).file() == file && 555 * Redirect.from(file).type() == Redirect.Type.READ 556 * }</pre> 557 * 558 * @param file The {@code File} for the {@code Redirect}. 559 * @return a redirect to read from the specified file 560 */ 561 public static Redirect from(final File file) { 562 if (file == null) 563 throw new NullPointerException(); 564 return new Redirect() { 565 public Type type() { return Type.READ; } 566 public File file() { return file; } 567 public String toString() { 568 return "redirect to read from file \"" + file + "\""; 569 } 570 }; 571 } 572 573 /** 574 * Returns a redirect to write to the specified file. 575 * If the specified file exists when the subprocess is started, 576 * its previous contents will be discarded. 577 * 578 * <p>It will always be true that 579 * <pre> {@code 580 * Redirect.to(file).file() == file && 581 * Redirect.to(file).type() == Redirect.Type.WRITE 582 * }</pre> 583 * 584 * @param file The {@code File} for the {@code Redirect}. 585 * @return a redirect to write to the specified file 586 */ 587 public static Redirect to(final File file) { 588 if (file == null) 589 throw new NullPointerException(); 590 return new Redirect() { 591 public Type type() { return Type.WRITE; } 592 public File file() { return file; } 593 public String toString() { 594 return "redirect to write to file \"" + file + "\""; 595 } 596 boolean append() { return false; } 597 }; 598 } 599 600 /** 601 * Returns a redirect to append to the specified file. 602 * Each write operation first advances the position to the 603 * end of the file and then writes the requested data. 604 * Whether the advancement of the position and the writing 605 * of the data are done in a single atomic operation is 606 * system-dependent and therefore unspecified. 607 * 608 * <p>It will always be true that 609 * <pre> {@code 610 * Redirect.appendTo(file).file() == file && 611 * Redirect.appendTo(file).type() == Redirect.Type.APPEND 612 * }</pre> 613 * 614 * @param file The {@code File} for the {@code Redirect}. 615 * @return a redirect to append to the specified file 616 */ 617 public static Redirect appendTo(final File file) { 618 if (file == null) 619 throw new NullPointerException(); 620 return new Redirect() { 621 public Type type() { return Type.APPEND; } 622 public File file() { return file; } 623 public String toString() { 624 return "redirect to append to file \"" + file + "\""; 625 } 626 boolean append() { return true; } 627 }; 628 } 629 630 /** 631 * Compares the specified object with this {@code Redirect} for 632 * equality. Returns {@code true} if and only if the two 633 * objects are identical or both objects are {@code Redirect} 634 * instances of the same type associated with non-null equal 635 * {@code File} instances. 636 */ 637 public boolean equals(Object obj) { 638 if (obj == this) 639 return true; 640 if (! (obj instanceof Redirect)) 641 return false; 642 Redirect r = (Redirect) obj; 643 if (r.type() != this.type()) 644 return false; 645 assert this.file() != null; 646 return this.file().equals(r.file()); 647 } 648 649 /** 650 * Returns a hash code value for this {@code Redirect}. 651 * @return a hash code value for this {@code Redirect} 652 */ 653 public int hashCode() { 654 File file = file(); 655 if (file == null) 656 return super.hashCode(); 657 else 658 return file.hashCode(); 659 } 660 661 /** 662 * No public constructors. Clients must use predefined 663 * static {@code Redirect} instances or factory methods. 664 */ 665 private Redirect() {} 666 } 667 668 private Redirect[] redirects() { 669 if (redirects == null) 670 redirects = new Redirect[] { 671 Redirect.PIPE, Redirect.PIPE, Redirect.PIPE 672 }; 673 return redirects; 674 } 675 676 /** 677 * Sets this process builder's standard input source. 678 * 679 * Subprocesses subsequently started by this object's {@link #start()} 680 * method obtain their standard input from this source. 681 * 682 * <p>If the source is {@link Redirect#PIPE Redirect.PIPE} 683 * (the initial value), then the standard input of a 684 * subprocess can be written to using the output stream 685 * returned by {@link Process#getOutputStream()}. 686 * If the source is set to any other value, then 687 * {@link Process#getOutputStream()} will return a 688 * <a href="#redirect-input">null output stream</a>. 689 * 690 * @param source the new standard input source 691 * @return this process builder 692 * @throws IllegalArgumentException 693 * if the redirect does not correspond to a valid source 694 * of data, that is, has type 695 * {@link Redirect.Type#WRITE WRITE} or 696 * {@link Redirect.Type#APPEND APPEND} 697 * @since 1.7 698 */ 699 public ProcessBuilder redirectInput(Redirect source) { 700 if (source.type() == Redirect.Type.WRITE || 701 source.type() == Redirect.Type.APPEND) 702 throw new IllegalArgumentException( 703 "Redirect invalid for reading: " + source); 704 redirects()[0] = source; 705 return this; 706 } 707 708 /** 709 * Sets this process builder's standard output destination. 710 * 711 * Subprocesses subsequently started by this object's {@link #start()} 712 * method send their standard output to this destination. 713 * 714 * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE} 715 * (the initial value), then the standard output of a subprocess 716 * can be read using the input stream returned by {@link 717 * Process#getInputStream()}. 718 * If the destination is set to any other value, then 719 * {@link Process#getInputStream()} will return a 720 * <a href="#redirect-output">null input stream</a>. 721 * 722 * @param destination the new standard output destination 723 * @return this process builder 724 * @throws IllegalArgumentException 725 * if the redirect does not correspond to a valid 726 * destination of data, that is, has type 727 * {@link Redirect.Type#READ READ} 728 * @since 1.7 729 */ 730 public ProcessBuilder redirectOutput(Redirect destination) { 731 if (destination.type() == Redirect.Type.READ) 732 throw new IllegalArgumentException( 733 "Redirect invalid for writing: " + destination); 734 redirects()[1] = destination; 735 return this; 736 } 737 738 /** 739 * Sets this process builder's standard error destination. 740 * 741 * Subprocesses subsequently started by this object's {@link #start()} 742 * method send their standard error to this destination. 743 * 744 * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE} 745 * (the initial value), then the error output of a subprocess 746 * can be read using the input stream returned by {@link 747 * Process#getErrorStream()}. 748 * If the destination is set to any other value, then 749 * {@link Process#getErrorStream()} will return a 750 * <a href="#redirect-output">null input stream</a>. 751 * 752 * <p>If the {@link #redirectErrorStream() redirectErrorStream} 753 * attribute has been set {@code true}, then the redirection set 754 * by this method has no effect. 755 * 756 * @param destination the new standard error destination 757 * @return this process builder 758 * @throws IllegalArgumentException 759 * if the redirect does not correspond to a valid 760 * destination of data, that is, has type 761 * {@link Redirect.Type#READ READ} 762 * @since 1.7 763 */ 764 public ProcessBuilder redirectError(Redirect destination) { 765 if (destination.type() == Redirect.Type.READ) 766 throw new IllegalArgumentException( 767 "Redirect invalid for writing: " + destination); 768 redirects()[2] = destination; 769 return this; 770 } 771 772 /** 773 * Sets this process builder's standard input source to a file. 774 * 775 * <p>This is a convenience method. An invocation of the form 776 * {@code redirectInput(file)} 777 * behaves in exactly the same way as the invocation 778 * {@link #redirectInput(Redirect) redirectInput} 779 * {@code (Redirect.from(file))}. 780 * 781 * @param file the new standard input source 782 * @return this process builder 783 * @since 1.7 784 */ 785 public ProcessBuilder redirectInput(File file) { 786 return redirectInput(Redirect.from(file)); 787 } 788 789 /** 790 * Sets this process builder's standard output destination to a file. 791 * 792 * <p>This is a convenience method. An invocation of the form 793 * {@code redirectOutput(file)} 794 * behaves in exactly the same way as the invocation 795 * {@link #redirectOutput(Redirect) redirectOutput} 796 * {@code (Redirect.to(file))}. 797 * 798 * @param file the new standard output destination 799 * @return this process builder 800 * @since 1.7 801 */ 802 public ProcessBuilder redirectOutput(File file) { 803 return redirectOutput(Redirect.to(file)); 804 } 805 806 /** 807 * Sets this process builder's standard error destination to a file. 808 * 809 * <p>This is a convenience method. An invocation of the form 810 * {@code redirectError(file)} 811 * behaves in exactly the same way as the invocation 812 * {@link #redirectError(Redirect) redirectError} 813 * {@code (Redirect.to(file))}. 814 * 815 * @param file the new standard error destination 816 * @return this process builder 817 * @since 1.7 818 */ 819 public ProcessBuilder redirectError(File file) { 820 return redirectError(Redirect.to(file)); 821 } 822 823 /** 824 * Returns this process builder's standard input source. 825 * 826 * Subprocesses subsequently started by this object's {@link #start()} 827 * method obtain their standard input from this source. 828 * The initial value is {@link Redirect#PIPE Redirect.PIPE}. 829 * 830 * @return this process builder's standard input source 831 * @since 1.7 832 */ 833 public Redirect redirectInput() { 834 return (redirects == null) ? Redirect.PIPE : redirects[0]; 835 } 836 837 /** 838 * Returns this process builder's standard output destination. 839 * 840 * Subprocesses subsequently started by this object's {@link #start()} 841 * method redirect their standard output to this destination. 842 * The initial value is {@link Redirect#PIPE Redirect.PIPE}. 843 * 844 * @return this process builder's standard output destination 845 * @since 1.7 846 */ 847 public Redirect redirectOutput() { 848 return (redirects == null) ? Redirect.PIPE : redirects[1]; 849 } 850 851 /** 852 * Returns this process builder's standard error destination. 853 * 854 * Subprocesses subsequently started by this object's {@link #start()} 855 * method redirect their standard error to this destination. 856 * The initial value is {@link Redirect#PIPE Redirect.PIPE}. 857 * 858 * @return this process builder's standard error destination 859 * @since 1.7 860 */ 861 public Redirect redirectError() { 862 return (redirects == null) ? Redirect.PIPE : redirects[2]; 863 } 864 865 /** 866 * Sets the source and destination for subprocess standard I/O 867 * to be the same as those of the current Java process. 868 * 869 * <p>This is a convenience method. An invocation of the form 870 * <pre> {@code 871 * pb.inheritIO() 872 * }</pre> 873 * behaves in exactly the same way as the invocation 874 * <pre> {@code 875 * pb.redirectInput(Redirect.INHERIT) 876 * .redirectOutput(Redirect.INHERIT) 877 * .redirectError(Redirect.INHERIT) 878 * }</pre> 879 * 880 * This gives behavior equivalent to most operating system 881 * command interpreters, or the standard C library function 882 * {@code system()}. 883 * 884 * @return this process builder 885 * @since 1.7 886 */ 887 public ProcessBuilder inheritIO() { 888 Arrays.fill(redirects(), Redirect.INHERIT); 889 return this; 890 } 891 892 /** 893 * Tells whether this process builder merges standard error and 894 * standard output. 895 * 896 * <p>If this property is {@code true}, then any error output 897 * generated by subprocesses subsequently started by this object's 898 * {@link #start()} method will be merged with the standard 899 * output, so that both can be read using the 900 * {@link Process#getInputStream()} method. This makes it easier 901 * to correlate error messages with the corresponding output. 902 * The initial value is {@code false}. 903 * 904 * @return this process builder's {@code redirectErrorStream} property 905 */ 906 public boolean redirectErrorStream() { 907 return redirectErrorStream; 908 } 909 910 /** 911 * Sets this process builder's {@code redirectErrorStream} property. 912 * 913 * <p>If this property is {@code true}, then any error output 914 * generated by subprocesses subsequently started by this object's 915 * {@link #start()} method will be merged with the standard 916 * output, so that both can be read using the 917 * {@link Process#getInputStream()} method. This makes it easier 918 * to correlate error messages with the corresponding output. 919 * The initial value is {@code false}. 920 * 921 * @param redirectErrorStream the new property value 922 * @return this process builder 923 */ 924 public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) { 925 this.redirectErrorStream = redirectErrorStream; 926 return this; 927 } 928 929 /** 930 * Starts a new process using the attributes of this process builder. 931 * 932 * <p>The new process will 933 * invoke the command and arguments given by {@link #command()}, 934 * in a working directory as given by {@link #directory()}, 935 * with a process environment as given by {@link #environment()}. 936 * 937 * <p>This method checks that the command is a valid operating 938 * system command. Which commands are valid is system-dependent, 939 * but at the very least the command must be a non-empty list of 940 * non-null strings. 941 * 942 * <p>A minimal set of system dependent environment variables may 943 * be required to start a process on some operating systems. 944 * As a result, the subprocess may inherit additional environment variable 945 * settings beyond those in the process builder's {@link #environment()}. 946 * 947 * <p>If there is a security manager, its 948 * {@link SecurityManager#checkExec checkExec} 949 * method is called with the first component of this object's 950 * {@code command} array as its argument. This may result in 951 * a {@link SecurityException} being thrown. 952 * 953 * <p>Starting an operating system process is highly system-dependent. 954 * Among the many things that can go wrong are: 955 * <ul> 956 * <li>The operating system program file was not found. 957 * <li>Access to the program file was denied. 958 * <li>The working directory does not exist. 959 * <li>Invalid character in command argument, such as NUL. 960 * </ul> 961 * 962 * <p>In such cases an exception will be thrown. The exact nature 963 * of the exception is system-dependent, but it will always be a 964 * subclass of {@link IOException}. 965 * 966 * <p>If the operating system does not support the creation of 967 * processes, an {@link UnsupportedOperationException} will be thrown. 968 * 969 * <p>Subsequent modifications to this process builder will not 970 * affect the returned {@link Process}. 971 * 972 * @return a new {@link Process} object for managing the subprocess 973 * 974 * @throws NullPointerException 975 * if an element of the command list is null 976 * 977 * @throws IndexOutOfBoundsException 978 * if the command is an empty list (has size {@code 0}) 979 * 980 * @throws SecurityException 981 * if a security manager exists and 982 * <ul> 983 * 984 * <li>its 985 * {@link SecurityManager#checkExec checkExec} 986 * method doesn't allow creation of the subprocess, or 987 * 988 * <li>the standard input to the subprocess was 989 * {@linkplain #redirectInput redirected from a file} 990 * and the security manager's 991 * {@link SecurityManager#checkRead(String) checkRead} method 992 * denies read access to the file, or 993 * 994 * <li>the standard output or standard error of the 995 * subprocess was 996 * {@linkplain #redirectOutput redirected to a file} 997 * and the security manager's 998 * {@link SecurityManager#checkWrite(String) checkWrite} method 999 * denies write access to the file 1000 * 1001 * </ul> 1002 * 1003 * @throws UnsupportedOperationException 1004 * If the operating system does not support the creation of processes. 1005 * 1006 * @throws IOException if an I/O error occurs 1007 * 1008 * @see Runtime#exec(String[], String[], java.io.File) 1009 */ 1010 public Process start() throws IOException { 1011 // Must convert to array first -- a malicious user-supplied 1012 // list might try to circumvent the security check. 1013 String[] cmdarray = command.toArray(new String[command.size()]); 1014 cmdarray = cmdarray.clone(); 1015 1016 for (String arg : cmdarray) 1017 if (arg == null) 1018 throw new NullPointerException(); 1019 // Throws IndexOutOfBoundsException if command is empty 1020 String prog = cmdarray[0]; 1021 1022 SecurityManager security = System.getSecurityManager(); 1023 if (security != null) 1024 security.checkExec(prog); 1025 1026 String dir = directory == null ? null : directory.toString(); 1027 1028 for (int i = 1; i < cmdarray.length; i++) { 1029 if (cmdarray[i].indexOf('\u0000') >= 0) { 1030 throw new IOException("invalid null character in command"); 1031 } 1032 } 1033 1034 try { 1035 return ProcessImpl.start(cmdarray, 1036 environment, 1037 dir, 1038 redirects, 1039 redirectErrorStream); 1040 } catch (IOException | IllegalArgumentException e) { 1041 String exceptionInfo = ": " + e.getMessage(); 1042 Throwable cause = e; 1043 if ((e instanceof IOException) && security != null) { 1044 // Can not disclose the fail reason for read-protected files. 1045 try { 1046 security.checkRead(prog); 1047 } catch (SecurityException se) { 1048 exceptionInfo = ""; 1049 cause = se; 1050 } 1051 } 1052 // It's much easier for us to create a high-quality error 1053 // message than the low-level C code which found the problem. 1054 throw new IOException( 1055 "Cannot run program \"" + prog + "\"" 1056 + (dir == null ? "" : " (in directory \"" + dir + "\")") 1057 + exceptionInfo, 1058 cause); 1059 } 1060 } 1061} 1062