1 /* 2 * Copyright (c) 1995, 2015, 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.io.*; 29 import java.lang.ProcessBuilder.Redirect; 30 import java.nio.channels.Pipe; 31 import java.util.concurrent.CompletableFuture; 32 import java.util.concurrent.TimeUnit; 33 import java.util.stream.Stream; 34 35 /** 36 * {@code Process} provides control of native processes spawned by ProcessBuilder.start and Runtime.exec. 37 * The class provides methods for performing input from the process, performing 38 * output to the process, waiting for the process to complete, 39 * checking the exit status of the process, and destroying (killing) 40 * the process. 41 * The {@link ProcessBuilder#start()} and 42 * {@link Runtime#exec(String[],String[],File) Runtime.exec} 43 * methods create a native process and return an instance of a 44 * subclass of {@code Process} that can be used to control the process 45 * and obtain information about it. 46 * 47 * <p>The methods that create processes may not work well for special 48 * processes on certain native platforms, such as native windowing 49 * processes, daemon processes, Win16/DOS processes on Microsoft 50 * Windows, or shell scripts. 51 * 52 * <p>By default, the created subprocess does not have its own terminal 53 * or console. All its standard I/O (i.e. stdin, stdout, stderr) 54 * operations will be redirected to the parent process, where they can 55 * be accessed via the streams obtained using the methods 56 * {@link #getOutputStream()}, 57 * {@link #getInputStream()}, and 58 * {@link #getErrorStream()}. 59 * The parent process uses these streams to feed input to and get output 60 * from the subprocess. Because some native platforms only provide 61 * limited buffer size for standard input and output streams, failure 62 * to promptly write the input stream or read the output stream of 63 * the subprocess may cause the subprocess to block, or even deadlock. 64 * 65 * <p>Where desired, <a href="ProcessBuilder.html#redirect-input"> 66 * subprocess I/O can also be redirected</a> 67 * using methods of the {@link ProcessBuilder} class. 68 * 69 * <p>The subprocess is not killed when there are no more references to 70 * the {@code Process} object, but rather the subprocess 71 * continues executing asynchronously. 72 * 73 * <p>There is no requirement that a process represented by a {@code 74 * Process} object execute asynchronously or concurrently with respect 75 * to the Java process that owns the {@code Process} object. 76 * 77 * <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way 78 * to create a {@code Process}. 79 * 80 * @since 1.0 81 */ 82 public abstract class Process { 83 /** 84 * Default constructor for Process. 85 */ 86 public Process() {} 87 88 /** 89 * Returns the output stream connected to the normal input of the 90 * subprocess. Output to the stream is piped into the standard 91 * input of the process represented by this {@code Process} object. 92 * 93 * <p>If the standard input of the subprocess has been redirected using 94 * {@link ProcessBuilder#redirectInput(Redirect) 95 * ProcessBuilder.redirectInput} 96 * then this method will return a 97 * <a href="ProcessBuilder.html#redirect-input">null output stream</a>. 98 * 99 * <p>Implementation note: It is a good idea for the returned 100 * output stream to be buffered. 101 * 102 * @return the output stream connected to the normal input of the 103 * subprocess 104 */ 105 public abstract OutputStream getOutputStream(); 106 107 /** 108 * Returns the input stream connected to the normal output of the 109 * subprocess. The stream obtains data piped from the standard 110 * output of the process represented by this {@code Process} object. 111 * 112 * <p>If the standard output of the subprocess has been redirected using 113 * {@link ProcessBuilder#redirectOutput(Redirect) 114 * ProcessBuilder.redirectOutput} 115 * then this method will return a 116 * <a href="ProcessBuilder.html#redirect-output">null input stream</a>. 117 * 118 * <p>Otherwise, if the standard error of the subprocess has been 119 * redirected using 120 * {@link ProcessBuilder#redirectErrorStream(boolean) 121 * ProcessBuilder.redirectErrorStream} 122 * then the input stream returned by this method will receive the 123 * merged standard output and the standard error of the subprocess. 124 * 125 * <p>Implementation note: It is a good idea for the returned 126 * input stream to be buffered. 127 * 128 * @return the input stream connected to the normal output of the 129 * subprocess 130 */ 131 public abstract InputStream getInputStream(); 132 133 /** 134 * Returns the input stream connected to the error output of the 135 * subprocess. The stream obtains data piped from the error output 136 * of the process represented by this {@code Process} object. 137 * 138 * <p>If the standard error of the subprocess has been redirected using 139 * {@link ProcessBuilder#redirectError(Redirect) 140 * ProcessBuilder.redirectError} or 141 * {@link ProcessBuilder#redirectErrorStream(boolean) 142 * ProcessBuilder.redirectErrorStream} 143 * then this method will return a 144 * <a href="ProcessBuilder.html#redirect-output">null input stream</a>. 145 * 146 * <p>Implementation note: It is a good idea for the returned 147 * input stream to be buffered. 148 * 149 * @return the input stream connected to the error output of 150 * the subprocess 151 */ 152 public abstract InputStream getErrorStream(); 153 154 /** 155 * Returns the output channel connected to the normal input of the 156 * subprocess if and only if it has been redirected using 157 * {@link ProcessBuilder#redirectInput ProcessBuilder.redirectInput}( 158 * {@link Redirect#PIPE_CHANNEL} 159 * ). 160 * It returns {@code null} otherwise. 161 * <p> Output to the channel is piped into the standard 162 * input of the process represented by this {@code Process} object 163 * <p> It is the user's responsibility to obtain the output channel and 164 * close it if {@code PIPE_CHANNEL} redirection has been used. 165 * 166 * @return the output channel connected to the normal input of the 167 * subprocess if redirected to {@code PIPE_CHANNEL} or null otherwise 168 * @since 1.9 169 */ 170 public Pipe.SinkChannel getOutputChannel() { 171 return null; 172 } 173 174 /** 175 * Returns the input channel connected to the normal output of the 176 * subprocess if and only if it has been redirected using 177 * {@link ProcessBuilder#redirectOutput ProcessBuilder.redirectOutput}( 178 * {@link Redirect#PIPE_CHANNEL} 179 * ). 180 * It returns {@code null} otherwise. 181 * <p> The channel obtains data piped from the standard 182 * output of the process represented by this {@code Process} object. 183 * <p> It is the user's responsibility to obtain the input channel and 184 * close it if {@code PIPE_CHANNEL} redirection has been used. 185 * <p> If the standard error of the subprocess has been 186 * redirected using 187 * {@link ProcessBuilder#redirectErrorStream(boolean) 188 * ProcessBuilder.redirectErrorStream} 189 * then the input channel returned by this method will receive the 190 * merged standard output and the standard error of the subprocess. 191 * 192 * @return the input channel connected to the normal output of the 193 * subprocess if redirected from {@code PIPE_CHANNEL} or 194 * null otherwise 195 * @since 1.9 196 */ 197 public Pipe.SourceChannel getInputChannel() { 198 return null; 199 } 200 201 /** 202 * Returns the input channel connected to the error output of the 203 * subprocess if and only if it has been redirected using 204 * {@link ProcessBuilder#redirectError ProcessBuilder.redirectError}( 205 * {@link Redirect#PIPE_CHANNEL} 206 * ) and has not been redirected using 207 * {@link ProcessBuilder#redirectErrorStream(boolean) 208 * ProcessBuilder.redirectErrorStream}. It returns {@code null} otherwise. 209 * <p> The channel obtains data piped from the error 210 * output of the process represented by this {@code Process} object. 211 * <p> It is the user's responsibility to obtain the error channel and 212 * close it if {@code PIPE_CHANNEL} redirection has been used. 213 * 214 * @return the input channel connected to the error output of the 215 * subprocess if redirected from {@code PIPE_CHANNEL} or 216 * null otherwise 217 * @since 1.9 218 */ 219 public Pipe.SourceChannel getErrorChannel() { 220 return null; 221 } 222 223 /** 224 * Causes the current thread to wait, if necessary, until the 225 * process represented by this {@code Process} object has 226 * terminated. This method returns immediately if the subprocess 227 * has already terminated. If the subprocess has not yet 228 * terminated, the calling thread will be blocked until the 229 * subprocess exits. 230 * 231 * @return the exit value of the subprocess represented by this 232 * {@code Process} object. By convention, the value 233 * {@code 0} indicates normal termination. 234 * @throws InterruptedException if the current thread is 235 * {@linkplain Thread#interrupt() interrupted} by another 236 * thread while it is waiting, then the wait is ended and 237 * an {@link InterruptedException} is thrown. 238 */ 239 public abstract int waitFor() throws InterruptedException; 240 241 /** 242 * Causes the current thread to wait, if necessary, until the 243 * subprocess represented by this {@code Process} object has 244 * terminated, or the specified waiting time elapses. 245 * 246 * <p>If the subprocess has already terminated then this method returns 247 * immediately with the value {@code true}. If the process has not 248 * terminated and the timeout value is less than, or equal to, zero, then 249 * this method returns immediately with the value {@code false}. 250 * 251 * <p>The default implementation of this methods polls the {@code exitValue} 252 * to check if the process has terminated. Concrete implementations of this 253 * class are strongly encouraged to override this method with a more 254 * efficient implementation. 255 * 256 * @param timeout the maximum time to wait 257 * @param unit the time unit of the {@code timeout} argument 258 * @return {@code true} if the subprocess has exited and {@code false} if 259 * the waiting time elapsed before the subprocess has exited. 260 * @throws InterruptedException if the current thread is interrupted 261 * while waiting. 262 * @throws NullPointerException if unit is null 263 * @since 1.8 264 */ 265 public boolean waitFor(long timeout, TimeUnit unit) 266 throws InterruptedException 267 { 268 long startTime = System.nanoTime(); 269 long rem = unit.toNanos(timeout); 270 271 do { 272 try { 273 exitValue(); 274 return true; 275 } catch(IllegalThreadStateException ex) { 276 if (rem > 0) 277 Thread.sleep( 278 Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100)); 279 } 280 rem = unit.toNanos(timeout) - (System.nanoTime() - startTime); 281 } while (rem > 0); 282 return false; 283 } 284 285 /** 286 * Returns the exit value for the subprocess. 287 * 288 * @return the exit value of the subprocess represented by this 289 * {@code Process} object. By convention, the value 290 * {@code 0} indicates normal termination. 291 * @throws IllegalThreadStateException if the subprocess represented 292 * by this {@code Process} object has not yet terminated 293 */ 294 public abstract int exitValue(); 295 296 /** 297 * Kills the subprocess. 298 * Whether the process represented by this {@code Process} object is 299 * {@link #supportsDestroyForcibly forcibly terminated} or not is 300 * implementation dependent. 301 * Forcible process destruction is defined as the immediate termination of a process, 302 * whereas regular destruction allows a process to shut down cleanly. 303 * If the process is not alive, no action is taken. 304 * <p> 305 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is 306 * {@link java.util.concurrent.CompletableFuture#complete completed} when the process has terminated. 307 */ 308 public abstract void destroy(); 309 310 /** 311 * Kills the subprocess. The subprocess represented by this 312 * {@code Process} object is forcibly terminated. 313 * 314 * <p>The default implementation of this method invokes {@link #destroy} 315 * and so may not forcibly terminate the process. 316 * Concrete implementations of this class are strongly encouraged to override 317 * this method with a compliant implementation. 318 * Invoking this method on {@code Process} objects returned by {@link ProcessBuilder#start} and 319 * {@link Runtime#exec} forcibly terminate the process. 320 * <p> 321 * Forcible process destruction is defined as the immediate termination of a process, 322 * whereas regular destruction allows a process to shut down cleanly. 323 * If the process is not alive, no action is taken. 324 * <p> 325 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is 326 * {@link java.util.concurrent.CompletableFuture#complete completed} when the process has terminated. 327 * 328 * <p>Note: The subprocess may not terminate immediately. 329 * i.e. {@code isAlive()} may return true for a brief period 330 * after {@code destroyForcibly()} is called. This method 331 * may be chained to {@code waitFor()} if needed. 332 * 333 * @return the {@code Process} object representing the 334 * subprocess to be forcibly destroyed. 335 * @since 1.8 336 */ 337 public Process destroyForcibly() { 338 destroy(); 339 return this; 340 } 341 342 /** 343 * Returns {@code true} if the implementation of {@link #destroy} is forcible. 344 * Forcible process destruction is defined as the immediate termination of a process. 345 * Returns {@code false} if the implementation of {@code destroy} 346 * allows a process to shut down cleanly. 347 * 348 * @implSpec 349 * Processes returned from ProcessBuilder support this operation to 350 * return true or false depending on the platform implementation. 351 * 352 * @return {@code true} if the implementation of {@link #destroy} is forcible; 353 * otherwise {@code false} 354 * @throws UnsupportedOperationException if the Process implementation 355 * does not support this operation 356 * @since 1.9 357 */ 358 public boolean supportsDestroyForcibly() { 359 throw new UnsupportedOperationException("supportsDestroyForcibly not supported for " + this.getClass().toString()); 360 } 361 362 /** 363 * Tests whether the subprocess represented by this {@code Process} is 364 * alive. 365 * 366 * @return {@code true} if the subprocess represented by this 367 * {@code Process} object has not yet terminated. 368 * @since 1.8 369 */ 370 public boolean isAlive() { 371 try { 372 exitValue(); 373 return false; 374 } catch(IllegalThreadStateException e) { 375 return true; 376 } 377 } 378 379 /** 380 * Returns the native process ID of the subprocess. 381 * The native process ID is an identification number that the operating 382 * system assigns to the process. 383 * 384 * @implSpec 385 * The Process instances created by {@link ProcessBuilder ProcessBuilder} return the process id 386 * equivalent to {@code toHandle().getPid()}. 387 * 388 * @implNote 389 * The implementation of this method returns the pid from {@link #toHandle toHandle.getPid()}. 390 * Override to provide the pid of the Process. 391 * @return the native process id of the subprocess 392 * @throws UnsupportedOperationException if the Process implementation 393 * does not support this operation 394 * @since 1.9 395 */ 396 public long getPid() { 397 return toHandle().getPid(); 398 } 399 400 /** 401 * Returns a {@code CompletableFuture<Process>} for the termination of the Process. 402 * The {@link java.util.concurrent.CompletableFuture} provides the ability 403 * to trigger dependent functions or actions that may be run synchronously 404 * or asynchronously upon process termination. 405 * When the process terminates the CompletableFuture is 406 * {@link java.util.concurrent.CompletableFuture#complete completed} regardless 407 * of the exit status of the process. 408 * <p> 409 * Calling {@code onExit().get()} waits for the process to terminate and returns 410 * the Process. The future can be used to check if the process is 411 * {@link java.util.concurrent.CompletableFuture#isDone done} or to 412 * {@link java.util.concurrent.CompletableFuture#get() wait} for it to terminate. 413 * {@link java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling} 414 * the CompletableFuture does not affect the Process. 415 * <p> 416 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} 417 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}. 418 * <p> 419 * @apiNote 420 * Using {@link #onExit() onExit} is an alternative to 421 * {@link #waitFor() waitFor} that enables both additional concurrency 422 * and convenient access to the result of a Process. 423 * Lambdas can be used to evaluate the result of the Process execution and 424 * provide a functional. 425 * If there is other processing to be done before the value is used 426 * then {@linkplain #onExit onExit} is a convenient mechanism to 427 * free the current thread and block only if and when the value is needed. 428 * <br> 429 * For example, launching a process to compare two files and get a boolean if they are identical: 430 * <pre> {@code Process p = new ProcessBuilder("cmp", "f1", "f2").start(); 431 * Future<Boolean> identical = p.onExit().thenApply((p1) -> (p1.exitValue() == 0)); 432 * ... 433 * if (identical.get()) { ... } 434 * }</pre> 435 * 436 * @implNote 437 * The default implementation of this method employs a thread to 438 * {@link #waitFor() wait} for process exit, 439 * which may consume a lot of memory for thread stacks if a 440 * large number of processes are waited for concurrently. 441 * <p> 442 * External implementations are advised to override this method and provide 443 * more efficient implementation. For example, to delegate to the underlying 444 * process, it can simply do the following: 445 * <pre>{@code 446 * public CompletableFuture<Process> onExit() { 447 * return delegate.onExit(); 448 * } 449 * }</pre> 450 * ...which in case of implementation of the delegate is used. 451 * 452 * @return a {@code CompletableFuture<Process>} for the Process; 453 * a unique instance is returned for each call to {@code onExit}. 454 * 455 * @since 1.9 456 */ 457 public CompletableFuture<Process> onExit() { 458 return CompletableFuture.supplyAsync(() -> { 459 boolean interrupted = false; 460 while (true) { 461 try { 462 waitFor(); 463 break; 464 } catch (InterruptedException x) { 465 interrupted = true; 466 } 467 } 468 if (interrupted) { 469 Thread.currentThread().interrupt(); 470 } 471 return this; 472 }, ProcessHandleImpl.asyncExecutor()); 473 } 474 475 /** 476 * Returns a ProcessHandle for the Process. 477 * 478 * @implSpec 479 * The Process instances created by {@link ProcessBuilder ProcessBuilder} 480 * return a ProcessHandle equivalent to {@code ProcessHandle.of(pid)}. 481 * 482 * @implNote 483 * The implementation of this method throws 484 * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}. 485 * Concrete implementations of this class are strongly encouraged to override 486 * this method with a compliant implementation. 487 * @return Returns a ProcessHandle for the Process 488 * @throws UnsupportedOperationException if the Process implementation 489 * does not support this operation 490 * @since 1.9 491 */ 492 public ProcessHandle toHandle() { 493 throw new UnsupportedOperationException("toHandle not supported for " + this.getClass().toString()); 494 } 495 496 /** 497 * Returns a snapshot of information about the process. 498 * 499 * @implSpec 500 * The Process instances created by {@link ProcessBuilder ProcessBuilder} 501 * return a ProcessHandle.Info equivalent to {@code toHandle().info()}. 502 * 503 * <p> An {@code Info} instance has various accessor methods that return 504 * information about the process, if the process is alive and the 505 * information is available, otherwise they return {@code null}. 506 * 507 * @return a snapshot of the information about the process; non-null 508 * @throws UnsupportedOperationException if the Process implementation 509 * does not support this operation 510 * @since 1.9 511 */ 512 public ProcessHandle.Info info() { 513 return toHandle().info(); 514 } 515 516 /** 517 * Returns a snapshot of the direct children of the process. 518 * A process that is {@link #isAlive not alive} has zero children. 519 * <p> 520 * <em>Note that processes are created and terminate asynchronously. 521 * There is no guarantee that a process is {@link #isAlive alive}. 522 * </em> 523 * 524 * @implSpec 525 * The Process instances created by {@link ProcessBuilder ProcessBuilder} 526 * return a {@code Stream<ProcessHandle>} equivalent to {@code toHandle().children()}. 527 * 528 * @return a Stream of ProcessHandles for processes that are direct children 529 * of the process 530 * @throws UnsupportedOperationException if the Process implementation 531 * does not support this operation 532 * @throws SecurityException if a security manager has been installed and 533 * it denies RuntimePermission("manageProcess") 534 */ 535 public Stream<ProcessHandle> children() { 536 return toHandle().children(); 537 } 538 539 /** 540 * Returns a snapshot of the direct and indirect children of the process. 541 * A process that is {@link #isAlive not alive} has zero children. 542 * <p> 543 * <em>Note that processes are created and terminate asynchronously. 544 * There is no guarantee that a process is {@link #isAlive alive}. 545 * </em> 546 * 547 * @implSpec 548 * The Process instances created by {@link ProcessBuilder ProcessBuilder} 549 * return a {@code Stream<ProcessHandle>} equivalent to {@code toHandle().allChildren()}. 550 * 551 * @return a Stream of ProcessHandles for processes that are direct and 552 * indirect children of the process 553 * @throws UnsupportedOperationException if the Process implementation 554 * does not support this operation 555 * @throws SecurityException if a security manager has been installed and 556 * it denies RuntimePermission("manageProcess") 557 */ 558 public Stream<ProcessHandle> allChildren() { 559 return toHandle().allChildren(); 560 } 561 562 563 }