Runtime.java (exec): Convert prog name and arguments to string array.
* 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
This commit is contained in:
parent
8d30c4ee01
commit
1e45a14105
4 changed files with 87 additions and 33 deletions
|
@ -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>
|
1999-06-02 Warren Levy <warrenl@cygnus.com>
|
||||||
|
|
||||||
* java/net/URL.java (URL(URL,String)): Initialize port to -1.
|
* java/net/URL.java (URL(URL,String)): Initialize port to -1.
|
||||||
|
|
|
@ -21,6 +21,11 @@ package java.io;
|
||||||
|
|
||||||
public class DataInputStream extends FilterInputStream implements DataInput
|
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)
|
public DataInputStream(InputStream in)
|
||||||
{
|
{
|
||||||
super(in);
|
super(in);
|
||||||
|
@ -103,14 +108,29 @@ public class DataInputStream extends FilterInputStream implements DataInput
|
||||||
{
|
{
|
||||||
StringBuffer strb = new StringBuffer();
|
StringBuffer strb = new StringBuffer();
|
||||||
|
|
||||||
while (true)
|
readloop: while (true)
|
||||||
{
|
{
|
||||||
int c = read();
|
int c = 0;
|
||||||
if (c < 0) // got an EOF
|
char ch = ' ';
|
||||||
return strb.length() > 0 ? strb.toString() : null;
|
boolean getnext = true;
|
||||||
char ch = (char) c;
|
while (getnext)
|
||||||
if ((ch &= 0xFF) == '\n')
|
{
|
||||||
break;
|
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')
|
if (ch == '\r')
|
||||||
{
|
{
|
||||||
// FIXME: The following code tries to adjust the stream back one
|
// 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
|
// and since it is undesirable to make non-deprecated methods
|
||||||
// less efficient, the following seems like the most reasonable
|
// less efficient, the following seems like the most reasonable
|
||||||
// approach.
|
// approach.
|
||||||
if (in instanceof BufferedInputStream && (read() & 0xFF) != '\n')
|
int next_c = 0;
|
||||||
|
char next_ch = ' ';
|
||||||
|
if (in instanceof BufferedInputStream)
|
||||||
{
|
{
|
||||||
BufferedInputStream bin = (BufferedInputStream) in;
|
next_c = read();
|
||||||
if (bin.pos > 0)
|
next_ch = (char) (next_c & 0xFF);
|
||||||
bin.pos--;
|
if ((next_ch != '\n') && (next_c >= 0))
|
||||||
|
{
|
||||||
|
BufferedInputStream bin = (BufferedInputStream) in;
|
||||||
|
if (bin.pos > 0)
|
||||||
|
bin.pos--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (markSupported())
|
else if (markSupported())
|
||||||
{
|
{
|
||||||
mark(1);
|
next_c = read();
|
||||||
if ((read() & 0xFF) != '\n')
|
next_ch = (char) (next_c & 0xFF);
|
||||||
reset();
|
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;
|
break;
|
||||||
}
|
}
|
||||||
strb.append(ch);
|
strb.append(ch);
|
||||||
|
|
|
@ -13,6 +13,7 @@ package java.lang;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Tom Tromey <tromey@cygnus.com>
|
* @author Tom Tromey <tromey@cygnus.com>
|
||||||
|
@ -30,15 +31,15 @@ public class Runtime
|
||||||
{
|
{
|
||||||
public Process exec (String prog) throws IOException
|
public Process exec (String prog) throws IOException
|
||||||
{
|
{
|
||||||
String[] a = new String[1];
|
return exec (prog, null);
|
||||||
a[0] = prog;
|
|
||||||
return exec (a, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Process exec (String prog, String[] envp) throws IOException
|
public Process exec (String prog, String[] envp) throws IOException
|
||||||
{
|
{
|
||||||
String[] a = new String[1];
|
StringTokenizer st = new StringTokenizer(prog);
|
||||||
a[0] = prog;
|
String[] a = new String[st.countTokens ()];
|
||||||
|
for (int i = 0; i < a.length; i++)
|
||||||
|
a[i] = st.nextToken ();
|
||||||
return exec (a, envp);
|
return exec (a, envp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ details. */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <cni.h>
|
#include <cni.h>
|
||||||
#include <jvm.h>
|
#include <jvm.h>
|
||||||
|
@ -115,15 +116,7 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
|
||||||
// thrown we will leak memory.
|
// thrown we will leak memory.
|
||||||
char **args = (char **) _Jv_Malloc ((progarray->length + 1)
|
char **args = (char **) _Jv_Malloc ((progarray->length + 1)
|
||||||
* sizeof (char *));
|
* sizeof (char *));
|
||||||
|
|
||||||
char **env = NULL;
|
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.
|
// FIXME: GC will fail here if _Jv_Malloc throws an exception.
|
||||||
// That's because we have to manually free the contents, but we
|
// That's because we have to manually free the contents, but we
|
||||||
|
@ -134,10 +127,11 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
|
||||||
|
|
||||||
if (envp)
|
if (envp)
|
||||||
{
|
{
|
||||||
|
env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
|
||||||
elts = elements (envp);
|
elts = elements (envp);
|
||||||
for (int i = 0; i < envp->length; ++i)
|
for (int i = 0; i < envp->length; ++i)
|
||||||
args[i] = new_string (elts[i]);
|
env[i] = new_string (elts[i]);
|
||||||
args[envp->length] = NULL;
|
env[envp->length] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create pipes for I/O.
|
// Create pipes for I/O.
|
||||||
|
@ -172,8 +166,18 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
|
||||||
// Child process, so remap descriptors and exec.
|
// Child process, so remap descriptors and exec.
|
||||||
|
|
||||||
if (envp)
|
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.
|
// We ignore errors from dup2 because they should never occur.
|
||||||
dup2 (outp[0], 0);
|
dup2 (outp[0], 0);
|
||||||
dup2 (inp[1], 1);
|
dup2 (inp[1], 1);
|
||||||
|
@ -186,8 +190,9 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
|
||||||
close (outp[0]);
|
close (outp[0]);
|
||||||
close (outp[1]);
|
close (outp[1]);
|
||||||
|
|
||||||
environ = env;
|
|
||||||
execvp (args[0], args);
|
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);
|
_exit (127);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue