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)