001: /*
002: * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.lang;
027:
028: import java.io.*;
029:
030: /* This class is for the exclusive use of ProcessBuilder.start() to
031: * create new processes.
032: *
033: * @author Martin Buchholz
034: * @version 1.38, 07/06/11
035: * @since 1.5
036: */
037:
038: final class ProcessImpl extends Process {
039:
040: // System-dependent portion of ProcessBuilder.start()
041: static Process start(String cmdarray[],
042: java.util.Map<String, String> environment, String dir,
043: boolean redirectErrorStream) throws IOException {
044: String envblock = ProcessEnvironment
045: .toEnvironmentBlock(environment);
046: return new ProcessImpl(cmdarray, envblock, dir,
047: redirectErrorStream);
048: }
049:
050: private long handle = 0;
051: private FileDescriptor stdin_fd;
052: private FileDescriptor stdout_fd;
053: private FileDescriptor stderr_fd;
054: private OutputStream stdin_stream;
055: private InputStream stdout_stream;
056: private InputStream stderr_stream;
057:
058: private ProcessImpl(String cmd[], String envblock, String path,
059: boolean redirectErrorStream) throws IOException {
060: // Win32 CreateProcess requires cmd[0] to be normalized
061: cmd[0] = new File(cmd[0]).getPath();
062:
063: StringBuilder cmdbuf = new StringBuilder(80);
064: for (int i = 0; i < cmd.length; i++) {
065: if (i > 0) {
066: cmdbuf.append(' ');
067: }
068: String s = cmd[i];
069: if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
070: if (s.charAt(0) != '"') {
071: cmdbuf.append('"');
072: cmdbuf.append(s);
073: if (s.endsWith("\\")) {
074: cmdbuf.append("\\");
075: }
076: cmdbuf.append('"');
077: } else if (s.endsWith("\"")) {
078: /* The argument has already been quoted. */
079: cmdbuf.append(s);
080: } else {
081: /* Unmatched quote for the argument. */
082: throw new IllegalArgumentException();
083: }
084: } else {
085: cmdbuf.append(s);
086: }
087: }
088: String cmdstr = cmdbuf.toString();
089:
090: stdin_fd = new FileDescriptor();
091: stdout_fd = new FileDescriptor();
092: stderr_fd = new FileDescriptor();
093:
094: handle = create(cmdstr, envblock, path, redirectErrorStream,
095: stdin_fd, stdout_fd, stderr_fd);
096:
097: java.security.AccessController
098: .doPrivileged(new java.security.PrivilegedAction() {
099: public Object run() {
100: stdin_stream = new BufferedOutputStream(
101: new FileOutputStream(stdin_fd));
102: stdout_stream = new BufferedInputStream(
103: new FileInputStream(stdout_fd));
104: stderr_stream = new FileInputStream(stderr_fd);
105: return null;
106: }
107: });
108: }
109:
110: public OutputStream getOutputStream() {
111: return stdin_stream;
112: }
113:
114: public InputStream getInputStream() {
115: return stdout_stream;
116: }
117:
118: public InputStream getErrorStream() {
119: return stderr_stream;
120: }
121:
122: public void finalize() {
123: closeHandle(handle);
124: }
125:
126: private static final int STILL_ACTIVE = getStillActive();
127:
128: private static native int getStillActive();
129:
130: public int exitValue() {
131: int exitCode = getExitCodeProcess(handle);
132: if (exitCode == STILL_ACTIVE)
133: throw new IllegalThreadStateException(
134: "process has not exited");
135: return exitCode;
136: }
137:
138: private static native int getExitCodeProcess(long handle);
139:
140: public int waitFor() throws InterruptedException {
141: waitForInterruptibly(handle);
142: if (Thread.interrupted())
143: throw new InterruptedException();
144: return exitValue();
145: }
146:
147: private static native void waitForInterruptibly(long handle);
148:
149: public void destroy() {
150: terminateProcess(handle);
151: }
152:
153: private static native void terminateProcess(long handle);
154:
155: private static native long create(String cmdstr, String envblock,
156: String dir, boolean redirectErrorStream,
157: FileDescriptor in_fd, FileDescriptor out_fd,
158: FileDescriptor err_fd) throws IOException;
159:
160: private static native boolean closeHandle(long handle);
161: }
|