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

Print this page

        

@@ -61,15 +61,65 @@
 
     private /* final */ OutputStream stdin;
     private /* final */ InputStream  stdout;
     private /* final */ InputStream  stderr;
 
+    private static enum LaunchMechanism {
+        FORK(1),
+        VFORK(3);
+
+        private int value;
+        LaunchMechanism(int x) {value = x;}
+    };
+
+    /* default is VFORK on Linux */
+    private static final LaunchMechanism launchMechanism;
+    private static byte[] helperpath;
+
+    private static byte[] toCString(String s) {
+        if (s == null)
+            return null;
+        byte[] bytes = s.getBytes();
+        byte[] result = new byte[bytes.length + 1];
+        System.arraycopy(bytes, 0,
+                         result, 0,
+                         bytes.length);
+        result[result.length-1] = (byte)0;
+        return result;
+    }
+
+    static {
+        launchMechanism = AccessController.doPrivileged(
+                new PrivilegedAction<LaunchMechanism>()
+        {
+            public LaunchMechanism run() {
+                String javahome = System.getProperty("java.home");
+                String osArch = System.getProperty("os.arch");
+
+                helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
+                String s = System.getProperty(
+                    "jdk.lang.Process.launchMechanism", "vfork");
+
+                try {
+                    return LaunchMechanism.valueOf(s.toUpperCase());
+                } catch (IllegalArgumentException e) {
+                    throw new Error(s + " is not a supported " +
+                        "process launch mechanism on this platform.");
+                }
+            }
+        });
+    }
+
     /* this is for the reaping thread */
     private native int waitForProcessExit(int pid);
 
     /**
-     * Create a process using fork(2) and exec(2).
+     * Create a process. Depending on the mode flag, this is done by
+     * one of the following mechanisms.
+     * - fork(2) and exec(2)
+     * - clone(2) and exec(2)
+     * - vfork(2) and exec(2)
      *
      * @param fds an array of three file descriptors.
      *        Indexes 0, 1, and 2 correspond to standard input,
      *        standard output and standard error, respectively.  On
      *        input, a value of -1 means to create a pipe to connect

@@ -78,11 +128,12 @@
      *        pipe which has been created.  An element of this array
      *        is -1 on input if and only if it is <em>not</em> -1 on
      *        output.
      * @return the pid of the subprocess
      */
-    private native int forkAndExec(byte[] prog,
+    private native int forkAndExec(int mode, byte[] helperpath,
+                                   byte[] prog,
                                    byte[] argBlock, int argc,
                                    byte[] envBlock, int envc,
                                    byte[] dir,
                                    int[] fds,
                                    boolean redirectErrorStream)

@@ -130,11 +181,13 @@
                 final byte[] dir,
                 final int[] fds,
                 final boolean redirectErrorStream)
             throws IOException {
 
-        pid = forkAndExec(prog,
+        pid = forkAndExec(launchMechanism.value,
+                          helperpath,
+                          prog,
                           argBlock, argc,
                           envBlock, envc,
                           dir,
                           fds,
                           redirectErrorStream);

@@ -234,15 +287,14 @@
         try { stdin.close();  } catch (IOException ignored) {}
         try { stdout.close(); } catch (IOException ignored) {}
         try { stderr.close(); } catch (IOException ignored) {}
     }
 
-    /* This routine initializes JNI field offsets for the class */
-    private static native void initIDs();
+    private static native void init();
 
     static {
-        initIDs();
+        init();
     }
 
     /**
      * A buffered input stream for a subprocess pipe file descriptor
      * that allows the underlying file descriptor to be reclaimed when