src/solaris/classes/java/lang/UNIXProcess.java.solaris

Print this page




  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), 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.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("java.lang.useFork");
  79                 if (s != null) {
  80                     launchMechanism = LaunchMechanism.FORK;
  81                 }
  82                 return null;
  83             }
  84         });
  85     }
  86 
  87     /* this is for the reaping thread */
  88     private native int waitForProcessExit(int pid);
  89 
  90     /**
  91      * Create a process. Depending on the mode flag, this is done by
  92      * one of the following mechanisms.
  93      * - fork(2) and exec(2)
  94      * - vfork(2) and exec(2)
  95      * - posix_spawn(2)
  96      *
  97      * @param std_fds array of file descriptors.  Indexes 0, 1, and
  98      *        2 correspond to standard input, standard output and
  99      *        standard error, respectively.  On input, a value of -1
 100      *        means to create a pipe to connect child and parent
 101      *        processes.  On output, a value which is not -1 is the
 102      *        parent pipe fd corresponding to the pipe which has
 103      *        been created.  An element of this array is -1 on input
 104      *        if and only if it is <em>not</em> -1 on output.
 105      * @return the pid of the subprocess
 106      */
 107     private native int forkAndExec(int mode, byte[] prog,
 108                                    byte[] argBlock, int argc,
 109                                    byte[] envBlock, int envc,
 110                                    byte[] dir,
 111                                    int[] std_fds,
 112                                    boolean redirectErrorStream)
 113         throws IOException;
 114 
 115     UNIXProcess(final byte[] prog,
 116                 final byte[] argBlock, int argc,
 117                 final byte[] envBlock, int envc,
 118                 final byte[] dir,
 119                 final int[] std_fds,
 120                 final boolean redirectErrorStream)
 121     throws IOException {
 122         pid = forkAndExec(launchMechanism.value,
 123                           prog,
 124                           argBlock, argc,
 125                           envBlock, envc,
 126                           dir,
 127                           std_fds,
 128                           redirectErrorStream);
 129 
 130         java.security.AccessController.doPrivileged(
 131         new java.security.PrivilegedAction<Void>() { public Void run() {
 132             if (std_fds[0] == -1)
 133                 stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE;
 134             else {
 135                 FileDescriptor stdin_fd = new FileDescriptor();
 136                 fdAccess.set(stdin_fd, std_fds[0]);
 137                 stdin_stream = new BufferedOutputStream(
 138                     new FileOutputStream(stdin_fd));
 139             }
 140 
 141             if (std_fds[1] == -1)
 142                 stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
 143             else {