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);
 }