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)
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)
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 private static native void waitForInterruptibly(long handle);
259 @Override
260 public boolean waitFor(long timeout, TimeUnit unit)
261 throws InterruptedException {
262 if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
263 if (timeout <= 0) return false;
264
265 long msTimeout = unit.toMillis(timeout);
266 long ns = unit.toNanos(timeout) % 1000000;
267 msTimeout += Math.round((double)ns / 1000000);
268
269 waitForTimeoutInterruptibly(handle, msTimeout);
270 if (Thread.interrupted())
271 throw new InterruptedException();
272 return (getExitCodeProcess(handle) != STILL_ACTIVE);
273 }
274 private static native void waitForTimeoutInterruptibly(
275 long handle, long timeout);
276
277 public void destroy() { terminateProcess(handle); }
278 @Override
279 public Process destroyForcibly() {
280 destroy();
281 return this;
282 }
283 private static native void terminateProcess(long handle);
284
285 @Override
286 public boolean isAlive() {
287 return isProcessAlive(handle);
288 }
289 private static native boolean isProcessAlive(long handle);
290
291 /**
292 * Create a process using the win32 function CreateProcess.
293 *
294 * @param cmdstr the Windows commandline
295 * @param envblock NUL-separated, double-NUL-terminated list of
296 * environment strings in VAR=VALUE form
297 * @param dir the working directory of the process, or null if
298 * inheriting the current directory from the parent process
299 * @param stdHandles array of windows HANDLEs. Indexes 0, 1, and
300 * 2 correspond to standard input, standard output and
301 * standard error, respectively. On input, a value of -1
302 * means to create a pipe to connect child and parent
303 * processes. On output, a value which is not -1 is the
304 * parent pipe handle corresponding to the pipe which has
305 * been created. An element of this array is -1 on input
306 * if and only if it is <em>not</em> -1 on output.
307 * @param redirectErrorStream redirectErrorStream attribute
308 * @return the native subprocess HANDLE returned by CreateProcess
309 */
310 private static native long create(String cmdstr,
311 String envblock,
312 String dir,
313 long[] stdHandles,
314 boolean redirectErrorStream)
315 throws IOException;
316
317 /**
318 * Opens a file for atomic append. The file is created if it doesn't
319 * already exist.
320 *
321 * @param file the file to open or create
322 * @return the native HANDLE
323 */
324 private static native long openForAtomicAppend(String path)
325 throws IOException;
326
327 private static native boolean closeHandle(long handle);
328 }
329
|