You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/10/06 05:58:17 UTC
svn commit: r453484 - in
/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes:
javasrc/java/lang/Runtime.java native/Runtime_lnx.cpp native/Runtime_win.cpp
Author: geirm
Date: Thu Oct 5 20:58:16 2006
New Revision: 453484
URL: http://svn.apache.org/viewvc?view=rev&rev=453484
Log:
HARMONY-1573
Passes tests for linux - now testing on windows
Ubuntu 6 - smoke, c-unit, ~kernel, tests w/ JIRA
Modified:
incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java
incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_lnx.cpp
incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_win.cpp
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java?view=diff&rev=453484&r1=453483&r2=453484
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java Thu Oct 5 20:58:16 2006
@@ -147,15 +147,16 @@
*/
static void addShutdownHook(Thread hook) throws IllegalStateException, IllegalArgumentException {
+ if (hook.getState() != Thread.State.NEW) {
+ throw new IllegalArgumentException();
+ }
synchronized (hooksList) {
if (hooksList.contains((Object) hook)) {
throw new IllegalArgumentException();
}
}
- synchronized (Synchro.class) {
- if (VMState > 0) {
- throw new IllegalStateException();
- }
+ if (VMState > 0) {
+ throw new IllegalStateException();
}
synchronized (hooksList) {
hooksList.addElement((Object) hook);
@@ -169,10 +170,8 @@
*/
static boolean removeShutdownHook(Thread hook) throws IllegalStateException {
- synchronized (Synchro.class) {
- if (VMState > 0) {
- throw new IllegalStateException();
- }
+ if (VMState > 0) {
+ throw new IllegalStateException();
}
synchronized (hooksList) {
return hooksList == null ? false : hooksList.removeElement((Object) hook);
@@ -296,16 +295,11 @@
private final native void close0(long handle) throws IOException;
public final synchronized void close() throws IOException {
- if (streamHandle == -1) return;
-
- long handle = streamHandle;
- streamHandle = -1;
- close0(handle);
+ close0(streamHandle);
}
protected void finalize() throws Throwable {
- if (streamHandle != -1)
- close0(this.streamHandle);
+ close0(streamHandle);
}
}
@@ -412,15 +406,11 @@
private final native void close0(long handle);
public final synchronized void close() throws IOException {
- if (streamHandle == -1) return;
- long handle = streamHandle;
- streamHandle = -1;
- close0(handle);
+ close0(streamHandle);
}
protected void finalize() throws Throwable {
- if (streamHandle != -1)
- close0(this.streamHandle);
+ close0(streamHandle);
}
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_lnx.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_lnx.cpp?view=diff&rev=453484&r1=453483&r2=453484
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_lnx.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_lnx.cpp Thu Oct 5 20:58:16 2006
@@ -44,6 +44,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
+#include <sys/ioctl.h>
#include <sys/poll.h>
#include <errno.h>
@@ -55,9 +56,6 @@
jboolean jb = true;
jlong *lp = (jlong*)env->GetLongArrayElements(la, &jb);
lp[0] = 0;
- lp[1] = -1ll;
- lp[2] = -1ll;
- lp[3] = -1ll;
env->ReleaseLongArrayElements(la, lp, 0);
if (lpszMess != NULL) {
INFO(lpszMess);
@@ -300,36 +298,53 @@
}
jint JNICALL Java_java_lang_Runtime_00024SubProcess_00024SubInputStream_available0 (JNIEnv *env, jobject obj, jlong inputHandle) {
- struct pollfd r[1];
int res;
-
- r[0].fd = (int) inputHandle;
- r[0].events = POLLRDNORM;
- r[0].revents = 0;
-
- do {
- res = poll(r, 1, 0);
- } while (res == -1 && errno == EINTR);
-
- if (res == 1) {
- if(r[0].revents & r[0].events) {
- return 1; // Can we define the number certainly? Idea: can buffer be attached to pipe for preliminary reading or else one?
+ if (ioctl((int) inputHandle, FIONREAD, &res) == -1) {
+ if (errno == EINVAL) {
+ struct pollfd r[1];
+
+ r[0].fd = (int) inputHandle;
+ r[0].events = POLLRDNORM;
+ r[0].revents = 0;
+
+ do {
+ res = poll(r, 1, 0);
+ } while (res == -1 && errno == EINTR);
+
+ if (res == 1) {
+ if(r[0].revents & r[0].events) {
+ return 1; // So, in that case we can define one byte is available at least
+ } else if(r[0].revents & (POLLERR | POLLNVAL)) {
+ char mess[100];
+ mess[0] = '\0';
+ sprintf(mess, "%s", (r[0].revents & POLLERR ? "Some error condition has raised." : "Invalid request: handle closed."));
+ jclass jc = env->FindClass((const char *)"java/io/IOException");
+ env->ThrowNew(jc, (const char *) mess);
+ }
+ return 0;
+ } else if (res < 0) {
+ char mess[100];
+ mess[0] = '\0';
+ sprintf(mess, "It's impossible to identify if there are available bytes in the input stream! ERRNO=%d. %s", errno, strerror(errno));
+ jclass jc = env->FindClass((const char *)"java/io/IOException");
+ env->ThrowNew(jc, (const char *) mess);
+ }
+ return 0;
+ } else {
+ char mess[100];
+ mess[0] = '\0';
+ sprintf(mess, "%s", "Some error condition has raised.");
+ jclass jc = env->FindClass((const char *)"java/io/IOException");
+ env->ThrowNew(jc, (const char *) mess);
}
- return 0;
- } else if (res < 0) {
- char mess[100];
- mess[0] = '\0';
- sprintf(mess, "It's impossible to identify if there are available bytes in the input stream! ERRNO=%d. %s", errno, strerror(errno));
- jclass jc = env->FindClass((const char *)"java/io/IOException");
- env->ThrowNew(jc, (const char *) mess);
}
- return 0;
+ return res;
}
void JNICALL Java_java_lang_Runtime_00024SubProcess_00024SubInputStream_close0 (JNIEnv *env, jobject obj, jlong inputHandle) {
int res = close((int) inputHandle);
- if (res == -1) {
+ if (res == -1 && errno != EBADF) {
ThrowError(env);
}
}
@@ -383,7 +398,7 @@
void JNICALL Java_java_lang_Runtime_00024SubProcess_00024SubOutputStream_close0 (JNIEnv *env, jobject obj, jlong outputHandle) {
int res = close((int) outputHandle);
- if (res == -1) {
+ if (res == -1 && errno != EBADF) {
ThrowError(env);
}
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_win.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_win.cpp?view=diff&rev=453484&r1=453483&r2=453484
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_win.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/Runtime_win.cpp Thu Oct 5 20:58:16 2006
@@ -37,9 +37,6 @@
{
jlong *lp = (jlong*)env->GetLongArrayElements(la, 0);
lp[0] = 0;
- lp[1] = 0;
- lp[2] = 0;
- lp[3] = 0;
env->ReleaseLongArrayElements(la, lp, 0);
INFO(lpszMess);
@@ -94,8 +91,8 @@
{
TRACE("Creating child process ...");
- HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
- hChildStderrorRd, hChildStderrorWr;
+ HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup, hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
+ hChildStderrorRd, hChildStderrorWr, hChildStderrorRdDup;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
SECURITY_ATTRIBUTES saAttr;
@@ -107,8 +104,9 @@
}
// Get the the command to call and its arguments:
- int l = 1024;
- char *strCmnd = (char*)malloc(1024);
+ int btl = 1024;
+ int l = btl;
+ char *strCmnd = (char*)malloc(btl);
*strCmnd = '\0';
jsize len = env->GetArrayLength(cmdarray);
int cur_pos = 0;
@@ -117,15 +115,14 @@
jstring jo = (jstring)env->GetObjectArrayElement(cmdarray, (jsize) i);
const char *strChain = env->GetStringUTFChars(jo, 0);
bool need_esc = (*strChain != '\"' && strchr(strChain, ' ') != NULL);
- cur_pos += strlen(strChain) + 1 + (need_esc ? 0 : 2);
+ cur_pos += strlen(strChain) + (i == 0 ? 0 : 1) + (need_esc ? 0 : 2);
while (l <= cur_pos) {
- char *strtmp = (char*)malloc(l + 1024);
+ char *strtmp = (char*)malloc(l + btl);
memcpy(strtmp, strCmnd, l);
- l += 1024;
+ l += btl;
free((void *)strCmnd);
strCmnd = strtmp;
}
-
if ( i != 0 ) {
strcat(strCmnd, " ");
}
@@ -141,8 +138,8 @@
char *strEnvp = NULL;
// Get the array, each element of which has environment variable settings:
if (envp != NULL) {
- int l = 1024;
- strEnvp = (char*)malloc(1024);
+ int l = btl;
+ strEnvp = (char*)malloc(btl);
*strEnvp = '\0';
len = env->GetArrayLength(envp);
cur_pos = 0;
@@ -151,9 +148,9 @@
const char* strChain = env->GetStringUTFChars(jo, 0);
size_t tmp = strlen(strChain) + 1;
while ((unsigned)l <= (cur_pos + tmp)) {
- char *strtmp = (char*)malloc(l + 1024);
+ char *strtmp = (char*)malloc(l + btl);
memcpy(strtmp, strEnvp, l);
- l += 1024;
+ l += btl;
free(strEnvp);
strEnvp = strtmp;
}
@@ -168,32 +165,71 @@
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
-
- // Create a pipe for the child process's STDOUT.
- if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
- Error("Stdout pipe creation failed\n", env, la);
- return;
- }
-
- // Create anonymous pipe to be STDERROR for child process.
- if (! CreatePipe(&hChildStderrorRd, &hChildStderrorWr, &saAttr, 0)) {
- CloseHandle(hChildStdoutRd);
- CloseHandle(hChildStdoutWr);
- Error("Stderror pipe creation failed\n", env, la);
- return;
- }
-
- // Create anonymous pipe to be STDIN for child process.
- if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
- CloseHandle(hChildStdoutRd);
- CloseHandle(hChildStdoutWr);
- CloseHandle(hChildStderrorRd);
- CloseHandle(hChildStderrorWr);
- Error("Stdin pipe creation failed\n", env, la);
- return;
- }
-
- // Now create the child process:
+
+ // Preparation of the child process's STDOUT:
+
+ // 1. Create a pipe for the child process's STDOUT.
+ if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
+ Error("Stdout pipe creation failed\n", env, la);
+ return;
+ }
+
+ // 2. Create noninheritable read handle and close the inheritable read handle.
+ if( !DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
+ CloseHandle(hChildStdoutRd);
+ CloseHandle(hChildStdoutWr);
+ Error("DuplicateHandle failed", env, la);
+ return;
+ }
+ CloseHandle(hChildStdoutRd);
+
+ // Preparation of the child process's STDERROR:
+
+ // 1. Create anonymous pipe to be STDERROR for child process.
+ if (! CreatePipe(&hChildStderrorRd, &hChildStderrorWr, &saAttr, 0)) {
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStdoutWr);
+ Error("Stderror pipe creation failed\n", env, la);
+ return;
+ }
+
+ // 2. Create a noninheritable duplicate of the read handle, and close the inheritable read handle.
+ if( !DuplicateHandle(GetCurrentProcess(), hChildStderrorRd, GetCurrentProcess(), &hChildStderrorRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStdoutWr);
+ CloseHandle(hChildStderrorRd);
+ CloseHandle(hChildStderrorWr);
+ Error("DuplicateHandle failed", env, la);
+ return;
+ }
+ CloseHandle(hChildStderrorRd);
+
+ // Preparation of the child process's STDIN:
+
+ // 1. Create anonymous pipe to be STDIN for child process.
+ if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStdoutWr);
+ CloseHandle(hChildStderrorRdDup);
+ CloseHandle(hChildStderrorWr);
+ Error("Stdin pipe creation failed\n", env, la);
+ return;
+ }
+
+ // 2. Create a noninheritable duplicate of the write handle, and close the inheritable write handle.
+ if ( !DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStdoutWr);
+ CloseHandle(hChildStderrorRdDup);
+ CloseHandle(hChildStderrorWr);
+ CloseHandle(hChildStdinRd);
+ CloseHandle(hChildStdinWr);
+ Error("DuplicateHandle failed", env, la);
+ return;
+ }
+ CloseHandle(hChildStdinWr);
+
+ // Now create the child process:
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
@@ -234,15 +270,15 @@
if (created) {
CloseHandle(piProcInfo.hThread);
jlong *lp = (jlong*)env->GetLongArrayElements(la, 0);
- lp[0] = (jlong) piProcInfo.hProcess;
- lp[1] = (jlong) hChildStdinWr;
- lp[2] = (jlong) hChildStdoutRd;
- lp[3] = (jlong) hChildStderrorRd;
+ lp[0] = (jlong) piProcInfo.hProcess;
+ lp[1] = (jlong) hChildStdinWrDup;
+ lp[2] = (jlong) hChildStdoutRdDup;
+ lp[3] = (jlong) hChildStderrorRdDup;
env->ReleaseLongArrayElements(la, lp, 0);
} else {
- CloseHandle(hChildStdoutRd);
- CloseHandle(hChildStderrorRd);
- CloseHandle(hChildStdinWr);
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStderrorRdDup);
+ CloseHandle(hChildStdinWrDup);
}
}
@@ -283,7 +319,7 @@
TerminateProcess(
(HANDLE) handle /* handle to the process */,
- 0 /* exit code for the process */ );
+ ERROR_PROCESS_ABORTED /* exit code for the process */ );
}
void JNICALL Java_java_lang_Runtime_00024SubProcess_close0 (JNIEnv *env, jobject obj, jint handle) {
@@ -366,7 +402,7 @@
JNIEnv *env, jobject obj, jlong inputHandle)
{
DWORD res = CloseHandle((HANDLE)(POINTER_SIZE_INT)inputHandle);
- if (res == 0) {
+ if (res == 0 && GetLastError() != ERROR_INVALID_HANDLE) {
ThrowError(env);
}
}
@@ -424,5 +460,5 @@
void JNICALL Java_java_lang_Runtime_00024SubProcess_00024SubOutputStream_close0 (JNIEnv *env, jobject obj, jlong outputHandle) {
DWORD res = CloseHandle((HANDLE)(POINTER_SIZE_INT)outputHandle /* handle to pipe */ );
- if (res == 0) ThrowError(env);
+ if (res == 0 && GetLastError() != ERROR_INVALID_HANDLE) ThrowError(env);
}