1 /* 2 * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang; 27 28 import java.io.*; 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.List; 32 import java.util.concurrent.TimeUnit; 33 34 /** 35 * The {@link ProcessBuilder#start()} and 36 * {@link Runtime#exec(String[],String[],File) Runtime.exec} 37 * methods create a native process and return an instance of a 38 * subclass of {@code Process} that can be used to control the process 39 * and obtain information about it. The class {@code Process} 40 * provides methods for performing input from the process, performing 41 * output to the process, waiting for the process to complete, 42 * checking the exit status of the process, and destroying (killing) 43 * the process. 44 * 45 * <p>The methods that create processes may not work well for special 46 * processes on certain native platforms, such as native windowing 47 * processes, daemon processes, Win16/DOS processes on Microsoft 48 * Windows, or shell scripts. 49 * 50 * <p>By default, the created subprocess does not have its own terminal 51 * or console. All its standard I/O (i.e. stdin, stdout, stderr) 52 * operations will be redirected to the parent process, where they can 53 * be accessed via the streams obtained using the methods 54 * {@link #getOutputStream()}, 55 * {@link #getInputStream()}, and 56 * {@link #getErrorStream()}. 57 * The parent process uses these streams to feed input to and get output 58 * from the subprocess. Because some native platforms only provide 59 * limited buffer size for standard input and output streams, failure 60 * to promptly write the input stream or read the output stream of 61 * the subprocess may cause the subprocess to block, or even deadlock. 62 * 63 * <p>Where desired, <a href="ProcessBuilder.html#redirect-input"> 64 * subprocess I/O can also be redirected</a> 65 * using methods of the {@link ProcessBuilder} class. 66 * 67 * <p>The subprocess is not killed when there are no more references to 68 * the {@code Process} object, but rather the subprocess 69 * continues executing asynchronously. 70 * 71 * <p>There is no requirement that a process represented by a {@code 72 * Process} object execute asynchronously or concurrently with respect 73 * to the Java process that owns the {@code Process} object. 74 * 75 * <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way 76 * to create a {@code Process}. 77 * 78 * @since JDK1.0 79 */ 80 public abstract class Process { 81 82 /** 83 * Returns the output stream connected to the normal input of the 84 * subprocess. Output to the stream is piped into the standard 85 * input of the process represented by this {@code Process} object. 86 * 87 * <p>If the standard input of the subprocess has been redirected using 88 * {@link ProcessBuilder#redirectInput(Redirect) 89 * ProcessBuilder.redirectInput} 90 * then this method will return a 91 * <a href="ProcessBuilder.html#redirect-input">null output stream</a>. 92 * 93 * <p>Implementation note: It is a good idea for the returned 94 * output stream to be buffered. 95 * 96 * @return the output stream connected to the normal input of the 97 * subprocess 98 */ 99 public abstract OutputStream getOutputStream(); 100 101 /** 102 * Returns the input stream connected to the normal output of the 103 * subprocess. The stream obtains data piped from the standard 104 * output of the process represented by this {@code Process} object. 105 * 106 * <p>If the standard output of the subprocess has been redirected using 107 * {@link ProcessBuilder#redirectOutput(Redirect) 108 * ProcessBuilder.redirectOutput} 109 * then this method will return a 110 * <a href="ProcessBuilder.html#redirect-output">null input stream</a>. 111 * 112 * <p>Otherwise, if the standard error of the subprocess has been 113 * redirected using 114 * {@link ProcessBuilder#redirectErrorStream(boolean) 115 * ProcessBuilder.redirectErrorStream} 116 * then the input stream returned by this method will receive the 117 * merged standard output and the standard error of the subprocess. 118 * 119 * <p>Implementation note: It is a good idea for the returned 120 * input stream to be buffered. 121 * 122 * @return the input stream connected to the normal output of the 123 * subprocess 124 */ 125 public abstract InputStream getInputStream(); 126 127 /** 128 * Returns the input stream connected to the error output of the 129 * subprocess. The stream obtains data piped from the error output 130 * of the process represented by this {@code Process} object. 131 * 132 * <p>If the standard error of the subprocess has been redirected using 133 * {@link ProcessBuilder#redirectError(Redirect) 134 * ProcessBuilder.redirectError} or 135 * {@link ProcessBuilder#redirectErrorStream(boolean) 136 * ProcessBuilder.redirectErrorStream} 137 * then this method will return a 138 * <a href="ProcessBuilder.html#redirect-output">null input stream</a>. 139 * 140 * <p>Implementation note: It is a good idea for the returned 141 * input stream to be buffered. 142 * 143 * @return the input stream connected to the error output of 144 * the subprocess 145 */ 146 public abstract InputStream getErrorStream(); 147 148 /** 149 * Causes the current thread to wait, if necessary, until the 150 * process represented by this {@code Process} object has 151 * terminated. This method returns immediately if the subprocess 152 * has already terminated. If the subprocess has not yet 153 * terminated, the calling thread will be blocked until the 154 * subprocess exits. 155 * 156 * @return the exit value of the subprocess represented by this 157 * {@code Process} object. By convention, the value 158 * {@code 0} indicates normal termination. 159 * @throws InterruptedException if the current thread is 160 * {@linkplain Thread#interrupt() interrupted} by another 161 * thread while it is waiting, then the wait is ended and 162 * an {@link InterruptedException} is thrown. 163 */ 164 public abstract int waitFor() throws InterruptedException; 165 166 /** 167 * Causes the current thread to wait, if necessary, until the 168 * subprocess represented by this {@code Process} object has 169 * terminated, or the specified waiting time elapses. 170 * 171 * <p>If the subprocess has already terminated then this method returns 172 * immediately with the value {@code true}. If the process has not 173 * terminated and the timeout value is less than, or equal to, zero, then 174 * this method returns immediately with the value {@code false}. 175 * 176 * <p>The default implementation of this methods polls the {@code exitValue} 177 * to check if the process has terminated. Concrete implementations of this 178 * class are strongly encouraged to override this method with a more 179 * efficient implementation. 180 * 181 * @param timeout the maximum time to wait 182 * @param unit the time unit of the {@code timeout} argument 183 * @return {@code true} if the subprocess has exited and {@code false} if 184 * the waiting time elapsed before the subprocess has exited. 185 * @throws InterruptedException if the current thread is interrupted 186 * while waiting. 187 * @throws NullPointerException if unit is null 188 * @since 1.8 189 */ 190 public boolean waitFor(long timeout, TimeUnit unit) 191 throws InterruptedException 192 { 193 long startTime = System.nanoTime(); 194 long rem = unit.toNanos(timeout); 195 196 do { 197 try { 198 exitValue(); 199 return true; 200 } catch(IllegalThreadStateException ex) { 201 if (rem > 0) 202 Thread.sleep( 203 Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100)); 204 } 205 rem = unit.toNanos(timeout) - (System.nanoTime() - startTime); 206 } while (rem > 0); 207 return false; 208 } 209 210 /** 211 * Returns the exit value for the subprocess. 212 * 213 * @return the exit value of the subprocess represented by this 214 * {@code Process} object. By convention, the value 215 * {@code 0} indicates normal termination. 216 * @throws IllegalThreadStateException if the subprocess represented 217 * by this {@code Process} object has not yet terminated 218 */ 219 public abstract int exitValue(); 220 221 /** 222 * Kills the subprocess. Whether the subprocess represented by this 223 * {@code Process} object is forcibly terminated or not is 224 * implementation dependent. 225 */ 226 public abstract void destroy(); 227 228 /** 229 * Kills the subprocess. The subprocess represented by this 230 * {@code Process} object is forcibly terminated. 231 * 232 * <p>The default implementation of this method invokes {@link #destroy} 233 * and so may not forcibly terminate the process. Concrete implementations 234 * of this class are strongly encouraged to override this method with a 235 * compliant implementation. Invoking this method on {@code Process} 236 * objects returned by {@link ProcessBuilder#start} and 237 * {@link Runtime#exec} will forcibly terminate the process. 238 * 239 * <p>Note: The subprocess may not terminate immediately. 240 * i.e. {@code isAlive()} may return true for a brief period 241 * after {@code destroyForcibly()} is called. This method 242 * may be chained to {@code waitFor()} if needed. 243 * 244 * @return the {@code Process} object representing the 245 * subprocess to be forcibly destroyed. 246 * @since 1.8 247 */ 248 public Process destroyForcibly() { 249 destroy(); 250 return this; 251 } 252 253 /** 254 * Tests whether the subprocess represented by this {@code Process} is 255 * alive. 256 * 257 * @return {@code true} if the subprocess represented by this 258 * {@code Process} object has not yet terminated. 259 * @since 1.8 260 */ 261 public boolean isAlive() { 262 try { 263 exitValue(); 264 return false; 265 } catch(IllegalThreadStateException e) { 266 return true; 267 } 268 } 269 270 /** 271 * Returns the process id of the subprocess 272 * 273 * @return the process id or -1 if the process is not alive 274 * @since 1.8 275 */ 276 public abstract int getPid(); 277 278 /** 279 * Returns the process id of the current process. 280 * 281 * @return the process id of the current process. 282 * @since 1.8 283 * 284 **/ 285 public static native int getCurrentPid(); 286 287 public abstract String getProcessName(int pid); 288 289 /** 290 * @return the process name of the current process. 291 * @since 1.8 292 */ 293 public String getCurrentProcessName() { 294 return getProcessName( getCurrentPid() ); 295 } 296 297 /** 298 * @return the process name of this process or null if no longer live 299 * @since 1.8 300 */ 301 public String getProcessName() { 302 int pid = getPid(); 303 if (pid >=0) { 304 return getProcessName( getPid() ); 305 } else { 306 return null; 307 } 308 } 309 }