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 }