diff --git a/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/pty.dll b/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/pty.dll new file mode 100644 index 00000000000..65946aaee7a Binary files /dev/null and b/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/pty.dll differ diff --git a/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/winpty-agent.exe b/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/winpty-agent.exe new file mode 100644 index 00000000000..021e086947f Binary files /dev/null and b/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/winpty-agent.exe differ diff --git a/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/winpty.dll b/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/winpty.dll new file mode 100644 index 00000000000..b4672786d70 Binary files /dev/null and b/core/org.eclipse.cdt.core.win32.x86/os/win32/x86/winpty.dll differ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll new file mode 100644 index 00000000000..e0ad8c13bd3 Binary files /dev/null and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll differ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/winpty-agent.exe b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/winpty-agent.exe new file mode 100644 index 00000000000..0dc90fd36dc Binary files /dev/null and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/winpty-agent.exe differ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/winpty.dll b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/winpty.dll new file mode 100644 index 00000000000..cda66d0dd59 Binary files /dev/null and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/winpty.dll differ diff --git a/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTY.h b/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTY.h new file mode 100644 index 00000000000..5c80c5793c8 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTY.h @@ -0,0 +1,45 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_eclipse_cdt_utils_pty_PTY */ + +#ifndef _Included_org_eclipse_cdt_utils_pty_PTY +#define _Included_org_eclipse_cdt_utils_pty_PTY +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: openMaster + * Signature: (Z)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster + (JNIEnv *, jobject, jboolean); + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: change_window_size + * Signature: (III)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_change_1window_1size + (JNIEnv *, jobject, jint, jint, jint); + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: exec2 + * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;IZ)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_exec2 + (JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint, jboolean); + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: waitFor + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_waitFor + (JNIEnv *, jobject, jint, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTYInputStream.h b/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTYInputStream.h new file mode 100644 index 00000000000..86cd5bdd240 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTYInputStream.h @@ -0,0 +1,31 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_eclipse_cdt_utils_pty_PTYInputStream */ + +#ifndef _Included_org_eclipse_cdt_utils_pty_PTYInputStream +#define _Included_org_eclipse_cdt_utils_pty_PTYInputStream +#ifdef __cplusplus +extern "C" { +#endif +#undef org_eclipse_cdt_utils_pty_PTYInputStream_MAX_SKIP_BUFFER_SIZE +#define org_eclipse_cdt_utils_pty_PTYInputStream_MAX_SKIP_BUFFER_SIZE 2048L +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: read0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_read0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTYOutputStream.h b/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTYOutputStream.h new file mode 100644 index 00000000000..108ef248d8c --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/jni/include/PTYOutputStream.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_eclipse_cdt_utils_pty_PTYOutputStream */ + +#ifndef _Included_org_eclipse_cdt_utils_pty_PTYOutputStream +#define _Included_org_eclipse_cdt_utils_pty_PTYOutputStream +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: write0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_write0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.win32/library/pty/jni/src/dllmain.cpp b/core/org.eclipse.cdt.core.win32/library/pty/jni/src/dllmain.cpp new file mode 100644 index 00000000000..c19f2ebbdcc --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/jni/src/dllmain.cpp @@ -0,0 +1,71 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include +#include +#include + +#pragma comment(lib, "delayimp") + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +static HMODULE getCurrentModule() +{ + HMODULE module; + if (!GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)getCurrentModule, + &module)) { + assert(false); + } + return module; +} + +HMODULE PTYExplicitLoadLibrary( LPCSTR pszModuleName ) +{ + if( lstrcmpiA( pszModuleName, "winpty.dll" ) == 0 ) + { + CHAR szPath[MAX_PATH] = ""; + //_hdllInstance is the HMODULE of *this* module + DWORD cchPath = GetModuleFileNameA(getCurrentModule(), szPath, MAX_PATH ); + while( cchPath > 0 ) + { + switch( szPath[cchPath - 1] ) + { + case '\\': + case '/': + case ':': + break; + default: + --cchPath; + continue; + } + break; //stop searching; found path separator + } + lstrcpynA( szPath + cchPath, pszModuleName, MAX_PATH - cchPath ); + return LoadLibraryA( szPath ); //call with full path to dependent DLL + } + return NULL; +} + +FARPROC WINAPI PTYDliNotifyHook( unsigned dliNotify, PDelayLoadInfo pdli ) +{ + if( dliNotify == dliNotePreLoadLibrary ) + return (FARPROC)PTYExplicitLoadLibrary( pdli->szDll ); + return NULL; +} + +extern "C" PfnDliHook __pfnDliNotifyHook2 = PTYDliNotifyHook; diff --git a/core/org.eclipse.cdt.core.win32/library/pty/jni/src/pty.cpp b/core/org.eclipse.cdt.core.win32/library/pty/jni/src/pty.cpp new file mode 100644 index 00000000000..d1b5f42c163 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/jni/src/pty.cpp @@ -0,0 +1,416 @@ +/******************************************************************************* + * Copyright (c) 2013 Wind River Systems, Inc. and others. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ + +#include "PTY.h" +#include "PTYInputStream.h" +#include "PTYOutputStream.h" +#include "winpty.h" + +#include +#include +#include +#include +#include +#include + +static std::map fd2pty; +static std::map fd2rc; + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: openMaster + * Signature: (Z)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster(JNIEnv *env, jobject jobj, jboolean console) +{ + jfieldID fid; /* Store the field ID */ + jstring jstr = NULL; + jclass cls; + + int master = -1; + char line[1024]; + + line[0] = '\0'; + + /* Open new winpty handle */ + winpty_t* winpty = winpty_open(80, 40); + if (winpty == NULL) { + return NULL; + } + + /* Configure console mode */ + if (console) { + winpty_set_console_mode(winpty, 1); + } + + /* Generate masterFD based on current system time */ + srand((unsigned int)time(NULL)); + master = rand(); + + sprintf(line, "winpty_%i", master); + + /* Remember the winpty handle for the generated masterFD */ + fd2pty.insert(std::pair(master, winpty)); + + /* Get a reference to the obj's class */ + cls = env->GetObjectClass(jobj); + + /* Set the master fd. */ + fid = env->GetFieldID(cls, "master", "I"); + if (fid == NULL) { + return NULL; + } + env->SetIntField(jobj, fid, (jint)master); + + /* Create a new String for the slave. */ + jstr = env->NewStringUTF(line); + + return jstr; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: change_window_size + * Signature: (III)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_change_1window_1size(JNIEnv *env, jobject jobj, jint fdm, jint width, jint height) +{ + int fd; + std::map :: const_iterator fd2pty_Iter; + + fd = fdm; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) + return winpty_set_size(winpty, width, height); + } + + return 0; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: read0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_read0 + (JNIEnv *env, jobject jobj, jint jfd, jbyteArray buf, jint buf_len) +{ + DWORD amount = -1; + OVERLAPPED over; + int fd; + std::map :: const_iterator fd2pty_Iter; + + fd = jfd; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) { + /* Get the pipe handle */ + HANDLE handle = winpty_get_data_pipe(winpty); + + memset(&over, 0, sizeof(over)); + over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + char *buffer = new char[buf_len]; + memset(buffer, 0, sizeof(*buffer)); + + jbyte *data = env->GetByteArrayElements(buf, 0); + memset(data, 0, sizeof(*data)); + + amount = 0; + BOOL ret = ReadFile(handle, buffer, buf_len, &amount, &over); + if (!ret) { + DWORD error = GetLastError(); + if (error == ERROR_IO_PENDING) + ret = GetOverlappedResult(handle, &over, &amount, TRUE); + } + + if (ret && amount > 0) + memcpy(data, buffer, amount); + + if (!ret || amount == 0) + amount = -1; + + if (!ret) { + int rc = winpty_get_exit_code(winpty); + fd2rc.insert(std::pair(fd, rc)); + } + + delete[] buffer; + env->ReleaseByteArrayElements(buf, data, 0); + ResetEvent(over.hEvent); + } + } + + return amount; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0(JNIEnv *env, jobject jobj, jint jfd) +{ + int fd; + std::map :: iterator fd2pty_Iter; + + fd = jfd; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) { + winpty_close(winpty); + winpty = NULL; + } + fd2pty.erase(fd2pty_Iter); + } + + return 0; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: write0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_write0(JNIEnv *env, jobject jobj, jint jfd, jbyteArray buf, jint buf_len) +{ + DWORD written = -1; + OVERLAPPED over; + int fd; + std::map :: iterator fd2pty_Iter; + + fd = jfd; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) { + /* Get the pipe handle */ + HANDLE handle = winpty_get_data_pipe(winpty); + + memset(&over, 0, sizeof(over)); + over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + char *buffer = new char[buf_len]; + memset(buffer, 0, sizeof(*buffer)); + + jbyte *data = env->GetByteArrayElements(buf, 0); + memcpy(buffer, data, buf_len); + + BOOL ret = WriteFile(handle, buffer, buf_len, &written, &over); + env->ReleaseByteArrayElements(buf, data, 0); + + if (!ret && GetLastError() == ERROR_IO_PENDING) + ret = GetOverlappedResult(handle, &over, &written, TRUE); + if (!ret || (int)written != buf_len) + written = -1; + + delete[] buffer; + } + } + + return written; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0(JNIEnv *env, jobject jobj, jint jfd) +{ + int fd; + std::map :: iterator fd2pty_Iter; + + fd = jfd; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) { + winpty_close(winpty); + winpty = NULL; + } + fd2pty.erase(fd2pty_Iter); + } + + return 0; +} + +/* + * Convert convert slashes to backslashes. + */ +static std::wstring convertSlashes(const wchar_t *path) +{ + std::wstring ret; + + for (int i = 0; path[i] != L'\0'; ++i) { + if (path[i] == L'/') + ret.push_back(L'\\'); + else + ret.push_back(path[i]); + } + + return ret; +} + +// Convert argc/argv into a Win32 command-line following the escaping convention +// documented on MSDN. (e.g. see CommandLineToArgvW documentation) +static std::wstring argvToCommandLine(const std::vector &argv) +{ + std::wstring result; + for (size_t argIndex = 0; argIndex < argv.size(); ++argIndex) { + if (argIndex > 0) + result.push_back(L' '); + const wchar_t *arg = argv[argIndex].c_str(); + const bool quote = + wcschr(arg, L' ') != NULL || + wcschr(arg, L'\t') != NULL || + *arg == L'\0'; + if (quote) + result.push_back(L'\"'); + int bsCount = 0; + for (const wchar_t *p = arg; *p != L'\0'; ++p) { + if (*p == L'\\') { + bsCount++; + } else if (*p == L'\"') { + result.append(bsCount * 2 + 1, L'\\'); + result.push_back(L'\"'); + bsCount = 0; + } else { + result.append(bsCount, L'\\'); + bsCount = 0; + result.push_back(*p); + } + } + if (quote) { + result.append(bsCount * 2, L'\\'); + result.push_back(L'\"'); + } else { + result.append(bsCount, L'\\'); + } + } + return result; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: exec2 + * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;IZ)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_exec2 + (JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jintArray jchannels, jstring jslaveName, jint masterFD, jboolean console) +{ + int fd; + std::map :: iterator fd2pty_Iter; + + jint *channels = env->GetIntArrayElements(jchannels, 0); + const wchar_t *cwdW = (const wchar_t *) env->GetStringChars(jdir, NULL); + const char *pts_name = env->GetStringUTFChars(jslaveName, NULL); + + int pid = -1; + + int i; + jint argc = env->GetArrayLength(jcmd); + jint envc = env->GetArrayLength(jenv); + + if (channels == NULL) + goto bail_out; + + fd = masterFD; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) { + std::vector argVector; + + for (i = 0; i < argc; i++) { + jstring j_str = (jstring) env->GetObjectArrayElement(jcmd, i); + const wchar_t *w_str = (const wchar_t *) env->GetStringChars(j_str, NULL); + if (i == 0) argVector.push_back(convertSlashes(w_str)); + else argVector.push_back(w_str); + env->ReleaseStringChars(j_str, (const jchar *) w_str); + env->DeleteLocalRef(j_str); + } + + std::wstring envp; + + for (i = 0; i < envc; i++) { + jstring j_str = (jstring) env->GetObjectArrayElement(jenv, i); + const wchar_t *w_str = (const wchar_t *) env->GetStringChars(j_str, NULL); + envp.append(w_str); + envp.push_back(L'\0'); + env->ReleaseStringChars(j_str, (const jchar *) w_str); + env->DeleteLocalRef(j_str); + } + + std::wstring cmdLine = argvToCommandLine(argVector); + const wchar_t *cmdLineW = cmdLine.c_str(); + + int ret = winpty_start_process(winpty, + NULL, + cmdLineW, + cwdW, + envp.c_str()); + + if (ret == 0) { + // Success. Get the process id. + pid = winpty_get_process_id(winpty); + } + } + } + +bail_out: + env->ReleaseIntArrayElements(jchannels, channels, 0); + env->ReleaseStringChars(jdir, (const jchar *) cwdW); + env->ReleaseStringUTFChars(jslaveName, pts_name); + + return pid; +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: waitFor + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_waitFor + (JNIEnv *env, jobject jobj, jint masterFD, jint pid) +{ + int status = -1; + DWORD flags; + + int fd; + std::map :: iterator fd2pty_Iter; + std::map :: iterator fd2rc_Iter; + + fd = masterFD; + fd2pty_Iter = fd2pty.find(fd); + if (fd2pty_Iter != fd2pty.end()) { + winpty_t* winpty = fd2pty_Iter -> second; + if (winpty != NULL) { + HANDLE handle = winpty_get_data_pipe(winpty); + BOOL success; + do { + success = GetHandleInformation(handle, &flags); + if (success) Sleep(500); + } while (success); + + fd2rc_Iter = fd2rc.find(fd); + if (fd2rc_Iter != fd2rc.end()) { + status = fd2rc_Iter -> second; + fd2rc.erase(fd2rc_Iter); + } + } + } + + return status; +} diff --git a/core/org.eclipse.cdt.core.win32/library/pty/pty.sln b/core/org.eclipse.cdt.core.win32/library/pty/pty.sln new file mode 100644 index 00000000000..bd82345255b --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/pty.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pty", "pty.vcxproj", "{5589D515-1C56-4641-97CF-3C4561109258}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winpty", "winpty.vcxproj", "{D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winpty-agent", "winpty-agent.vcxproj", "{E7A42398-12E7-4BC1-B72B-5D62B71E9816}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5589D515-1C56-4641-97CF-3C4561109258}.Debug|Win32.ActiveCfg = Debug|Win32 + {5589D515-1C56-4641-97CF-3C4561109258}.Debug|Win32.Build.0 = Debug|Win32 + {5589D515-1C56-4641-97CF-3C4561109258}.Debug|x64.ActiveCfg = Debug|x64 + {5589D515-1C56-4641-97CF-3C4561109258}.Debug|x64.Build.0 = Debug|x64 + {5589D515-1C56-4641-97CF-3C4561109258}.Release|Win32.ActiveCfg = Release|Win32 + {5589D515-1C56-4641-97CF-3C4561109258}.Release|Win32.Build.0 = Release|Win32 + {5589D515-1C56-4641-97CF-3C4561109258}.Release|x64.ActiveCfg = Release|x64 + {5589D515-1C56-4641-97CF-3C4561109258}.Release|x64.Build.0 = Release|x64 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Debug|Win32.Build.0 = Debug|Win32 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Debug|x64.ActiveCfg = Debug|x64 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Debug|x64.Build.0 = Debug|x64 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Release|Win32.ActiveCfg = Release|Win32 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Release|Win32.Build.0 = Release|Win32 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Release|x64.ActiveCfg = Release|x64 + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD}.Release|x64.Build.0 = Release|x64 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Debug|Win32.ActiveCfg = Debug|Win32 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Debug|Win32.Build.0 = Debug|Win32 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Debug|x64.ActiveCfg = Debug|x64 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Debug|x64.Build.0 = Debug|x64 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Release|Win32.ActiveCfg = Release|Win32 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Release|Win32.Build.0 = Release|Win32 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Release|x64.ActiveCfg = Release|x64 + {E7A42398-12E7-4BC1-B72B-5D62B71E9816}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/core/org.eclipse.cdt.core.win32/library/pty/pty.vcxproj b/core/org.eclipse.cdt.core.win32/library/pty/pty.vcxproj new file mode 100644 index 00000000000..29311ce2b06 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/pty.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {5589D515-1C56-4641-97CF-3C4561109258} + Win32Proj + pty + + + + DynamicLibrary + true + Unicode + Windows7.1SDK + + + DynamicLibrary + true + Unicode + Windows7.1SDK + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + true + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ./jni/include;C:\NoScan\Apps\Java\jdk1.6.0_31\include;C:\NoScan\Apps\Java\jdk1.6.0_31\include\win32;..\winpty\include;.;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Windows + true + DelayImp.lib;winpty.lib;%(AdditionalDependencies) + $(SolutionDir)$(Platform)\$(Configuration)\ + winpty.dll;%(DelayLoadDLLs) + + + + + NotUsing + Level3 + Disabled + _SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + ./jni/include;C:\NoScan\Apps\Java\jdk1.6.0_31\include;C:\NoScan\Apps\Java\jdk1.6.0_31\include\win32;..\winpty\include;.;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Windows + true + DelayImp.lib;winpty.lib;%(AdditionalDependencies) + $(SolutionDir)$(Platform)\$(Configuration)\ + winpty.dll;%(DelayLoadDLLs) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ./jni/include;C:\NoScan\Apps\Java\jdk1.6.0_31\include;C:\NoScan\Apps\Java\jdk1.6.0_31\include\win32;..\winpty\include;.;%(AdditionalIncludeDirectories) + MultiThreaded + + + Windows + true + true + true + DelayImp.lib;winpty.lib;%(AdditionalDependencies) + $(SolutionDir)$(Platform)\$(Configuration)\ + winpty.dll;%(DelayLoadDLLs) + + + + + Level3 + + + MaxSpeed + true + true + _SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + ./jni/include;C:\NoScan\Apps\Java\jdk1.6.0_31\include;C:\NoScan\Apps\Java\jdk1.6.0_31\include\win32;..\winpty\include;.;%(AdditionalIncludeDirectories) + MultiThreaded + + + Windows + true + true + true + DelayImp.lib;winpty.lib;%(AdditionalDependencies) + $(SolutionDir)$(Platform)\$(Configuration)\ + winpty.dll;%(DelayLoadDLLs) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/pty/pty.vcxproj.filters b/core/org.eclipse.cdt.core.win32/library/pty/pty.vcxproj.filters new file mode 100644 index 00000000000..4c428115fd8 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/pty.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {679c3039-d4a8-48db-9a3b-33f73f3b44c0} + + + {b7f98685-8f42-40d2-bd2b-65bcbac17645} + + + + + include + + + include + + + include + + + + + src + + + src + + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/pty/winpty-agent.vcxproj b/core/org.eclipse.cdt.core.win32/library/pty/winpty-agent.vcxproj new file mode 100644 index 00000000000..69e8ac3b008 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/winpty-agent.vcxproj @@ -0,0 +1,185 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {E7A42398-12E7-4BC1-B72B-5D62B71E9816} + Win32Proj + winptyagent + + + + Application + true + Unicode + Windows7.1SDK + + + Application + true + Unicode + Windows7.1SDK + + + Application + false + true + Unicode + Windows7.1SDK + + + Application + false + true + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + NotUsing + Level3 + Disabled + WIN32;_WINDOWS;NOMINMAX;_DEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Console + true + + + + + NotUsing + Level3 + Disabled + WIN32;_WINDOWS;NOMINMAX;_DEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Console + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;_WINDOWS;NOMINMAX;NDEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreaded + + + Console + false + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;_WINDOWS;NOMINMAX;NDEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreaded + + + Console + false + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/pty/winpty-agent.vcxproj.filters b/core/org.eclipse.cdt.core.win32/library/pty/winpty-agent.vcxproj.filters new file mode 100644 index 00000000000..17401866621 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/winpty-agent.vcxproj.filters @@ -0,0 +1,90 @@ + + + + + {a7174beb-334f-4496-868c-348a80e5f4d8} + + + {0c9e153d-99b4-4f47-ba3c-57e53e1c71b7} + + + + + shared + + + shared + + + shared + + + shared + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + + + shared + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/pty/winpty.vcxproj b/core/org.eclipse.cdt.core.win32/library/pty/winpty.vcxproj new file mode 100644 index 00000000000..bf4fabb5b4d --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/winpty.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D7BFF73A-A86A-47FF-AD2B-CC2EFCAD5ABD} + Win32Proj + winpty + + + + DynamicLibrary + true + Unicode + Windows7.1SDK + + + DynamicLibrary + true + Unicode + Windows7.1SDK + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + DynamicLibrary + false + true + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + NotUsing + Level3 + Disabled + WIN32;NOMINMAX;_DEBUG;_WINDOWS;_USRDLL;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WINPTY;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Windows + true + + + + + NotUsing + Level3 + Disabled + WIN32;_WINDOWS;NOMINMAX;_DEBUG;_USRDLL;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WINPTY;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Windows + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NOMINMAX;NDEBUG;_WINDOWS;_USRDLL;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WINPTY;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreaded + + + Windows + false + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;_WINDOWS;NOMINMAX;NDEBUG;_USRDLL;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WINPTY;%(PreprocessorDefinitions) + ..\winpty\include;%(AdditionalIncludeDirectories) + MultiThreaded + + + Windows + false + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/pty/winpty.vcxproj.filters b/core/org.eclipse.cdt.core.win32/library/pty/winpty.vcxproj.filters new file mode 100644 index 00000000000..ad2b6019f77 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/pty/winpty.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {6f8f9f7f-1797-423e-9189-990b2baff405} + + + {6fa1f334-3a7c-4a8c-970b-15c2a6a08ba2} + + + {84962cba-90e7-4b83-8656-6563b933bb73} + + + + + shared + + + shared + + + shared + + + shared + + + include + + + + + shared + + + libwinpty + + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/pty/PTY.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/pty/PTY.java index 137955125db..9782765e0e6 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/pty/PTY.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/pty/PTY.java @@ -14,22 +14,38 @@ package org.eclipse.cdt.utils.pty; import java.io.IOException; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.utils.spawner.Spawner; +import org.eclipse.core.runtime.Platform; /** * PTY - pseudo terminal support. */ public class PTY { + /** + * The pty modes. + * @since 5.6 + */ + public enum Mode { + /** This mode is for use with an Eclipse console. */ + CONSOLE, + /** This mode is for use with a terminal emulator. */ + TERMINAL + } + final boolean console; - String slave; - PTYInputStream in; - PTYOutputStream out; + final String slave; + final PTYInputStream in; + final PTYOutputStream out; + /** * NOTE: Field is accessed by the native layer. Do not refactor! */ int master; private static boolean hasPTY; + private static boolean isWinPTY; + private static boolean isConsoleModeSupported; private static boolean setTerminalSizeErrorAlreadyLogged; /** @@ -47,12 +63,53 @@ public class PTY { } } + /** + * @return whether PTY support for console mode is available on this platform + */ + public static boolean isSupported() { + return isSupported(Mode.CONSOLE); + } + + /** + * @return whether PTY support for given mode is available on this platform + * @since 5.6 + */ + public static boolean isSupported(Mode mode ) { + return hasPTY && (isConsoleModeSupported || mode == Mode.TERMINAL); + } + + /** * Create PTY for use with Eclipse console. - * Identical to {@link PTY#PTY(boolean) PTY(true)}. + * Identical to {@link PTY#PTY(boolean) PTY(Mode.CONSOLE)}. */ public PTY() throws IOException { - this(true); + this(Mode.CONSOLE); + } + + /** + * Create PTY for given mode. + * + *

+ * The provided mode indicates whether the pseudo terminal is used with the interactive + * Eclipse console or a terminal emulation: + *

    + *
  • CONSOLE - the terminal is configured with no echo and stderr is + * redirected to a pipe instead of the PTY. This mode is not supported on windows
  • + *
  • TERMINAL - the terminal is configured with echo and stderr is + * connected to the PTY. This mode is best suited for use with a proper terminal emulation. + * Note that this mode might not be supported on all platforms. + * Known platforms which support this mode are: + * linux-x86, linux-x86_64, solaris-sparc, macosx. + *
  • + *
+ *

+ * @param mode the desired mode of operation + * @throws IOException if the PTY could not be created + * @since 5.6 + */ + public PTY(Mode mode) throws IOException { + this(mode == Mode.CONSOLE); } /** @@ -63,7 +120,7 @@ public class PTY { * Eclipse console: *
    *
  • If true the terminal is configured with no echo and stderr is - * redirected to a pipe instead of the PTY.
  • + * redirected to a pipe instead of the PTY. This mode is not supported on windows *
  • If false the terminal is configured with echo and stderr is * connected to the PTY. This mode is best suited for use with a proper terminal emulation. * Note that this mode might not be supported on all platforms. @@ -75,14 +132,16 @@ public class PTY { * * @param console whether terminal is used with Eclipse console * @throws IOException if the PTY could not be created + * @deprecated Use {@link #PTY(Mode)} instead * @since 5.2 */ + @Deprecated public PTY(boolean console) throws IOException { this.console = console; - - if (hasPTY) { - slave= openMaster(console); + if (console && !isConsoleModeSupported) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.cannotCreatePty")); //$NON-NLS-1$ } + slave= hasPTY ? openMaster(console) : null; if (slave == null) { throw new IOException(CCorePlugin.getResourceString("Util.exception.cannotCreatePty")); //$NON-NLS-1$ @@ -91,7 +150,20 @@ public class PTY { in = new PTYInputStream(new MasterFD()); out = new PTYOutputStream(new MasterFD()); } - + + /** + * Test whether the slave name can be used as a tty device by external processes (e.g. gdb). + * If the slave name is not valid an IOException is thrown. + * @throws IOException if the slave name is not valid + * @since 5.6 + */ + public void validateSlaveName() throws IOException { + // on windows the slave name is just an internal identifier + // and does not represent a real device + if (isWinPTY) + throw new IOException("Slave name is not valid"); //$NON-NLS-1$ + } + public String getSlaveName() { return slave; } @@ -144,27 +216,58 @@ public class PTY { } /** - * @return whether PTY support is available on this platform + * @noreference This method is not intended to be referenced by clients. + * @since 5.6 */ - public static boolean isSupported() { - return hasPTY; + public int exec_pty(Spawner spawner, String[] cmdarray, String[] envp, String dir, int[] chan) throws IOException { + if (isWinPTY) { + return exec2(cmdarray, envp, dir, chan, slave, master, console); + } else { + return spawner.exec2(cmdarray, envp, dir, chan, slave, master, console); + } + } + + /** + * @noreference This method is not intended to be referenced by clients. + * @since 5.6 + */ + public int waitFor(Spawner spawner, int pid) { + if (isWinPTY) { + return waitFor(master, pid); + } else { + return spawner.waitFor(pid); + } } native String openMaster(boolean console); native int change_window_size(int fdm, int width, int height); + /** + * Native method when executing with a terminal emulation (winpty only). + */ + native int exec2(String[] cmdarray, String[] envp, String dir, int[] chan, String slaveName, int masterFD, boolean console) throws IOException; + + /** + * Native method to wait for process to terminate (winpty only). + */ + native int waitFor(int masterFD, int processID); + static { try { System.loadLibrary("pty"); //$NON-NLS-1$ hasPTY = true; + isWinPTY = Platform.OS_WIN32.equals(Platform.getOS()); + // on windows console mode is not supported except for experimental use + // to enable it, set system property org.eclipse.cdt.core.winpty_console_mode=true + isConsoleModeSupported = !isWinPTY || Boolean.getBoolean("org.eclipse.cdt.core.winpty_console_mode"); //$NON-NLS-1$ } catch (SecurityException e) { // Comment out it worries the users too much //CCorePlugin.log(e); } catch (UnsatisfiedLinkError e) { // Comment out it worries the users too much //CCorePlugin.log(e); - } + } } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java index ad07b7ead4c..c8f66f41118 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java @@ -348,7 +348,7 @@ public class Spawner extends Process { } } - private void exec_pty(String[] cmdarray, String[] envp, String dirpath, PTY pty) throws IOException { + private void exec_pty(String[] cmdarray, String[] envp, String dirpath, final PTY pty) throws IOException { String command = cmdarray[0]; SecurityManager s = System.getSecurityManager(); if (s != null) @@ -356,17 +356,15 @@ public class Spawner extends Process { if (envp == null) envp = new String[0]; - final String slaveName = pty.getSlaveName(); - final int masterFD = pty.getMasterFD().getFD(); - final boolean console = pty.isConsole(); - //int fdm = pty.get Reaper reaper = new Reaper(cmdarray, envp, dirpath) { - /* (non-Javadoc) - * @see org.eclipse.cdt.utils.spawner.Spawner.Reaper#execute(java.lang.String[], java.lang.String[], java.lang.String, int[]) - */ @Override int execute(String[] cmd, String[] env, String dir, int[] channels) throws IOException { - return exec2(cmd, env, dir, channels, slaveName, masterFD, console); + return pty.exec_pty(Spawner.this, cmd, env, dir, channels); + } + + @Override + protected int waitFor(int pid) { + return pty.waitFor(Spawner.this, pid); } }; reaper.setDaemon(true); @@ -432,18 +430,20 @@ public class Spawner extends Process { /** * Native method when executing with a terminal emulation. + * @noreference This method is not intended to be referenced by clients. */ - native int exec2( String[] cmdarray, String[] envp, String dir, int[] chan, String slaveName, int masterFD, boolean console) throws IOException; + public native int exec2( String[] cmdarray, String[] envp, String dir, int[] chan, String slaveName, int masterFD, boolean console) throws IOException; /** * Native method to drop a signal on the process with pid. */ public native int raise(int processID, int sig); - /* + /** * Native method to wait(3) for process to terminate. + * @noreference This method is not intended to be referenced by clients. */ - native int waitFor(int processID); + public native int waitFor(int processID); static { try { @@ -477,6 +477,10 @@ public class Spawner extends Process { return exec0(cmdarray, envp, dir, channels); } + int waitFor(int pid) { + return Spawner.this.waitFor(pid); + } + @Override public void run() { try { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java index a15d872cac6..78247d42394 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java @@ -45,6 +45,9 @@ class SpawnerInputStream extends InputStream { */ @Override public int read(byte[] buf, int off, int len) throws IOException { + if (fd == -1) { + return -1; + } if (buf == null) { throw new NullPointerException(); } else if ( @@ -85,6 +88,9 @@ class SpawnerInputStream extends InputStream { @Override public int available() throws IOException { + if (fd == -1) { + return 0; + } try { return available0(fd); } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIPlugin.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIPlugin.java index a9cbffc7dc7..490faa9760e 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIPlugin.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIPlugin.java @@ -160,6 +160,7 @@ public class MIPlugin extends Plugin { try { PTY pseudo = new PTY(); + pseudo.validateSlaveName(); pty = new MITTYAdapter(pseudo); } catch (IOException e) { // Should we not print/log this ? @@ -436,6 +437,7 @@ public class MIPlugin extends Plugin { if (usePty) { try { PTY pseudo = new PTY(); + pseudo.validateSlaveName(); pty = new MITTYAdapter(pseudo); } catch (IOException e) { // Should we not print/log this ? diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java index b0c63d0ab41..ffa1d165f6a 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java @@ -507,6 +507,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses { // These types always use a PTY try { fPty = new PTY(); + fPty.validateSlaveName(); // Tell GDB to use this PTY fGdb.queueCommand( diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java index e88e9b6b3ca..436d32262e4 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/StartOrRestartProcessSequence_7_0.java @@ -270,6 +270,7 @@ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence { // and requires a pty for it. try { fPty = new PTY(); + fPty.validateSlaveName(); // Tell GDB to use this PTY fCommandControl.queueCommand(