From 44f55673d683be254e684cfd0f0fca27a5f4446d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 9 Nov 2010 14:56:26 -0700 Subject: [PATCH] fix handle leaks in Windows Process implementation --- classpath/java-lang.cpp | 23 ++++++++++++++--------- classpath/java/lang/Runtime.java | 24 ++++++++++++++++-------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index e6751163ed..ee8a6456d4 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -165,17 +165,17 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0); jlong inDescriptor = static_cast(descriptor(e, in[0])); if(e->ExceptionCheck()) return; - e->SetLongArrayRegion(process, 1, 1, &inDescriptor); + e->SetLongArrayRegion(process, 2, 1, &inDescriptor); makePipe(e, out); SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0); jlong outDescriptor = static_cast(descriptor(e, out[1])); if(e->ExceptionCheck()) return; - e->SetLongArrayRegion(process, 2, 1, &outDescriptor); + e->SetLongArrayRegion(process, 3, 1, &outDescriptor); makePipe(e, err); SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0); jlong errDescriptor = static_cast(descriptor(e, err[0])); if(e->ExceptionCheck()) return; - e->SetLongArrayRegion(process, 3, 1, &errDescriptor); + e->SetLongArrayRegion(process, 4, 1, &errDescriptor); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); @@ -203,11 +203,12 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, jlong pid = reinterpret_cast(pi.hProcess); e->SetLongArrayRegion(process, 0, 1, &pid); - + jlong tid = reinterpret_cast(pi.hThread); + e->SetLongArrayRegion(process, 1, 1, &tid); } extern "C" JNIEXPORT jint JNICALL -Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid) +Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid) { DWORD exitCode; WaitForSingleObject(reinterpret_cast(pid), INFINITE); @@ -215,6 +216,10 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid) if(not success){ throwNew(e, "java/lang/Exception", getErrorStr(GetLastError())); } + + CloseHandle(reinterpret_cast(pid)); + CloseHandle(reinterpret_cast(tid)); + return exitCode; } #else @@ -240,15 +245,15 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, makePipe(e, in); if(e->ExceptionCheck()) return; jlong inDescriptor = static_cast(in[0]); - e->SetLongArrayRegion(process, 1, 1, &inDescriptor); + e->SetLongArrayRegion(process, 2, 1, &inDescriptor); makePipe(e, out); if(e->ExceptionCheck()) return; jlong outDescriptor = static_cast(out[1]); - e->SetLongArrayRegion(process, 2, 1, &outDescriptor); + e->SetLongArrayRegion(process, 3, 1, &outDescriptor); makePipe(e, err); if(e->ExceptionCheck()) return; jlong errDescriptor = static_cast(err[0]); - e->SetLongArrayRegion(process, 3, 1, &errDescriptor); + e->SetLongArrayRegion(process, 4, 1, &errDescriptor); makePipe(e, msg); if(e->ExceptionCheck()) return; if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) { @@ -309,7 +314,7 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, } extern "C" JNIEXPORT jint JNICALL -Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid) +Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid, jlong) { bool finished = false; int status; diff --git a/classpath/java/lang/Runtime.java b/classpath/java/lang/Runtime.java index 777e54398b..55f16cd456 100644 --- a/classpath/java/lang/Runtime.java +++ b/classpath/java/lang/Runtime.java @@ -43,7 +43,7 @@ public class Runtime { } } - public Process exec(String command) { + public Process exec(String command) throws IOException { StringTokenizer t = new StringTokenizer(command); String[] cmd = new String[t.countTokens()]; for (int i = 0; i < cmd.length; i++) @@ -52,7 +52,7 @@ public class Runtime { return exec(cmd); } - public Process exec(final String[] command) { + public Process exec(final String[] command) throws IOException { final MyProcess[] process = new MyProcess[1]; final Throwable[] exception = new Throwable[1]; @@ -61,10 +61,11 @@ public class Runtime { public void run() { synchronized (process) { try { - long[] info = new long[4]; + long[] info = new long[5]; exec(command, info); process[0] = new MyProcess - (info[0], (int) info[1], (int) info[2], (int) info[3]); + (info[0], info[1], (int) info[2], (int) info[3], + (int) info[4]); } catch (Throwable e) { exception[0] = e; } finally { @@ -77,8 +78,9 @@ public class Runtime { synchronized (p) { try { if (p.pid != 0) { - p.exitCode = Runtime.waitFor(p.pid); + p.exitCode = Runtime.waitFor(p.pid, p.tid); p.pid = 0; + p.tid = 0; } } finally { p.notifyAll(); @@ -100,7 +102,11 @@ public class Runtime { } if (exception[0] != null) { - throw new RuntimeException(exception[0]); + if (exception[0] instanceof IOException) { + throw new IOException(exception[0]); + } else { + throw new RuntimeException(exception[0]); + } } return process[0]; @@ -111,7 +117,7 @@ public class Runtime { private static native void exec(String[] command, long[] process) throws IOException; - private static native int waitFor(long pid); + private static native int waitFor(long pid, long tid); private static native void load(String name, boolean mapName); @@ -125,13 +131,15 @@ public class Runtime { private static class MyProcess extends Process { private long pid; + private long tid; private final int in; private final int out; private final int err; private int exitCode; - public MyProcess(long pid, int in, int out, int err) { + public MyProcess(long pid, long tid, int in, int out, int err) { this.pid = pid; + this.tid = tid; this.in = in; this.out = out; this.err = err;