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