1 /*
2 * Copyright (c) 1995, 2010, 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.IOException;
29 import java.io.File;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.io.FileInputStream;
33 import java.io.FileOutputStream;
34 import java.io.FileDescriptor;
35 import java.io.BufferedInputStream;
36 import java.io.BufferedOutputStream;
37 import java.lang.ProcessBuilder.Redirect;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40
41 /* This class is for the exclusive use of ProcessBuilder.start() to
42 * create new processes.
43 *
44 * @author Martin Buchholz
45 * @since 1.5
46 */
47
48 final class ProcessImpl extends Process {
49 private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
50 = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
51
52 /**
53 * Open a file for writing. If {@code append} is {@code true} then the file
54 * is opened for atomic append directly and a FileOutputStream constructed
55 * with the resulting handle. This is because a FileOutputStream created
56 * to append to a file does not open the file in a manner that guarantees
57 * that writes by the child process will be atomic.
58 */
59 private static FileOutputStream newFileOutputStream(File f, boolean append)
237 closeHandle(handle);
238 }
239
240 private static final int STILL_ACTIVE = getStillActive();
241 private static native int getStillActive();
242
243 public int exitValue() {
244 int exitCode = getExitCodeProcess(handle);
245 if (exitCode == STILL_ACTIVE)
246 throw new IllegalThreadStateException("process has not exited");
247 return exitCode;
248 }
249 private static native int getExitCodeProcess(long handle);
250
251 public int waitFor() throws InterruptedException {
252 waitForInterruptibly(handle);
253 if (Thread.interrupted())
254 throw new InterruptedException();
255 return exitValue();
256 }
257 private static native void waitForInterruptibly(long handle);
258
259 public void destroy() { terminateProcess(handle); }
260 private static native void terminateProcess(long handle);
261
262 /**
263 * Create a process using the win32 function CreateProcess.
264 *
265 * @param cmdstr the Windows commandline
266 * @param envblock NUL-separated, double-NUL-terminated list of
267 * environment strings in VAR=VALUE form
268 * @param dir the working directory of the process, or null if
269 * inheriting the current directory from the parent process
270 * @param stdHandles array of windows HANDLEs. Indexes 0, 1, and
271 * 2 correspond to standard input, standard output and
272 * standard error, respectively. On input, a value of -1
273 * means to create a pipe to connect child and parent
274 * processes. On output, a value which is not -1 is the
275 * parent pipe handle corresponding to the pipe which has
276 * been created. An element of this array is -1 on input
277 * if and only if it is <em>not</em> -1 on output.
278 * @param redirectErrorStream redirectErrorStream attribute
279 * @return the native subprocess HANDLE returned by CreateProcess
280 */
281 private static native long create(String cmdstr,
282 String envblock,
283 String dir,
284 long[] stdHandles,
285 boolean redirectErrorStream)
286 throws IOException;
287
288 /**
289 * Opens a file for atomic append. The file is created if it doesn't
290 * already exist.
291 *
292 * @param file the file to open or create
293 * @return the native HANDLE
294 */
295 private static native long openForAtomicAppend(String path)
296 throws IOException;
297
298 private static native boolean closeHandle(long handle);
299 }
|
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.IOException;
29 import java.io.File;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.io.FileInputStream;
33 import java.io.FileOutputStream;
34 import java.io.FileDescriptor;
35 import java.io.BufferedInputStream;
36 import java.io.BufferedOutputStream;
37 import java.lang.ProcessBuilder.Redirect;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40 import java.util.concurrent.TimeUnit;
41
42 /* This class is for the exclusive use of ProcessBuilder.start() to
43 * create new processes.
44 *
45 * @author Martin Buchholz
46 * @since 1.5
47 */
48
49 final class ProcessImpl extends Process {
50 private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
51 = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
52
53 /**
54 * Open a file for writing. If {@code append} is {@code true} then the file
55 * is opened for atomic append directly and a FileOutputStream constructed
56 * with the resulting handle. This is because a FileOutputStream created
57 * to append to a file does not open the file in a manner that guarantees
58 * that writes by the child process will be atomic.
59 */
60 private static FileOutputStream newFileOutputStream(File f, boolean append)
238 closeHandle(handle);
239 }
240
241 private static final int STILL_ACTIVE = getStillActive();
242 private static native int getStillActive();
243
244 public int exitValue() {
245 int exitCode = getExitCodeProcess(handle);
246 if (exitCode == STILL_ACTIVE)
247 throw new IllegalThreadStateException("process has not exited");
248 return exitCode;
249 }
250 private static native int getExitCodeProcess(long handle);
251
252 public int waitFor() throws InterruptedException {
253 waitForInterruptibly(handle);
254 if (Thread.interrupted())
255 throw new InterruptedException();
256 return exitValue();
257 }
258
259 private static native void waitForInterruptibly(long handle);
260
261 @Override
262 public boolean waitFor(long timeout, TimeUnit unit)
263 throws InterruptedException
264 {
265 if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
266 if (timeout <= 0) return false;
267
268 long msTimeout = unit.toMillis(timeout);
269
270 waitForTimeoutInterruptibly(handle, msTimeout);
271 if (Thread.interrupted())
272 throw new InterruptedException();
273 return (getExitCodeProcess(handle) != STILL_ACTIVE);
274 }
275
276 private static native void waitForTimeoutInterruptibly(
277 long handle, long timeout);
278
279 public void destroy() { terminateProcess(handle); }
280
281 @Override
282 public Process destroyForcibly() {
283 destroy();
284 return this;
285 }
286
287 private static native void terminateProcess(long handle);
288
289 @Override
290 public boolean isAlive() {
291 return isProcessAlive(handle);
292 }
293
294 private static native boolean isProcessAlive(long handle);
295
296 /**
297 * Create a process using the win32 function CreateProcess.
298 *
299 * @param cmdstr the Windows commandline
300 * @param envblock NUL-separated, double-NUL-terminated list of
301 * environment strings in VAR=VALUE form
302 * @param dir the working directory of the process, or null if
303 * inheriting the current directory from the parent process
304 * @param stdHandles array of windows HANDLEs. Indexes 0, 1, and
305 * 2 correspond to standard input, standard output and
306 * standard error, respectively. On input, a value of -1
307 * means to create a pipe to connect child and parent
308 * processes. On output, a value which is not -1 is the
309 * parent pipe handle corresponding to the pipe which has
310 * been created. An element of this array is -1 on input
311 * if and only if it is <em>not</em> -1 on output.
312 * @param redirectErrorStream redirectErrorStream attribute
313 * @return the native subprocess HANDLE returned by CreateProcess
314 */
315 private static native long create(String cmdstr,
316 String envblock,
317 String dir,
318 long[] stdHandles,
319 boolean redirectErrorStream)
320 throws IOException;
321
322 /**
323 * Opens a file for atomic append. The file is created if it doesn't
324 * already exist.
325 *
326 * @param file the file to open or create
327 * @return the native HANDLE
328 */
329 private static native long openForAtomicAppend(String path)
330 throws IOException;
331
332 private static native boolean closeHandle(long handle);
333 }
334
|