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

Print this page




  47 
  48 /**
  49  * java.lang.Process subclass in the UNIX environment.
  50  *
  51  * @author Mario Wolczko and Ross Knippel.
  52  * @author Konstantin Kladko (ported to Bsd)
  53  * @author Martin Buchholz
  54  */
  55 final class UNIXProcess extends Process {
  56     private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
  57         = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
  58 
  59     private final int pid;
  60     private int exitcode;
  61     private boolean hasExited;
  62 
  63     private /* final */ OutputStream stdin;
  64     private /* final */ InputStream  stdout;
  65     private /* final */ InputStream  stderr;
  66 




































  67     /* this is for the reaping thread */
  68     private native int waitForProcessExit(int pid);
  69 
  70     /**
  71      * Create a process using fork(2) and exec(2).




  72      *
  73      * @param fds an array of three file descriptors.
  74      *        Indexes 0, 1, and 2 correspond to standard input,
  75      *        standard output and standard error, respectively.  On
  76      *        input, a value of -1 means to create a pipe to connect
  77      *        child and parent processes.  On output, a value which
  78      *        is not -1 is the parent pipe fd corresponding to the
  79      *        pipe which has been created.  An element of this array
  80      *        is -1 on input if and only if it is <em>not</em> -1 on
  81      *        output.
  82      * @return the pid of the subprocess
  83      */
  84     private native int forkAndExec(byte[] prog,
  85                                    byte[] argBlock, int argc,
  86                                    byte[] envBlock, int envc,
  87                                    byte[] dir,
  88                                    int[] fds,
  89                                    boolean redirectErrorStream)
  90         throws IOException;
  91 
  92     /**
  93      * The thread factory used to create "process reaper" daemon threads.
  94      */
  95     private static class ProcessReaperThreadFactory implements ThreadFactory {
  96         private final static ThreadGroup group = getRootThreadGroup();
  97 
  98         private static ThreadGroup getRootThreadGroup() {
  99             return doPrivileged(new PrivilegedAction<ThreadGroup> () {
 100                 public ThreadGroup run() {
 101                     ThreadGroup root = Thread.currentThread().getThreadGroup();
 102                     while (root.getParent() != null)
 103                         root = root.getParent();
 104                     return root;


 116     }
 117 
 118     /**
 119      * The thread pool of "process reaper" daemon threads.
 120      */
 121     private static final Executor processReaperExecutor =
 122         doPrivileged(new PrivilegedAction<Executor>() {
 123             public Executor run() {
 124                 return Executors.newCachedThreadPool
 125                     (new ProcessReaperThreadFactory());
 126             }});
 127 
 128     UNIXProcess(final byte[] prog,
 129                 final byte[] argBlock, final int argc,
 130                 final byte[] envBlock, final int envc,
 131                 final byte[] dir,
 132                 final int[] fds,
 133                 final boolean redirectErrorStream)
 134             throws IOException {
 135 
 136         pid = forkAndExec(prog,

 137                           argBlock, argc,
 138                           envBlock, envc,
 139                           dir,
 140                           fds,
 141                           redirectErrorStream);
 142 
 143         try {
 144             doPrivileged(new PrivilegedExceptionAction<Void>() {
 145                 public Void run() throws IOException {
 146                     initStreams(fds);
 147                     return null;
 148                 }});
 149         } catch (PrivilegedActionException ex) {
 150             throw (IOException) ex.getException();
 151         }
 152     }
 153 
 154     static FileDescriptor newFileDescriptor(int fd) {
 155         FileDescriptor fileDescriptor = new FileDescriptor();
 156         fdAccess.set(fileDescriptor, fd);




  47 
  48 /**
  49  * java.lang.Process subclass in the UNIX environment.
  50  *
  51  * @author Mario Wolczko and Ross Knippel.
  52  * @author Konstantin Kladko (ported to Bsd)
  53  * @author Martin Buchholz
  54  */
  55 final class UNIXProcess extends Process {
  56     private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
  57         = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
  58 
  59     private final int pid;
  60     private int exitcode;
  61     private boolean hasExited;
  62 
  63     private /* final */ OutputStream stdin;
  64     private /* final */ InputStream  stdout;
  65     private /* final */ InputStream  stderr;
  66 
  67     private static String javahome;
  68     private static String arch;
  69     private static String helperpath;
  70 
  71     enum LaunchMechanism {
  72         CLONE(1), FORK(2),
  73         VFORK(3), POSIX_SPAWN(4);
  74 
  75         private int value;
  76         LaunchMechanism(int x) {value = x;}
  77     };
  78 
  79     /* On BSD, the default is to spawn */
  80     private static LaunchMechanism launchMechanism = LaunchMechanism.POSIX_SPAWN;
  81 
  82     static {
  83         AccessController.doPrivileged(new PrivilegedAction<Void>() {
  84             public Void run() {
  85                 String javahome = System.getProperty("java.home");
  86                 String osarch = System.getProperty("os.arch");
  87                 
  88                 helperpath = javahome + "/lib/jspawnhelper";
  89                 String s = System.getProperty("jdk.lang.Process.launchMechanism");
  90                 if (s != null && !s.equals("POSIX_SPAWN")) {
  91                     if (s.equals("FORK")) {
  92                         launchMechanism = LaunchMechanism.FORK;
  93                     } else {
  94                         throw new Error(s + " is not a supported " +
  95                             "process launch mechanism on this platform.");
  96                     }
  97                 }
  98                 return null;
  99             }
 100         });
 101     }
 102 
 103     /* this is for the reaping thread */
 104     private native int waitForProcessExit(int pid);
 105 
 106     /**
 107      * Create a process. Depending on the mode flag, this is done by
 108      * one of the following mechanisms.
 109      * - fork(2) and exec(2)
 110      * - vfork(2) and exec(2)
 111      * - posix_spawn(2)
 112      *
 113      * @param fds an array of three file descriptors.
 114      *        Indexes 0, 1, and 2 correspond to standard input,
 115      *        standard output and standard error, respectively.  On
 116      *        input, a value of -1 means to create a pipe to connect
 117      *        child and parent processes.  On output, a value which
 118      *        is not -1 is the parent pipe fd corresponding to the
 119      *        pipe which has been created.  An element of this array
 120      *        is -1 on input if and only if it is <em>not</em> -1 on
 121      *        output.
 122      * @return the pid of the subprocess
 123      */
 124     private native int forkAndExec(int mode, byte[] prog,
 125                                    byte[] argBlock, int argc,
 126                                    byte[] envBlock, int envc,
 127                                    byte[] dir,
 128                                    int[] fds,
 129                                    boolean redirectErrorStream)
 130         throws IOException;
 131 
 132     /**
 133      * The thread factory used to create "process reaper" daemon threads.
 134      */
 135     private static class ProcessReaperThreadFactory implements ThreadFactory {
 136         private final static ThreadGroup group = getRootThreadGroup();
 137 
 138         private static ThreadGroup getRootThreadGroup() {
 139             return doPrivileged(new PrivilegedAction<ThreadGroup> () {
 140                 public ThreadGroup run() {
 141                     ThreadGroup root = Thread.currentThread().getThreadGroup();
 142                     while (root.getParent() != null)
 143                         root = root.getParent();
 144                     return root;


 156     }
 157 
 158     /**
 159      * The thread pool of "process reaper" daemon threads.
 160      */
 161     private static final Executor processReaperExecutor =
 162         doPrivileged(new PrivilegedAction<Executor>() {
 163             public Executor run() {
 164                 return Executors.newCachedThreadPool
 165                     (new ProcessReaperThreadFactory());
 166             }});
 167 
 168     UNIXProcess(final byte[] prog,
 169                 final byte[] argBlock, final int argc,
 170                 final byte[] envBlock, final int envc,
 171                 final byte[] dir,
 172                 final int[] fds,
 173                 final boolean redirectErrorStream)
 174             throws IOException {
 175 
 176         pid = forkAndExec(launchMechanism.value,
 177                           prog,
 178                           argBlock, argc,
 179                           envBlock, envc,
 180                           dir,
 181                           fds,
 182                           redirectErrorStream);
 183 
 184         try {
 185             doPrivileged(new PrivilegedExceptionAction<Void>() {
 186                 public Void run() throws IOException {
 187                     initStreams(fds);
 188                     return null;
 189                 }});
 190         } catch (PrivilegedActionException ex) {
 191             throw (IOException) ex.getException();
 192         }
 193     }
 194 
 195     static FileDescriptor newFileDescriptor(int fd) {
 196         FileDescriptor fileDescriptor = new FileDescriptor();
 197         fdAccess.set(fileDescriptor, fd);