Runtime.java (exec): Convert prog name and arguments to string array.
authorBryce McKinlay <bryce@albatross.co.nz>
Wed, 9 Jun 1999 17:42:26 +0000 (17:42 +0000)
committerBryce McKinlay <bryce@gcc.gnu.org>
Wed, 9 Jun 1999 17:42:26 +0000 (18:42 +0100)
* java/lang/Runtime.java (exec): Convert prog name and arguments
to string array.
* java/lang/natPosixProcess.cc (startProcess): Fix typo in
environment array conversion. Preserve current environment if envp
not passed. Preserve PATH unless explicitly specified.
* java/io/DataInputStream.java (readLine): Fix case where '\r' is
followed by EOF. Set a flag when a line is terminated by '\r' and
ignore following '\n' if set.

From-SVN: r27458

libjava/ChangeLog
libjava/java/io/DataInputStream.java
libjava/java/lang/Runtime.java
libjava/java/lang/natPosixProcess.cc

index bd9afc2..73ff2a5 100644 (file)
@@ -1,3 +1,14 @@
+1999-06-09  Bryce McKinlay <bryce@albatross.co.nz>
+
+       * java/lang/Runtime.java (exec): Convert prog name and arguments
+       to string array.
+       * java/lang/natPosixProcess.cc (startProcess): Fix typo in
+       environment array conversion. Preserve current environment if envp
+       not passed. Preserve PATH unless explicitly specified.
+       * java/io/DataInputStream.java (readLine): Fix case where '\r' is
+       followed by EOF. Set a flag when a line is terminated by '\r' and
+       ignore following '\n' if set.
+
 1999-06-02  Warren Levy  <warrenl@cygnus.com>
 
        * java/net/URL.java (URL(URL,String)): Initialize port to -1.
index d03f8f4..bbcf1da 100644 (file)
@@ -21,6 +21,11 @@ package java.io;
  
 public class DataInputStream extends FilterInputStream implements DataInput
 {
+  // readLine() hack to ensure that an '\r' not followed by an '\n' is
+  // handled correctly. If set, readLine() will ignore the first char it sees
+  // if that char is a '\n'
+  boolean ignoreInitialNewline = false;
+  
   public DataInputStream(InputStream in)
   {
     super(in);
@@ -103,14 +108,29 @@ public class DataInputStream extends FilterInputStream implements DataInput
   {
     StringBuffer strb = new StringBuffer();
 
-    while (true)
+    readloop: while (true)
       {
-       int c = read();
-       if (c < 0)      // got an EOF
-         return strb.length() > 0 ? strb.toString() : null;
-       char ch = (char) c;
-       if ((ch &= 0xFF) == '\n')
-         break;
+        int c = 0;
+        char ch = ' ';
+        boolean getnext = true;
+        while (getnext)
+          {
+           getnext = false;
+           c = read();
+           if (c < 0)  // got an EOF
+             return strb.length() > 0 ? strb.toString() : null;
+           ch = (char) c;
+           if ((ch &= 0xFF) == '\n')
+             // hack to correctly handle '\r\n' sequences
+             if (ignoreInitialNewline)
+               {
+                 ignoreInitialNewline = false;
+                 getnext = true;
+               }
+             else
+               break readloop;
+         }
+
        if (ch == '\r')
          {
            // FIXME: The following code tries to adjust the stream back one
@@ -134,18 +154,35 @@ public class DataInputStream extends FilterInputStream implements DataInput
            // and since it is undesirable to make non-deprecated methods
            // less efficient, the following seems like the most reasonable
            // approach.
-           if (in instanceof BufferedInputStream && (read() & 0xFF) != '\n')
+           int next_c = 0;
+            char next_ch = ' ';
+           if (in instanceof BufferedInputStream)
              {
-               BufferedInputStream bin = (BufferedInputStream) in;
-               if (bin.pos > 0)
-                  bin.pos--;
+               next_c = read();
+               next_ch = (char) (next_c & 0xFF);
+               if ((next_ch != '\n') && (next_c >= 0)) 
+                 {
+                   BufferedInputStream bin = (BufferedInputStream) in;
+                   if (bin.pos > 0)
+                      bin.pos--;
+                 }
              }
            else if (markSupported())
              {
-               mark(1);
-               if ((read() & 0xFF) != '\n')
-                 reset();
-             }
+               next_c = read();
+               next_ch = (char) (next_c & 0xFF);
+               if ((next_ch != '\n') && (next_c >= 0)) 
+                 {
+                   mark(1);
+                   if ((read() & 0xFF) != '\n')
+                     reset();
+                 }
+             } 
+           // In order to catch cases where 'in' isn't a BufferedInputStream
+           // and doesn't support mark() (such as reading from a Socket), set 
+           // a flag that instructs readLine() to ignore the first character 
+           // it sees _if_ that character is a '\n'.
+           else ignoreInitialNewline = true;
            break;
          }
        strb.append(ch);
index 62a7c18..cdba9a3 100644 (file)
@@ -13,6 +13,7 @@ package java.lang;
 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 class Runtime
 {
   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 30fa9d5..5c6d9a7 100644 (file)
@@ -20,6 +20,7 @@ details.  */
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 
 #include <cni.h>
 #include <jvm.h>
@@ -115,15 +116,7 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
   // 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 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
 
   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 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
       // 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 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
       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);
     }