1 /*
  2  * Copyright (c) 1995, 2021, 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 jdk.internal.misc.Blocker;
 29 import jdk.internal.util.StaticProperty;
 30 
 31 import java.io.*;
 32 import java.lang.ProcessBuilder.Redirect;
 33 import java.nio.charset.Charset;
 34 import java.nio.charset.UnsupportedCharsetException;
 35 import java.util.Objects;
 36 import java.util.concurrent.CompletableFuture;
 37 import java.util.concurrent.ForkJoinPool;
 38 import java.util.concurrent.TimeUnit;
 39 import java.util.stream.Stream;
 40 
 41 /**
 42  * {@code Process} provides control of native processes started by
 43  * ProcessBuilder.start and Runtime.exec.
 44  * The class provides methods for performing input from the process, performing
 45  * output to the process, waiting for the process to complete,
 46  * checking the exit status of the process, and destroying (killing)
 47  * the process.
 48  * The {@link ProcessBuilder#start()} and
 49  * {@link Runtime#exec(String[],String[],File) Runtime.exec}
 50  * methods create a native process and return an instance of a
 51  * subclass of {@code Process} that can be used to control the process
 52  * and obtain information about it.
 53  *
 54  * <p>The methods that create processes may not work well for special
 55  * processes on certain native platforms, such as native windowing
 56  * processes, daemon processes, Win16/DOS processes on Microsoft
 57  * Windows, or shell scripts.
 58  *
 59  * <p>By default, the created process does not have its own terminal
 60  * or console.  All its standard I/O (i.e. stdin, stdout, stderr)
 61  * operations will be redirected to the parent process, where they can
 62  * be accessed via the streams obtained using the methods
 63  * {@link #getOutputStream()},
 64  * {@link #getInputStream()}, and
 65  * {@link #getErrorStream()}.
 66  * The I/O streams of characters and lines can be written and read using the methods
 67  * {@link #outputWriter()}, {@link #outputWriter(Charset)}},
 68  * {@link #inputReader()}, {@link #inputReader(Charset)},
 69  * {@link #errorReader()}, and {@link #errorReader(Charset)}.
 70  * The parent process uses these streams to feed input to and get output
 71  * from the process.  Because some native platforms only provide
 72  * limited buffer size for standard input and output streams, failure
 73  * to promptly write the input stream or read the output stream of
 74  * the process may cause the process to block, or even deadlock.
 75  *
 76  * <p>Where desired, <a href="ProcessBuilder.html#redirect-input">
 77  * process I/O can also be redirected</a>
 78  * using methods of the {@link ProcessBuilder} class.
 79  *
 80  * <p>The process is not killed when there are no more references to
 81  * the {@code Process} object, but rather the process
 82  * continues executing asynchronously.
 83  *
 84  * <p>There is no requirement that the process represented by a {@code
 85  * Process} object execute asynchronously or concurrently with respect
 86  * to the Java process that owns the {@code Process} object.
 87  *
 88  * <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way
 89  * to create a {@code Process}.
 90  *
 91  * <p>Subclasses of Process should override the {@link #onExit()} and
 92  * {@link #toHandle()} methods to provide a fully functional Process including the
 93  * {@linkplain #pid() process id},
 94  * {@linkplain #info() information about the process},
 95  * {@linkplain #children() direct children}, and
 96  * {@linkplain #descendants() direct children plus descendants of those children} of the process.
 97  * Delegating to the underlying Process or ProcessHandle is typically
 98  * easiest and most efficient.
 99  *
100  * @since   1.0
101  */
102 public abstract class Process {
103 
104     // Readers and Writers created for this process; so repeated calls return the same object
105     // All updates must be done while synchronized on this Process.
106     private BufferedWriter outputWriter;
107     private Charset outputCharset;
108     private BufferedReader inputReader;
109     private Charset inputCharset;
110     private BufferedReader errorReader;
111     private Charset errorCharset;
112 
113     /**
114      * Default constructor for Process.
115      */
116     public Process() {}
117 
118     /**
119      * Returns the output stream connected to the normal input of the
120      * process.  Output to the stream is piped into the standard
121      * input of the process represented by this {@code Process} object.
122      *
123      * <p>If the standard input of the process has been redirected using
124      * {@link ProcessBuilder#redirectInput(Redirect)
125      * ProcessBuilder.redirectInput}
126      * then this method will return a
127      * <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
128      *
129      * @apiNote
130      * When writing to both {@link #getOutputStream()} and either {@link #outputWriter()}
131      * or {@link #outputWriter(Charset)}, {@link BufferedWriter#flush BufferedWriter.flush}
132      * should be called before writes to the {@code OutputStream}.
133      *
134      * @implNote
135      * Implementation note: It is a good idea for the returned
136      * output stream to be buffered.
137      *
138      * @return the output stream connected to the normal input of the
139      *         process
140      */
141     public abstract OutputStream getOutputStream();
142 
143     /**
144      * Returns the input stream connected to the normal output of the
145      * process.  The stream obtains data piped from the standard
146      * output of the process represented by this {@code Process} object.
147      *
148      * <p>If the standard output of the process has been redirected using
149      * {@link ProcessBuilder#redirectOutput(Redirect)
150      * ProcessBuilder.redirectOutput}
151      * then this method will return a
152      * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
153      *
154      * <p>Otherwise, if the standard error of the process has been
155      * redirected using
156      * {@link ProcessBuilder#redirectErrorStream(boolean)
157      * ProcessBuilder.redirectErrorStream}
158      * then the input stream returned by this method will receive the
159      * merged standard output and the standard error of the process.
160      *
161      * @apiNote
162      * Use {@link #getInputStream()} and {@link #inputReader()} with extreme care.
163      * The {@code BufferedReader} may have buffered input from the input stream.
164      *
165      * @implNote
166      * Implementation note: It is a good idea for the returned
167      * input stream to be buffered.
168      *
169      * @return the input stream connected to the normal output of the
170      *         process
171      */
172     public abstract InputStream getInputStream();
173 
174     /**
175      * Returns the input stream connected to the error output of the
176      * process.  The stream obtains data piped from the error output
177      * of the process represented by this {@code Process} object.
178      *
179      * <p>If the standard error of the process has been redirected using
180      * {@link ProcessBuilder#redirectError(Redirect)
181      * ProcessBuilder.redirectError} or
182      * {@link ProcessBuilder#redirectErrorStream(boolean)
183      * ProcessBuilder.redirectErrorStream}
184      * then this method will return a
185      * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
186      *
187      * @apiNote
188      * Use {@link #getErrorStream()} and {@link #errorReader()} with extreme care.
189      * The {@code BufferedReader} may have buffered input from the error stream.
190      *
191      * @implNote
192      * Implementation note: It is a good idea for the returned
193      * input stream to be buffered.
194      *
195      * @return the input stream connected to the error output of
196      *         the process
197      */
198     public abstract InputStream getErrorStream();
199 
200     /**
201      * Returns a {@link BufferedReader BufferedReader} connected to the standard
202      * output of the process. The {@link Charset} for the native encoding is used
203      * to read characters, lines, or stream lines from standard output.
204      *
205      * <p>This method delegates to {@link #inputReader(Charset)} using the
206      * {@link Charset} named by the {@code native.encoding} system property.
207      * If the {@code native.encoding} is not a valid charset name or not supported
208      * the {@link Charset#defaultCharset()} is used.
209      *
210      * @return a {@link BufferedReader BufferedReader} using the
211      *          {@code native.encoding} if supported, otherwise, the
212      *          {@link Charset#defaultCharset()}
213      * @since 17
214      */
215     public final BufferedReader inputReader() {
216         return inputReader(CharsetHolder.nativeCharset());
217     }
218 
219     /**
220      * Returns a {@link BufferedReader BufferedReader} connected to the
221      * standard output of this process using a Charset.
222      * The {@code BufferedReader} can be used to read characters, lines,
223      * or stream lines of the standard output.
224      *
225      * <p>Characters are read by an InputStreamReader that reads and decodes bytes
226      * from this process {@link #getInputStream()}. Bytes are decoded to characters
227      * using the {@code charset}; malformed-input and unmappable-character
228      * sequences are replaced with the charset's default replacement.
229      * The {@code BufferedReader} reads and buffers characters from the InputStreamReader.
230      *
231      * <p>The first call to this method creates the {@link BufferedReader BufferedReader},
232      * if called again with the same {@code charset} the same {@code BufferedReader} is returned.
233      * It is an error to call this method again with a different {@code charset}.
234      *
235      * <p>If the standard output of the process has been redirected using
236      * {@link ProcessBuilder#redirectOutput(Redirect) ProcessBuilder.redirectOutput}
237      * then the {@code InputStreamReader} will be reading from a
238      * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
239      *
240      * <p>Otherwise, if the standard error of the process has been redirected using
241      * {@link ProcessBuilder#redirectErrorStream(boolean)
242      * ProcessBuilder.redirectErrorStream} then the input reader returned by
243      * this method will receive the merged standard output and the standard error
244      * of the process.
245      *
246      * @apiNote
247      * Using both {@link #getInputStream} and {@link #inputReader(Charset)} has
248      * unpredictable behavior since the buffered reader reads ahead from the
249      * input stream.
250      *
251      * <p>When the process has terminated, and the standard input has not been redirected,
252      * reading of the bytes available from the underlying stream is on a best effort basis and
253      * may be unpredictable.
254      *
255      * @param charset the {@code Charset} used to decode bytes to characters
256      * @return a {@code BufferedReader} for the standard output of the process using the {@code charset}
257      * @throws NullPointerException if the {@code charset} is {@code null}
258      * @throws IllegalStateException if called more than once with different charset arguments
259      * @since 17
260      */
261     public final BufferedReader inputReader(Charset charset) {
262         Objects.requireNonNull(charset, "charset");
263         synchronized (this) {
264             if (inputReader == null) {
265                 inputCharset = charset;
266                 inputReader = new BufferedReader(new InputStreamReader(getInputStream(), charset));
267             } else {
268                 if (!inputCharset.equals(charset))
269                     throw new IllegalStateException("BufferedReader was created with charset: " + inputCharset);
270             }
271             return inputReader;
272         }
273     }
274 
275     /**
276      * Returns a {@link BufferedReader BufferedReader} connected to the standard
277      * error of the process. The {@link Charset} for the native encoding is used
278      * to read characters, lines, or stream lines from standard error.
279      *
280      * <p>This method delegates to {@link #errorReader(Charset)} using the
281      * {@link Charset} named by the {@code native.encoding} system property.
282      * If the {@code native.encoding} is not a valid charset name or not supported
283      * the {@link Charset#defaultCharset()} is used.
284      *
285      * @return a {@link BufferedReader BufferedReader} using the
286      *          {@code native.encoding} if supported, otherwise, the
287      *          {@link Charset#defaultCharset()}
288      * @since 17
289      */
290     public final BufferedReader errorReader() {
291         return errorReader(CharsetHolder.nativeCharset());
292     }
293 
294     /**
295      * Returns a {@link BufferedReader BufferedReader} connected to the
296      * standard error of this process using a Charset.
297      * The {@code BufferedReader} can be used to read characters, lines,
298      * or stream lines of the standard error.
299      *
300      * <p>Characters are read by an InputStreamReader that reads and decodes bytes
301      * from this process {@link #getErrorStream()}. Bytes are decoded to characters
302      * using the {@code charset}; malformed-input and unmappable-character
303      * sequences are replaced with the charset's default replacement.
304      * The {@code BufferedReader} reads and buffers characters from the InputStreamReader.
305      *
306      * <p>The first call to this method creates the {@link BufferedReader BufferedReader},
307      * if called again with the same {@code charset} the same {@code BufferedReader} is returned.
308      * It is an error to call this method again with a different {@code charset}.
309      *
310      * <p>If the standard error of the process has been redirected using
311      * {@link ProcessBuilder#redirectError(Redirect) ProcessBuilder.redirectError} or
312      * {@link ProcessBuilder#redirectErrorStream(boolean) ProcessBuilder.redirectErrorStream}
313      * then the {@code InputStreamReader} will be reading from a
314      * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
315      *
316      * @apiNote
317      * Using both {@link #getErrorStream} and {@link #errorReader(Charset)} has
318      * unpredictable behavior since the buffered reader reads ahead from the
319      * error stream.
320      *
321      * <p>When the process has terminated, and the standard error has not been redirected,
322      * reading of the bytes available from the underlying stream is on a best effort basis and
323      * may be unpredictable.
324      *
325      * @param charset the {@code Charset} used to decode bytes to characters
326      * @return a {@code BufferedReader} for the standard error of the process using the {@code charset}
327      * @throws NullPointerException if the {@code charset} is {@code null}
328      * @throws IllegalStateException if called more than once with different charset arguments
329      * @since 17
330      */
331     public final BufferedReader errorReader(Charset charset) {
332         Objects.requireNonNull(charset, "charset");
333         synchronized (this) {
334             if (errorReader == null) {
335                 errorCharset = charset;
336                 errorReader = new BufferedReader(new InputStreamReader(getErrorStream(), charset));
337             } else {
338                 if (!errorCharset.equals(charset))
339                     throw new IllegalStateException("BufferedReader was created with charset: " + errorCharset);
340             }
341             return errorReader;
342         }
343     }
344 
345     /**
346      * Returns a {@code BufferedWriter} connected to the normal input of the process
347      * using the native encoding.
348      * Writes text to a character-output stream, buffering characters so as to provide
349      * for the efficient writing of single characters, arrays, and strings.
350      *
351      * <p>This method delegates to {@link #outputWriter(Charset)} using the
352      * {@link Charset} named by the {@code native.encoding} system property.
353      * If the {@code native.encoding} is not a valid charset name or not supported
354      * the {@link Charset#defaultCharset()} is used.
355      *
356      * @return a {@code BufferedWriter} to the standard input of the process using the charset
357      *          for the {@code native.encoding} system property
358      * @since 17
359      */
360     public final BufferedWriter outputWriter() {
361         return outputWriter(CharsetHolder.nativeCharset());
362     }
363 
364     /**
365      * Returns a {@code BufferedWriter} connected to the normal input of the process
366      * using a Charset.
367      * Writes text to a character-output stream, buffering characters so as to provide
368      * for the efficient writing of single characters, arrays, and strings.
369      *
370      * <p>Characters written by the writer are encoded to bytes using {@link OutputStreamWriter}
371      * and the {@link Charset} are written to the standard input of the process represented
372      * by this {@code Process}.
373      * Malformed-input and unmappable-character sequences are replaced with the charset's
374      * default replacement.
375      *
376      * <p>The first call to this method creates the {@link BufferedWriter BufferedWriter},
377      * if called again with the same {@code charset} the same {@code BufferedWriter} is returned.
378      * It is an error to call this method again with a different {@code charset}.
379      *
380      * <p>If the standard input of the process has been redirected using
381      * {@link ProcessBuilder#redirectInput(Redirect)
382      * ProcessBuilder.redirectInput} then the {@code OutputStreamWriter} writes to a
383      * <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
384      *
385      * @apiNote
386      * A {@linkplain BufferedWriter} writes characters, arrays of characters, and strings.
387      * Wrapping the {@link BufferedWriter} with a {@link PrintWriter} provides
388      * efficient buffering and formatting of primitives and objects as well as support
389      * for auto-flush on line endings.
390      * Call the {@link BufferedWriter#flush()} method to flush buffered output to the process.
391      * <p>
392      * When writing to both {@link #getOutputStream()} and either {@link #outputWriter()}
393      * or {@link #outputWriter(Charset)}, {@linkplain BufferedWriter#flush BufferedWriter.flush}
394      * should be called before writes to the {@code OutputStream}.
395      *
396      * @param charset the {@code Charset} to encode characters to bytes
397      * @return a {@code BufferedWriter} to the standard input of the process using the {@code charset}
398      * @throws NullPointerException if the {@code charset} is {@code null}
399      * @throws IllegalStateException if called more than once with different charset arguments
400      * @since 17
401      */
402     public final BufferedWriter outputWriter(Charset charset) {
403         Objects.requireNonNull(charset, "charset");
404         synchronized (this) {
405             if (outputWriter == null) {
406                 outputCharset = charset;
407                 outputWriter = new BufferedWriter(new OutputStreamWriter(getOutputStream(), charset));
408             } else {
409                 if (!outputCharset.equals(charset))
410                     throw new IllegalStateException("BufferedWriter was created with charset: " + outputCharset);
411             }
412             return outputWriter;
413         }
414     }
415 
416     /**
417      * Causes the current thread to wait, if necessary, until the
418      * process represented by this {@code Process} object has
419      * terminated.  This method returns immediately if the process
420      * has already terminated.  If the process has not yet
421      * terminated, the calling thread will be blocked until the
422      * process exits.
423      *
424      * @return the exit value of the process represented by this
425      *         {@code Process} object.  By convention, the value
426      *         {@code 0} indicates normal termination.
427      * @throws InterruptedException if the current thread is
428      *         {@linkplain Thread#interrupt() interrupted} by another
429      *         thread while it is waiting, then the wait is ended and
430      *         an {@link InterruptedException} is thrown.
431      */
432     public abstract int waitFor() throws InterruptedException;
433 
434     /**
435      * Causes the current thread to wait, if necessary, until the
436      * process represented by this {@code Process} object has
437      * terminated, or the specified waiting time elapses.
438      *
439      * <p>If the process has already terminated then this method returns
440      * immediately with the value {@code true}.  If the process has not
441      * terminated and the timeout value is less than, or equal to, zero, then
442      * this method returns immediately with the value {@code false}.
443      *
444      * <p>The default implementation of this method polls the {@code exitValue}
445      * to check if the process has terminated. Concrete implementations of this
446      * class are strongly encouraged to override this method with a more
447      * efficient implementation.
448      *
449      * @param timeout the maximum time to wait
450      * @param unit the time unit of the {@code timeout} argument
451      * @return {@code true} if the process has exited and {@code false} if
452      *         the waiting time elapsed before the process has exited.
453      * @throws InterruptedException if the current thread is interrupted
454      *         while waiting.
455      * @throws NullPointerException if unit is null
456      * @since 1.8
457      */
458     public boolean waitFor(long timeout, TimeUnit unit)
459         throws InterruptedException
460     {
461         long remainingNanos = unit.toNanos(timeout); // throw NPE before other conditions
462         if (hasExited())
463             return true;
464         if (timeout <= 0)
465             return false;
466 
467         long deadline = System.nanoTime() + remainingNanos;
468         do {
469             Thread.sleep(Math.min(TimeUnit.NANOSECONDS.toMillis(remainingNanos) + 1, 100));
470             if (hasExited())
471                 return true;
472             remainingNanos = deadline - System.nanoTime();
473         } while (remainingNanos > 0);
474 
475         return false;
476     }
477 
478     /**
479      * Returns the exit value for the process.
480      *
481      * @return the exit value of the process represented by this
482      *         {@code Process} object.  By convention, the value
483      *         {@code 0} indicates normal termination.
484      * @throws IllegalThreadStateException if the process represented
485      *         by this {@code Process} object has not yet terminated
486      */
487     public abstract int exitValue();
488 
489     /**
490      * Kills the process.
491      * Whether the process represented by this {@code Process} object is
492      * {@linkplain #supportsNormalTermination normally terminated} or not is
493      * implementation dependent.
494      * Forcible process destruction is defined as the immediate termination of a
495      * process, whereas normal termination allows the process to shut down cleanly.
496      * If the process is not alive, no action is taken.
497      * <p>
498      * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
499      * {@linkplain java.util.concurrent.CompletableFuture#complete completed}
500      * when the process has terminated.
501      */
502     public abstract void destroy();
503 
504     /**
505      * Kills the process forcibly. The process represented by this
506      * {@code Process} object is forcibly terminated.
507      * Forcible process destruction is defined as the immediate termination of a
508      * process, whereas normal termination allows the process to shut down cleanly.
509      * If the process is not alive, no action is taken.
510      * <p>
511      * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
512      * {@linkplain java.util.concurrent.CompletableFuture#complete completed}
513      * when the process has terminated.
514      * <p>
515      * Invoking this method on {@code Process} objects returned by
516      * {@link ProcessBuilder#start()} and {@link Runtime#exec} forcibly terminate
517      * the process.
518      *
519      * @implSpec
520      * The default implementation of this method invokes {@link #destroy}
521      * and so may not forcibly terminate the process.
522      * @implNote
523      * Concrete implementations of this class are strongly encouraged to override
524      * this method with a compliant implementation.
525      * @apiNote
526      * The process may not terminate immediately.
527      * i.e. {@code isAlive()} may return true for a brief period
528      * after {@code destroyForcibly()} is called. This method
529      * may be chained to {@code waitFor()} if needed.
530      *
531      * @return the {@code Process} object representing the
532      *         process forcibly destroyed
533      * @since 1.8
534      */
535     public Process destroyForcibly() {
536         destroy();
537         return this;
538     }
539 
540     /**
541      * Returns {@code true} if the implementation of {@link #destroy} is to
542      * normally terminate the process,
543      * Returns {@code false} if the implementation of {@code destroy}
544      * forcibly and immediately terminates the process.
545      * <p>
546      * Invoking this method on {@code Process} objects returned by
547      * {@link ProcessBuilder#start()} and {@link Runtime#exec} return
548      * {@code true} or {@code false} depending on the platform implementation.
549      *
550      * @implSpec
551      * This implementation throws an instance of
552      * {@link java.lang.UnsupportedOperationException} and performs no other action.
553      *
554      * @return {@code true} if the implementation of {@link #destroy} is to
555      *         normally terminate the process;
556      *         otherwise, {@link #destroy} forcibly terminates the process
557      * @throws UnsupportedOperationException if the Process implementation
558      *         does not support this operation
559      * @since 9
560      */
561     public boolean supportsNormalTermination() {
562         throw new UnsupportedOperationException(this.getClass()
563                 + ".supportsNormalTermination() not supported" );
564     }
565 
566     /**
567      * Tests whether the process represented by this {@code Process} is
568      * alive.
569      *
570      * @return {@code true} if the process represented by this
571      *         {@code Process} object has not yet terminated.
572      * @since 1.8
573      */
574     public boolean isAlive() {
575         return !hasExited();
576     }
577 
578     /**
579      * This is called from the default implementation of
580      * {@code waitFor(long, TimeUnit)}, which is specified to poll
581      * {@code exitValue()}.
582      */
583     private boolean hasExited() {
584         try {
585             exitValue();
586             return true;
587         } catch (IllegalThreadStateException e) {
588             return false;
589         }
590     }
591 
592     /**
593      * Returns the native process ID of the process.
594      * The native process ID is an identification number that the operating
595      * system assigns to the process.
596      *
597      * @implSpec
598      * The implementation of this method returns the process id as:
599      * {@link #toHandle toHandle().pid()}.
600      *
601      * @return the native process id of the process
602      * @throws UnsupportedOperationException if the Process implementation
603      *         does not support this operation
604      * @since 9
605      */
606     public long pid() {
607         return toHandle().pid();
608     }
609 
610     /**
611      * Returns a {@code CompletableFuture<Process>} for the termination of the Process.
612      * The {@link java.util.concurrent.CompletableFuture} provides the ability
613      * to trigger dependent functions or actions that may be run synchronously
614      * or asynchronously upon process termination.
615      * When the process has terminated the CompletableFuture is
616      * {@link java.util.concurrent.CompletableFuture#complete completed} regardless
617      * of the exit status of the process.
618      * <p>
619      * Calling {@code onExit().get()} waits for the process to terminate and returns
620      * the Process. The future can be used to check if the process is
621      * {@linkplain java.util.concurrent.CompletableFuture#isDone done} or to
622      * {@linkplain java.util.concurrent.CompletableFuture#get() wait} for it to terminate.
623      * {@linkplain java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling}
624      * the CompletableFuture does not affect the Process.
625      * <p>
626      * Processes returned from {@link ProcessBuilder#start()} override the
627      * default implementation to provide an efficient mechanism to wait
628      * for process exit.
629      *
630      * @apiNote
631      * Using {@link #onExit() onExit} is an alternative to
632      * {@link #waitFor() waitFor} that enables both additional concurrency
633      * and convenient access to the result of the Process.
634      * Lambda expressions can be used to evaluate the result of the Process
635      * execution.
636      * If there is other processing to be done before the value is used
637      * then {@linkplain #onExit onExit} is a convenient mechanism to
638      * free the current thread and block only if and when the value is needed.
639      * <br>
640      * For example, launching a process to compare two files and get a boolean if they are identical:
641      * <pre> {@code   Process p = new ProcessBuilder("cmp", "f1", "f2").start();
642      *    Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0);
643      *    ...
644      *    if (identical.get()) { ... }
645      * }</pre>
646      *
647      * @implSpec
648      * This implementation executes {@link #waitFor()} in a separate thread
649      * repeatedly until it returns successfully. If the execution of
650      * {@code waitFor} is interrupted, the thread's interrupt status is preserved.
651      * <p>
652      * When {@link #waitFor()} returns successfully the CompletableFuture is
653      * {@linkplain java.util.concurrent.CompletableFuture#complete completed} regardless
654      * of the exit status of the process.
655      *
656      * This implementation may consume a lot of memory for thread stacks if a
657      * large number of processes are waited for concurrently.
658      * <p>
659      * External implementations should override this method and provide
660      * a more efficient implementation. For example, to delegate to the underlying
661      * process, it can do the following:
662      * <pre>{@code
663      *    public CompletableFuture<Process> onExit() {
664      *       return delegate.onExit().thenApply(p -> this);
665      *    }
666      * }</pre>
667      * @apiNote
668      * The process may be observed to have terminated with {@link #isAlive}
669      * before the ComputableFuture is completed and dependent actions are invoked.
670      *
671      * @return a new {@code CompletableFuture<Process>} for the Process
672      *
673      * @since 9
674      */
675     public CompletableFuture<Process> onExit() {
676         return CompletableFuture.supplyAsync(this::waitForInternal);
677     }
678 
679     /**
680      * Wait for the process to exit by calling {@code waitFor}.
681      * If the thread is interrupted, remember the interrupted state to
682      * be restored before returning. Use ForkJoinPool.ManagedBlocker
683      * so that the number of workers in case ForkJoinPool is used is
684      * compensated when the thread blocks in waitFor().
685      *
686      * @return the Process
687      */
688     private Process waitForInternal() {
689         boolean interrupted = false;
690         while (true) {
691             try {
692                 ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() {
693                     @Override
694                     public boolean block() throws InterruptedException {
695                         waitFor();
696                         return true;
697                     }
698 
699                     @Override
700                     public boolean isReleasable() {
701                         return !isAlive();
702                     }
703                 });
704                 break;
705             } catch (InterruptedException x) {
706                 interrupted = true;
707             }
708         }
709         if (interrupted) {
710             Thread.currentThread().interrupt();
711         }
712         return this;
713     }
714 
715     /**
716      * Returns a ProcessHandle for the Process.
717      *
718      * {@code Process} objects returned by {@link ProcessBuilder#start()} and
719      * {@link Runtime#exec} implement {@code toHandle} as the equivalent of
720      * {@link ProcessHandle#of(long) ProcessHandle.of(pid)} including the
721      * check for a SecurityManager and {@code RuntimePermission("manageProcess")}.
722      *
723      * @implSpec
724      * This implementation throws an instance of
725      * {@link java.lang.UnsupportedOperationException} and performs no other action.
726      * Subclasses should override this method to provide a ProcessHandle for the
727      * process.  The methods {@link #pid}, {@link #info}, {@link #children},
728      * and {@link #descendants}, unless overridden, operate on the ProcessHandle.
729      *
730      * @return Returns a ProcessHandle for the Process
731      * @throws UnsupportedOperationException if the Process implementation
732      *         does not support this operation
733      * @throws SecurityException if a security manager has been installed and
734      *         it denies RuntimePermission("manageProcess")
735      * @since 9
736      */
737     public ProcessHandle toHandle() {
738         throw new UnsupportedOperationException(this.getClass()
739                 + ".toHandle() not supported");
740     }
741 
742     /**
743      * Returns a snapshot of information about the process.
744      *
745      * <p> A {@link ProcessHandle.Info} instance has accessor methods
746      * that return information about the process if it is available.
747      *
748      * @implSpec
749      * This implementation returns information about the process as:
750      * {@link #toHandle toHandle().info()}.
751      *
752      * @return a snapshot of information about the process, always non-null
753      * @throws UnsupportedOperationException if the Process implementation
754      *         does not support this operation
755      * @since 9
756      */
757     public ProcessHandle.Info info() {
758         return toHandle().info();
759     }
760 
761     /**
762      * Returns a snapshot of the direct children of the process.
763      * The parent of a direct child process is the process.
764      * Typically, a process that is {@linkplain #isAlive not alive} has no children.
765      * <p>
766      * <em>Note that processes are created and terminate asynchronously.
767      * There is no guarantee that a process is {@linkplain #isAlive alive}.
768      * </em>
769      *
770      * @implSpec
771      * This implementation returns the direct children as:
772      * {@link #toHandle toHandle().children()}.
773      *
774      * @return a sequential Stream of ProcessHandles for processes that are
775      *         direct children of the process
776      * @throws UnsupportedOperationException if the Process implementation
777      *         does not support this operation
778      * @throws SecurityException if a security manager has been installed and
779      *         it denies RuntimePermission("manageProcess")
780      * @since 9
781      */
782     public Stream<ProcessHandle> children() {
783         return toHandle().children();
784     }
785 
786     /**
787      * Returns a snapshot of the descendants of the process.
788      * The descendants of a process are the children of the process
789      * plus the descendants of those children, recursively.
790      * Typically, a process that is {@linkplain #isAlive not alive} has no children.
791      * <p>
792      * <em>Note that processes are created and terminate asynchronously.
793      * There is no guarantee that a process is {@linkplain #isAlive alive}.
794      * </em>
795      *
796      * @implSpec
797      * This implementation returns all children as:
798      * {@link #toHandle toHandle().descendants()}.
799      *
800      * @return a sequential Stream of ProcessHandles for processes that
801      *         are descendants of the process
802      * @throws UnsupportedOperationException if the Process implementation
803      *         does not support this operation
804      * @throws SecurityException if a security manager has been installed and
805      *         it denies RuntimePermission("manageProcess")
806      * @since 9
807      */
808     public Stream<ProcessHandle> descendants() {
809         return toHandle().descendants();
810     }
811 
812     /**
813      * An input stream for a subprocess pipe that skips by reading bytes
814      * instead of seeking, the underlying pipe does not support seek.
815      */
816     static class PipeInputStream extends FileInputStream {
817 
818         PipeInputStream(FileDescriptor fd) {
819             super(fd);
820         }
821 
822         @Override
823         public long skip(long n) throws IOException {
824             long remaining = n;
825             int nr;
826 
827             if (n <= 0) {
828                 return 0;
829             }
830 
831             int size = (int)Math.min(2048, remaining);
832             byte[] skipBuffer = new byte[size];
833             while (remaining > 0) {
834                 nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
835                 if (nr < 0) {
836                     break;
837                 }
838                 remaining -= nr;
839             }
840 
841             return n - remaining;
842         }
843 
844         @Override
845         public int read() throws IOException {
846             boolean attempted = Blocker.begin();
847             try {
848                 return super.read();
849             } finally {
850                 Blocker.end(attempted);
851             }
852         }
853 
854         @Override
855         public int read(byte[] b) throws IOException {
856             boolean attempted = Blocker.begin();
857             try {
858                 return super.read(b);
859             } finally {
860                 Blocker.end(attempted);
861             }
862         }
863 
864         @Override
865         public int read(byte[] b, int off, int len) throws IOException {
866             boolean attempted = Blocker.begin();
867             try {
868                 return super.read(b, off, len);
869             } finally {
870                 Blocker.end(attempted);
871             }
872         }
873     }
874 
875     /**
876      * An output stream for a subprocess pipe.
877      */
878     static class PipeOutputStream extends FileOutputStream {
879         PipeOutputStream(FileDescriptor fd) {
880             super(fd);
881         }
882 
883         @Override
884         public void write(int b) throws IOException {
885             boolean attempted = Blocker.begin();
886             try {
887                 super.write(b);
888             } finally {
889                 Blocker.end(attempted);
890             }
891         }
892 
893         @Override
894         public void write(byte[] b) throws IOException {
895             boolean attempted = Blocker.begin();
896             try {
897                 super.write(b);
898             } finally {
899                 Blocker.end(attempted);
900             }
901         }
902 
903         @Override
904         public void write(byte[] b, int off, int len) throws IOException {
905             boolean attempted = Blocker.begin();
906             try {
907                 super.write(b, off, len);
908             } finally {
909                 Blocker.end(attempted);
910             }
911         }
912     }
913 
914     /**
915      * A nested class to delay looking up the Charset for the native encoding.
916      */
917     private static class CharsetHolder {
918         private static final Charset nativeCharset;
919         static {
920             Charset cs;
921             try {
922                 cs = Charset.forName(StaticProperty.nativeEncoding());
923             } catch (UnsupportedCharsetException uce) {
924                 cs = Charset.defaultCharset();
925             }
926             nativeCharset = cs;
927         }
928 
929         /**
930          * Charset for the native encoding or {@link Charset#defaultCharset().
931          */
932         static Charset nativeCharset() {
933             return nativeCharset;
934         }
935     }
936 }