This is the mail archive of the java-discuss@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch] Runtime.exec()


This patch fixes a few problems in the Runtime.exec() implementation.
Currently, the exec(String) methods won't work if the caller specifies
any arguments in the command since they are not converted correctly to
the array form expected by the native code. Also, there are some typos
in natPosixProcess.cc break the environment-passing stuff. I also added
code to preserve the PATH unless the caller explicitly sets it, as it is
used by the execvp() call.

Here's a changelog:

1999-06-02  Bryce McKinlay <bryce@albatross.co.nz>

        * java/lang/Runtime.java (exec): Convert prog name and arguments
to string array
        * java/lang/natPosixProcess.cc (startProcess): Fixed typo in
environment array conversion, Preserve existing environment if envp not
passed, Preserve PATH unless specified explicitly

regards

  [ bryce ]

Index: libjava/java/lang/Runtime.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/Runtime.java,v
retrieving revision 1.3
diff -u -r1.3 Runtime.java
--- Runtime.java	1999/05/12 11:23:43	1.3
+++ Runtime.java	1999/06/02 11:17:01
@@ -13,6 +13,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.StringTokenizer;
 
 /**
  * @author Tom Tromey <tromey@cygnus.com>
@@ -30,15 +31,15 @@
 {
   public Process exec (String prog) throws IOException
   {
-    String[] a = new String[1];
-    a[0] = prog;
-    return exec (a, null);
+    return exec (prog, null);
   }
 
   public Process exec (String prog, String[] envp) throws IOException
   {
-    String[] a = new String[1];
-    a[0] = prog;
+    StringTokenizer st = new StringTokenizer(prog);
+    String[] a = new String[st.countTokens()];
+    for (int i = 0; i < a.length; i++)
+      a[i] = st.nextToken();
     return exec (a, envp);
   }
 
Index: libjava/java/lang/natPosixProcess.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natPosixProcess.cc,v
retrieving revision 1.1
diff -u -r1.1 natPosixProcess.cc
--- natPosixProcess.cc	1999/05/12 11:23:44	1.1
+++ natPosixProcess.cc	1999/06/02 11:17:02
@@ -20,6 +20,7 @@
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 
 #include <cni.h>
 #include <jvm.h>
@@ -115,15 +116,7 @@
   // thrown we will leak memory.
   char **args = (char **) _Jv_Malloc ((progarray->length + 1)
 				      * sizeof (char *));
-
   char **env = NULL;
-  if (envp)
-    env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
-
-//   for (int i = 0; i < progarray->length; ++i)
-//     args[i] = NULL;
-//   for (int i = 0; i < envp->length; ++i)
-//     env[i] = NULL;
 
   // FIXME: GC will fail here if _Jv_Malloc throws an exception.
   // That's because we have to manually free the contents, but we 
@@ -134,10 +127,11 @@
 
   if (envp)
     {
+      env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
       elts = elements (envp);
       for (int i = 0; i < envp->length; ++i)
-	args[i] = new_string (elts[i]);
-      args[envp->length] = NULL;
+	env[i] = new_string (elts[i]);
+      env[envp->length] = NULL;
     }
 
   // Create pipes for I/O.
@@ -172,8 +166,18 @@
       // Child process, so remap descriptors and exec.
 
       if (envp)
-	environ = env;
-
+        {
+	  // preserve PATH unless specified explicitly
+	  char *path_val = getenv("PATH");
+	  environ = env;
+	  if (getenv("PATH") == NULL)
+	    {
+	      char *path_env = (char *) _Jv_Malloc (strlen(path_val) + 5 + 1);
+	      sprintf (path_env, "PATH=%s", path_val); 
+	      putenv (path_env);
+	    }
+	}
+	
       // We ignore errors from dup2 because they should never occur.
       dup2 (outp[0], 0);
       dup2 (inp[1], 1);
@@ -186,8 +190,9 @@
       close (outp[0]);
       close (outp[1]);
 
-      environ = env;
       execvp (args[0], args);
+      // FIXME: should throw an IOException if execvp() fails. Not trivial,
+      // because _Jv_Throw won't work from child process
       _exit (127);
     }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]