src/share/classes/java/lang/Process.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 24,33 **** --- 24,34 ---- */ package java.lang; import java.io.*; + import java.util.concurrent.TimeUnit; /** * The {@link ProcessBuilder#start()} and * {@link Runtime#exec(String[],String[],File) Runtime.exec} * methods create a native process and return an instance of a
*** 89,99 **** * output stream to be buffered. * * @return the output stream connected to the normal input of the * subprocess */ ! abstract public OutputStream getOutputStream(); /** * Returns the input stream connected to the normal output of the * subprocess. The stream obtains data piped from the standard * output of the process represented by this {@code Process} object. --- 90,100 ---- * output stream to be buffered. * * @return the output stream connected to the normal input of the * subprocess */ ! public abstract OutputStream getOutputStream(); /** * Returns the input stream connected to the normal output of the * subprocess. The stream obtains data piped from the standard * output of the process represented by this {@code Process} object.
*** 115,125 **** * input stream to be buffered. * * @return the input stream connected to the normal output of the * subprocess */ ! abstract public InputStream getInputStream(); /** * Returns the input stream connected to the error output of the * subprocess. The stream obtains data piped from the error output * of the process represented by this {@code Process} object. --- 116,126 ---- * input stream to be buffered. * * @return the input stream connected to the normal output of the * subprocess */ ! public abstract InputStream getInputStream(); /** * Returns the input stream connected to the error output of the * subprocess. The stream obtains data piped from the error output * of the process represented by this {@code Process} object.
*** 136,146 **** * input stream to be buffered. * * @return the input stream connected to the error output of * the subprocess */ ! abstract public InputStream getErrorStream(); /** * Causes the current thread to wait, if necessary, until the * process represented by this {@code Process} object has * terminated. This method returns immediately if the subprocess --- 137,147 ---- * input stream to be buffered. * * @return the input stream connected to the error output of * the subprocess */ ! public abstract InputStream getErrorStream(); /** * Causes the current thread to wait, if necessary, until the * process represented by this {@code Process} object has * terminated. This method returns immediately if the subprocess
*** 154,177 **** * @throws InterruptedException if the current thread is * {@linkplain Thread#interrupt() interrupted} by another * thread while it is waiting, then the wait is ended and * an {@link InterruptedException} is thrown. */ ! abstract public int waitFor() throws InterruptedException; /** * Returns the exit value for the subprocess. * * @return the exit value of the subprocess represented by this * {@code Process} object. By convention, the value * {@code 0} indicates normal termination. * @throws IllegalThreadStateException if the subprocess represented * by this {@code Process} object has not yet terminated */ ! abstract public int exitValue(); /** * Kills the subprocess. The subprocess represented by this * {@code Process} object is forcibly terminated. */ ! abstract public void destroy(); } --- 155,289 ---- * @throws InterruptedException if the current thread is * {@linkplain Thread#interrupt() interrupted} by another * thread while it is waiting, then the wait is ended and * an {@link InterruptedException} is thrown. */ ! public abstract int waitFor() throws InterruptedException; /** + * Causes the current thread to wait until the subprocess represented by + * this {@code Process} has terminated, unless the thread is + * {@linkplain Thread#interrupt interrupted}, or the specified waiting time + * elapses. + * + * <p>If the subprocess has already exited then this method returns + * immediately with the value {@code true}. If the process has not exited + * and the timeout is zero then this method returns immediately with the + * value {@code false} + * + * <p>If the subprocess has not exited then the current + * thread becomes disabled for thread scheduling purposes and lies + * dormant until one of three things happen: + * <ul> + * <li>The subprocess exits; or + * <li>Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * + * <p>If the subprocess terminates then the method returns with the + * value {@code true}. + * + * <p>If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is {@linkplain Thread#interrupt interrupted} while waiting, + * </ul> + * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * <p>If the specified waiting time elapses and the subprocess has not + * exited then the value {@code false} is returned. If the time is less + * than or equal to zero, the method will not wait at all. + * + * <p>The default implementation of this method polls {@code exitValue()} + * and repeatedly catches the resulting {@code IllegalThreadStateException} + * until the {@code timeout} expires or the subprocess is terminated. + * Implementations are strongly encouraged to override this method. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the {@code timeout} argument + * @return {@code true} if the subprocess has exited and {@code false} if + * the waiting time elapsed before the subprocess has exited. + * @throws InterruptedException if the current thread is interrupted + * while waiting + * @since 1.8 + */ + public boolean waitFor(long timeout, TimeUnit unit) + throws InterruptedException { + long now = System.nanoTime(); + + long end = now + TimeUnit.NANOSECONDS.convert(timeout, unit); + if (end <= 0) // overflow + end = Long.MAX_VALUE; + + long rem = end - now; + do { + try { + exitValue(); + return true; + } catch(IllegalThreadStateException ex) { + if(rem > 0) Thread.sleep(rem < 100 ? rem : 100); + } + rem = end - System.nanoTime(); + } while(rem > 0); + return false; + } + + /** * Returns the exit value for the subprocess. * * @return the exit value of the subprocess represented by this * {@code Process} object. By convention, the value * {@code 0} indicates normal termination. * @throws IllegalThreadStateException if the subprocess represented * by this {@code Process} object has not yet terminated */ ! public abstract int exitValue(); /** + * Kills the subprocess. Whether the subprocess represented by this + * {@code Process} object is forcibly terminated or not is + * implementation dependent. + */ + public abstract void destroy(); + + /** * Kills the subprocess. The subprocess represented by this * {@code Process} object is forcibly terminated. + * + * <p>The default implementation of this method invokes {@link #destroy()} + * and so is implementation dependent as to whether it terminates the + * process forcibly or not. Implementations are strongly encouraged to + * override this method. + * + * <p>Note: The subprocess may not terminate immediately. + * i.e. {@code isAlive()} may return true for a brief period + * after {@code destroyForcibly()} is called, however this method + * may be chained to {@code waitFor()} if needed. + * + * @return the {@code Process} object representing the + * subprocess to be forcibly destroyed. + * @since 1.8 */ ! public Process destroyForcibly() { ! destroy(); ! return this; ! } ! ! /** ! * Tests whether the subprocess represented by this {@code Process} is ! * alive. ! * ! * @return {@code true} if the subprocess represented by this ! * {@code Process} object has not yet terminated. ! * @since 1.8 ! */ ! public boolean isAlive() { ! try { ! exitValue(); ! return false; ! } catch(IllegalThreadStateException e) { ! return true; ! } ! } }