src/windows/native/java/lang/ProcessImpl_md.c

Print this page

        

*** 38,61 **** * deadlock. Windows 2000 inexplicably appears to need an extra 24 * bytes of slop to avoid deadlock. */ #define PIPE_SIZE (4096+24) static void ! win32Error(JNIEnv *env, const char *functionName) { ! static const char * const format = "%s error=%d, %s"; ! static const char * const fallbackFormat = "%s failed, error=%d"; ! char buf[256]; ! char errmsg[sizeof(buf) + 100]; const int errnum = GetLastError(); ! const int n = JVM_GetLastErrorString(buf, sizeof(buf)); if (n > 0) ! sprintf(errmsg, format, functionName, errnum, buf); else ! sprintf(errmsg, fallbackFormat, functionName, errnum); ! JNU_ThrowIOException(env, errmsg); } static void closeSafely(HANDLE handle) { --- 38,129 ---- * deadlock. Windows 2000 inexplicably appears to need an extra 24 * bytes of slop to avoid deadlock. */ #define PIPE_SIZE (4096+24) + /* We have THREE locales in action: + * 1. Thread default locale - dictates UNICODE-to-8bit conversion + * 2. System locale that defines the message localization + * 3. The file name locale + * Each locale could be an extended locale, that means that text cannot be + * mapped to 8bit sequence without multibyte encoding. + * VM is ready for that, if text is UTF-8. + * Here we make the work right from the beginning. + */ + + /* Unicode version of JVM call: + * hotspot/src/os/windows/vm/os_windows.cpp: + * size_t os::lasterror(char* buf, size_t len) + * JVM version need to be fixed accordingly as well as + * jdk/src/windows/native/java/io/io_util_md.c + * size_t getLastErrorString(char *buf, size_t len) + */ + size_t os_lasterror(WCHAR* buf, size_t len) { + DWORD errval; + if ((errval = GetLastError()) != 0) { + /* DOS error*/ + size_t n = (size_t)FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errval, + 0, + buf, + (DWORD)len, + NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (buf[n - 1] == L'\n') n--; + if (buf[n - 1] == L'\r') n--; + if (buf[n - 1] == L'.') n--; + buf[n] = L'\0'; + } + return n; + } + + if (errno != 0) { + /* C runtime error that has no corresponding DOS error code */ + const WCHAR* s = _wcserror(errno); + size_t n = wcslen(s); + if (n >= len) n = len - 1; + wcsncpy(buf, s, n); + buf[n] = L'\0'; + return n; + } + + return 0; + } + + #define MESAGE_LENGTH (256 + 100) + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) + static void ! win32Error(JNIEnv *env, const WCHAR *functionName) { ! WCHAR utf16_OSErrorMsg[MESAGE_LENGTH - 100]; ! WCHAR utf16_javaMessage[MESAGE_LENGTH]; ! /*Good suggestion about 2-bytes-per-symbol in localized error reports*/ ! char utf8_javaMessage[MESAGE_LENGTH*2]; const int errnum = GetLastError(); ! const int n = os_lasterror(utf16_OSErrorMsg, ARRAY_SIZE(utf16_OSErrorMsg)); if (n > 0) ! swprintf(utf16_javaMessage, MESAGE_LENGTH, L"%s error=%d, %s", functionName, errnum, utf16_OSErrorMsg); else ! swprintf(utf16_javaMessage, MESAGE_LENGTH, L"%s failed, error=%d", functionName, errnum); ! ! WideCharToMultiByte( ! CP_UTF8, ! 0, ! utf16_javaMessage, ! MESAGE_LENGTH, ! utf8_javaMessage, ! MESAGE_LENGTH*2, ! NULL, ! NULL); ! ! /*no way to die*/ ! utf8_javaMessage[MESAGE_LENGTH*2 - 1] = '\0'; ! JNU_ThrowIOException(env, utf8_javaMessage); } static void closeSafely(HANDLE handle) {
*** 114,124 **** if (handles[0] != (jlong) -1) { si.hStdInput = (HANDLE) handles[0]; handles[0] = (jlong) -1; } else { if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { ! win32Error(env, "CreatePipe"); goto Catch; } si.hStdInput = inRead; SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, 0); handles[0] = (jlong) inWrite; --- 182,192 ---- if (handles[0] != (jlong) -1) { si.hStdInput = (HANDLE) handles[0]; handles[0] = (jlong) -1; } else { if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { ! win32Error(env, L"CreatePipe"); goto Catch; } si.hStdInput = inRead; SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, 0); handles[0] = (jlong) inWrite;
*** 130,140 **** if (handles[1] != (jlong) -1) { si.hStdOutput = (HANDLE) handles[1]; handles[1] = (jlong) -1; } else { if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { ! win32Error(env, "CreatePipe"); goto Catch; } si.hStdOutput = outWrite; SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, 0); handles[1] = (jlong) outRead; --- 198,208 ---- if (handles[1] != (jlong) -1) { si.hStdOutput = (HANDLE) handles[1]; handles[1] = (jlong) -1; } else { if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { ! win32Error(env, L"CreatePipe"); goto Catch; } si.hStdOutput = outWrite; SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, 0); handles[1] = (jlong) outRead;
*** 149,159 **** } else if (handles[2] != (jlong) -1) { si.hStdError = (HANDLE) handles[2]; handles[2] = (jlong) -1; } else { if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { ! win32Error(env, "CreatePipe"); goto Catch; } si.hStdError = errWrite; SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, 0); handles[2] = (jlong) errRead; --- 217,227 ---- } else if (handles[2] != (jlong) -1) { si.hStdError = (HANDLE) handles[2]; handles[2] = (jlong) -1; } else { if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { ! win32Error(env, L"CreatePipe"); goto Catch; } si.hStdError = errWrite; SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, 0); handles[2] = (jlong) errRead;
*** 172,182 **** (LPVOID)penvBlock,/* environment block */ (LPCWSTR)pdir, /* change to the new current directory */ &si, /* (in) startup information */ &pi); /* (out) process information */ if (!ret) { ! win32Error(env, "CreateProcess"); goto Catch; } CloseHandle(pi.hThread); ret = (jlong)pi.hProcess; --- 240,250 ---- (LPVOID)penvBlock,/* environment block */ (LPCWSTR)pdir, /* change to the new current directory */ &si, /* (in) startup information */ &pi); /* (out) process information */ if (!ret) { ! win32Error(env, L"CreateProcess"); goto Catch; } CloseHandle(pi.hThread); ret = (jlong)pi.hProcess;
*** 208,218 **** JNIEXPORT jint JNICALL Java_java_lang_ProcessImpl_getExitCodeProcess(JNIEnv *env, jclass ignored, jlong handle) { DWORD exit_code; if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0) ! win32Error(env, "GetExitCodeProcess"); return exit_code; } JNIEXPORT jint JNICALL Java_java_lang_ProcessImpl_getStillActive(JNIEnv *env, jclass ignored) --- 276,286 ---- JNIEXPORT jint JNICALL Java_java_lang_ProcessImpl_getExitCodeProcess(JNIEnv *env, jclass ignored, jlong handle) { DWORD exit_code; if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0) ! win32Error(env, L"GetExitCodeProcess"); return exit_code; } JNIEXPORT jint JNICALL Java_java_lang_ProcessImpl_getStillActive(JNIEnv *env, jclass ignored)
*** 229,239 **** if (WaitForMultipleObjects(sizeof(events)/sizeof(events[0]), events, FALSE, /* Wait for ANY event */ INFINITE) /* Wait forever */ == WAIT_FAILED) ! win32Error(env, "WaitForMultipleObjects"); } JNIEXPORT void JNICALL Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env, jclass ignored, --- 297,307 ---- if (WaitForMultipleObjects(sizeof(events)/sizeof(events[0]), events, FALSE, /* Wait for ANY event */ INFINITE) /* Wait forever */ == WAIT_FAILED) ! win32Error(env, L"WaitForMultipleObjects"); } JNIEXPORT void JNICALL Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env, jclass ignored,
*** 248,258 **** result = WaitForMultipleObjects(sizeof(events)/sizeof(events[0]), events, FALSE, /* Wait for ANY event */ dwTimeout); /* Wait for dwTimeout */ if (result == WAIT_FAILED) ! win32Error(env, "WaitForMultipleObjects"); } JNIEXPORT void JNICALL Java_java_lang_ProcessImpl_terminateProcess(JNIEnv *env, jclass ignored, jlong handle) { --- 316,326 ---- result = WaitForMultipleObjects(sizeof(events)/sizeof(events[0]), events, FALSE, /* Wait for ANY event */ dwTimeout); /* Wait for dwTimeout */ if (result == WAIT_FAILED) ! win32Error(env, L"WaitForMultipleObjects"); } JNIEXPORT void JNICALL Java_java_lang_ProcessImpl_terminateProcess(JNIEnv *env, jclass ignored, jlong handle) {
*** 261,271 **** JNIEXPORT jboolean JNICALL Java_java_lang_ProcessImpl_isProcessAlive(JNIEnv *env, jclass ignored, jlong handle) { DWORD dwExitStatus; ! GetExitCodeProcess(handle, &dwExitStatus); return dwExitStatus == STILL_ACTIVE; } JNIEXPORT jboolean JNICALL Java_java_lang_ProcessImpl_closeHandle(JNIEnv *env, jclass ignored, jlong handle) --- 329,339 ---- JNIEXPORT jboolean JNICALL Java_java_lang_ProcessImpl_isProcessAlive(JNIEnv *env, jclass ignored, jlong handle) { DWORD dwExitStatus; ! GetExitCodeProcess((HANDLE) handle, &dwExitStatus); return dwExitStatus == STILL_ACTIVE; } JNIEXPORT jboolean JNICALL Java_java_lang_ProcessImpl_closeHandle(JNIEnv *env, jclass ignored, jlong handle)