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.concurrent.TimeUnit; 30 31 /* java.lang.Process subclass in the UNIX environment. 32 * 33 * @author Mario Wolczko and Ross Knippel. 34 */ 35 36 final class UNIXProcess extends Process { 37 private static final sun.misc.JavaIOFileDescriptorAccess fdAccess 38 = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); 39 40 private final int pid; 41 private int exitcode; 42 private boolean hasExited; 43 44 private OutputStream stdin_stream; 45 private InputStream stdout_stream; 46 private DeferredCloseInputStream stdout_inner_stream; 47 private InputStream stderr_stream; 48 49 /* this is for the reaping thread */ 50 private native int waitForProcessExit(int pid); 51 52 /** 53 * Create a process using fork(2) and exec(2). 54 * 55 * @param std_fds array of file descriptors. Indexes 0, 1, and 56 * 2 correspond to standard input, standard output and 57 * standard error, respectively. On input, a value of -1 58 * means to create a pipe to connect child and parent 59 * processes. On output, a value which is not -1 is the 60 * parent pipe fd corresponding to the pipe which has 61 * been created. An element of this array is -1 on input 62 * if and only if it is <em>not</em> -1 on output. 63 * @return the pid of the subprocess 64 */ 65 private native int forkAndExec(byte[] prog, 66 byte[] argBlock, int argc, 67 byte[] envBlock, int envc, 68 byte[] dir, 69 int[] std_fds, 70 boolean redirectErrorStream) 71 throws IOException; 72 73 UNIXProcess(final byte[] prog, 74 final byte[] argBlock, int argc, 75 final byte[] envBlock, int envc, 76 final byte[] dir, 77 final int[] std_fds, 78 final boolean redirectErrorStream) 79 throws IOException { 80 pid = forkAndExec(prog, 81 argBlock, argc, 82 envBlock, envc, 83 dir, 84 std_fds, 85 redirectErrorStream); 86 87 java.security.AccessController.doPrivileged( 88 new java.security.PrivilegedAction<Void>() { public Void run() { 89 if (std_fds[0] == -1) 90 stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE; 91 else { 92 FileDescriptor stdin_fd = new FileDescriptor(); 93 fdAccess.set(stdin_fd, std_fds[0]); 94 stdin_stream = new BufferedOutputStream( 95 new FileOutputStream(stdin_fd)); 96 } 97 98 if (std_fds[1] == -1) 99 stdout_stream = ProcessBuilder.NullInputStream.INSTANCE; 100 else { | 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.concurrent.TimeUnit; 30 import java.security.AccessController; 31 import java.security.PrivilegedAction; 32 33 /* java.lang.Process subclass in the UNIX environment. 34 * 35 * @author Mario Wolczko and Ross Knippel. 36 */ 37 38 final class UNIXProcess extends Process { 39 private static final sun.misc.JavaIOFileDescriptorAccess fdAccess 40 = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); 41 42 private final int pid; 43 private int exitcode; 44 private boolean hasExited; 45 46 private OutputStream stdin_stream; 47 private InputStream stdout_stream; 48 private DeferredCloseInputStream stdout_inner_stream; 49 private InputStream stderr_stream; 50 51 private static String javahome; 52 private static String arch; 53 private static String helperpath; 54 55 enum LaunchMechanism { 56 CLONE(1), FORK(2), 57 VFORK(3), POSIX_SPAWN(4); 58 59 private int value; 60 LaunchMechanism(int x) {value = x;} 61 }; 62 63 /* On Solaris, the default is to spawn */ 64 private static LaunchMechanism launchMechanism = LaunchMechanism.POSIX_SPAWN; 65 66 static { 67 AccessController.doPrivileged(new PrivilegedAction<Void>() { 68 public Void run() { 69 String javahome = System.getProperty("java.home"); 70 String osarch = System.getProperty("os.arch"); 71 if (osarch.equals("x86")) { 72 osarch = "i386"; 73 } else if (osarch.equals("x86_64")) { 74 osarch = "amd64"; 75 } 76 77 helperpath = javahome + "/lib/" + osarch + "/jspawnhelper"; 78 String s = System.getProperty("jdk.lang.Process.launchMechanism"); 79 if (s != null && !s.equals("POSIX_SPAWN")) { 80 if (s.equals("FORK")) { 81 launchMechanism = LaunchMechanism.FORK; 82 } else { 83 throw new Error(s + " is not a supported " + 84 "process launch mechanism on this platform."); 85 } 86 } 87 return null; 88 } 89 }); 90 } 91 92 /* this is for the reaping thread */ 93 private native int waitForProcessExit(int pid); 94 95 /** 96 * Create a process. Depending on the mode flag, this is done by 97 * one of the following mechanisms. 98 * - fork(2) and exec(2) 99 * - vfork(2) and exec(2) 100 * - posix_spawn(2) 101 * 102 * @param std_fds array of file descriptors. Indexes 0, 1, and 103 * 2 correspond to standard input, standard output and 104 * standard error, respectively. On input, a value of -1 105 * means to create a pipe to connect child and parent 106 * processes. On output, a value which is not -1 is the 107 * parent pipe fd corresponding to the pipe which has 108 * been created. An element of this array is -1 on input 109 * if and only if it is <em>not</em> -1 on output. 110 * @return the pid of the subprocess 111 */ 112 private native int forkAndExec(int mode, byte[] prog, 113 byte[] argBlock, int argc, 114 byte[] envBlock, int envc, 115 byte[] dir, 116 int[] std_fds, 117 boolean redirectErrorStream) 118 throws IOException; 119 120 UNIXProcess(final byte[] prog, 121 final byte[] argBlock, int argc, 122 final byte[] envBlock, int envc, 123 final byte[] dir, 124 final int[] std_fds, 125 final boolean redirectErrorStream) 126 throws IOException { 127 pid = forkAndExec(launchMechanism.value, 128 prog, 129 argBlock, argc, 130 envBlock, envc, 131 dir, 132 std_fds, 133 redirectErrorStream); 134 135 java.security.AccessController.doPrivileged( 136 new java.security.PrivilegedAction<Void>() { public Void run() { 137 if (std_fds[0] == -1) 138 stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE; 139 else { 140 FileDescriptor stdin_fd = new FileDescriptor(); 141 fdAccess.set(stdin_fd, std_fds[0]); 142 stdin_stream = new BufferedOutputStream( 143 new FileOutputStream(stdin_fd)); 144 } 145 146 if (std_fds[1] == -1) 147 stdout_stream = ProcessBuilder.NullInputStream.INSTANCE; 148 else { |