From 51c198f0f0567d4ff682c719bd772a6f69baef30 Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Wed, 28 Nov 2007 17:06:04 -0700 Subject: [PATCH 1/3] Implemented java.lang.Math.random() properly (seeding the random number on first use, and then using the system random number generator) --- classpath/java-lang.cpp | 20 ++++++++++++++++++++ classpath/java/lang/Math.java | 13 ++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index b377e0859a..ef44b027e4 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -136,6 +136,26 @@ Java_java_lang_Math_pow(JNIEnv*, jclass, jdouble val, jdouble exp) return pow(val, exp); } +extern "C" JNIEXPORT void JNICALL +Java_java_lang_Math_natRandomInitialize(JNIEnv*, jclass, jlong val) +{ +#ifdef WIN32 + srand(val); +#else + srand48(val); +#endif +} + +extern "C" JNIEXPORT jdouble JNICALL +Java_java_lang_Math_natRandom(JNIEnv*, jclass) +{ +#ifdef WIN32 + return rand(); +#else + return drand48(); +#endif +} + extern "C" JNIEXPORT jdouble JNICALL Java_java_lang_Math_floor(JNIEnv*, jclass, jdouble val) { diff --git a/classpath/java/lang/Math.java b/classpath/java/lang/Math.java index 9ad1f139ed..39636bb190 100644 --- a/classpath/java/lang/Math.java +++ b/classpath/java/lang/Math.java @@ -3,6 +3,7 @@ package java.lang; public final class Math { public static final double E = 2.718281828459045; public static final double PI = 3.141592653589793; + private static boolean randomInitialized = false; private Math() { } @@ -62,7 +63,17 @@ public final class Math { return (int) Math.floor(v + 0.5); } - public static native double random(); + public static double random() { + if (randomInitialized) { + natRandomInitialize(System.currentTimeMillis()); + randomInitialized = true; + } + return natRandom(); + } + + public static native void natRandomInitialize(long val); + + public static native double natRandom(); public static native double floor(double v); From 3f0e8a97777d4976870eba17764bd2f94d84e67f Mon Sep 17 00:00:00 2001 From: James Sanders Date: Wed, 28 Nov 2007 17:51:00 -0700 Subject: [PATCH 2/3] Implemented Runtime.exec(String) and Runtime.exec(String[]) and added test class --- test/RuntimeExec.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/RuntimeExec.java diff --git a/test/RuntimeExec.java b/test/RuntimeExec.java new file mode 100644 index 0000000000..86c03299c6 --- /dev/null +++ b/test/RuntimeExec.java @@ -0,0 +1,13 @@ +import java.lang.Runtime; + +public class RuntimeExec { + public static void main(String[] args) throws java.io.IOException { + System.out.println("Executing internet explorer"); + Runtime.getRuntime().exec("\"c:\\program files\\internet explorer\\iexplore.exe\" http://www.google.com"); + System.out.println("Executing firefox"); + String[] firefox = new String[2]; + firefox[0] = "c:\\program files\\mozilla firefox\\firefox.exe"; + firefox[1] = "http://www.google.com"; + Runtime.getRuntime().exec(firefox); + } +} From bf102aa1a8f46cbf97c7380a7478b0a21f7736c9 Mon Sep 17 00:00:00 2001 From: James Sanders Date: Wed, 28 Nov 2007 17:52:08 -0700 Subject: [PATCH 3/3] implemented Runtime.exec(String) and Runtime.exec(String[]) --- classpath/java-lang.cpp | 105 +++++++++++++++++++++++++++++++ classpath/java/lang/Runtime.java | 9 ++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index b377e0859a..bae74111d8 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -11,6 +11,8 @@ #ifdef WIN32 # include "windows.h" +# include "io.h" +# include "tchar.h" # define SO_PREFIX "" #else # define SO_PREFIX "lib" @@ -24,6 +26,109 @@ # define SO_SUFFIX ".so" #endif +namespace { +#ifdef WIN32 + void makePipe(JNIEnv* e, HANDLE p[2]) + { + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(sa); + sa.bInheritHandle = 1; + sa.lpSecurityDescriptor = 0; + + BOOL success = CreatePipe(p, p + 1, &sa, 0); + if (not success) { + char* errStr = (char*) malloc(9 * sizeof(char)); + snprintf(errStr, 9, "%d", (int) GetLastError()); + throwNew(e, "java/io/IOException", errStr); + } + } + + int descriptor(JNIEnv* e, HANDLE h) + { + int fd = _open_osfhandle(reinterpret_cast(h), 0); + if (fd == -1) { + throwNew(e, "java/io/IOException", strerror(errno)); + } + return fd; + } +#endif +} + +#ifdef WIN32 +extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass, + jobjectArray command, jintArray process) +{ + //const char* line = e->GetStringUTFChars(command, 0); + + int size = 0; + for (int i = 0; i < e->GetArrayLength(command); ++i){ + jstring element = (jstring) e->GetObjectArrayElement(command, i); + size += e->GetStringUTFLength(element) + 1; + } + + char line[size]; + char* linep = line; + for (int i = 0; i < e->GetArrayLength(command); ++i) { + if (i) *(linep++) = _T(' '); + jstring element = (jstring) e->GetObjectArrayElement(command, i); + const char* s = e->GetStringUTFChars(element, 0); + _tcscpy(linep, s); + linep += e->GetStringUTFLength(element); + } + *(linep++) = _T('\0'); + + printf("command: %s\n", _T(line)); + + HANDLE in[] = { 0, 0 }; + HANDLE out[] = { 0, 0 }; + HANDLE err[] = { 0, 0 }; + + makePipe(e, in); + SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0); + jint inDescriptor = descriptor(e, in[0]); + if(e->ExceptionOccurred()) return; + e->SetIntArrayRegion(process, 1, 1, &inDescriptor); + makePipe(e, out); + SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0); + jint outDescriptor = descriptor(e, out[1]); + if(e->ExceptionOccurred()) return; + e->SetIntArrayRegion(process, 2, 1, &outDescriptor); + makePipe(e, err); + SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0); + jint errDescriptor = descriptor(e, err[0]); + if(e->ExceptionOccurred()) return; + e->SetIntArrayRegion(process, 3, 1, &errDescriptor); + + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdOutput = in[1]; + si.hStdInput = out[0]; + si.hStdError = err[1]; + + BOOL success = CreateProcess(0, (LPSTR) line, 0, 0, 1, + CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, + 0, 0, &si, &pi); + + //e->ReleaseStringUTFChars(command, line); + + if (not success) { + char* errStr = (char*) malloc(9 * sizeof(char)); + snprintf(errStr, 9, "%d", (int) GetLastError()); + throwNew(e, "java/io/IOException", errStr); + return; + } + + jint pid = reinterpret_cast(pi.hProcess); + e->SetIntArrayRegion(process, 0, 1, &pid); + +} +#endif + extern "C" JNIEXPORT jstring JNICALL Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, jbooleanArray found) diff --git a/classpath/java/lang/Runtime.java b/classpath/java/lang/Runtime.java index 3546e388c2..f8478e0de9 100644 --- a/classpath/java/lang/Runtime.java +++ b/classpath/java/lang/Runtime.java @@ -6,6 +6,7 @@ import java.io.FileInputStream; import java.io.OutputStream; import java.io.FileOutputStream; import java.io.FileDescriptor; +import java.util.StringTokenizer; public class Runtime { private static final Runtime instance = new Runtime(); @@ -34,7 +35,11 @@ public class Runtime { public Process exec(String command) throws IOException { int[] process = new int[4]; - exec(command, process); + StringTokenizer t = new StringTokenizer(command); + String[] cmd = new String[t.countTokens()]; + for (int i = 0; i < cmd.length; i++) + cmd[i] = t.nextToken(); + exec(cmd, process); return new MyProcess(process[0], process[1], process[2], process[3]); } @@ -44,7 +49,7 @@ public class Runtime { return new MyProcess(process[0], process[1], process[2], process[3]); } - private static native void exec(String command, int[] process); + //private static native void exec(String command, int[] process); private static native void exec(String[] command, int[] process);