mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Merge 70e486ff0d
into 7f86b4a76c
This commit is contained in:
commit
707b40f55f
8 changed files with 13 additions and 587 deletions
|
@ -126,14 +126,6 @@ $(OS_DIR_WIN32_X86_64)/spawner.dll: win/iostream.c win/raise.c win/spawner.c win
|
|||
$^ \
|
||||
-Wl,--kill-at --shared
|
||||
|
||||
$(OS_DIR_WIN32_X86_64)/pty.dll: win/pty.cpp win/pty_dllmain.cpp win/util.c
|
||||
mkdir -p $(dir $@) && \
|
||||
$(REPRODUCIBLE_BUILD_WRAPPER) \
|
||||
x86_64-w64-mingw32-g++ $(COMMON_CCFLAGS) -o $@ -Iinclude -Iwin/include -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" \
|
||||
-DUNICODE \
|
||||
$^ \
|
||||
-Wl,--kill-at --shared -L$(OS_DIR_WIN32_X86_64) -lwinpty -static-libstdc++ -static-libgcc
|
||||
|
||||
# Windows aarch64
|
||||
$(OS_DIR_WIN32_AARCH64)/starter.exe: win/starter.c win/util.c
|
||||
mkdir -p $(dir $@) && \
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012 Ryan Prichard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WINPTY_H
|
||||
#define WINPTY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef WINPTY
|
||||
#define WINPTY_API __declspec(dllexport)
|
||||
#else
|
||||
#define WINPTY_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct winpty_s winpty_t;
|
||||
|
||||
/*
|
||||
* winpty API.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Starts a new winpty instance with the given size.
|
||||
*
|
||||
* This function creates a new agent process and connects to it.
|
||||
*/
|
||||
WINPTY_API winpty_t *winpty_open(int cols, int rows);
|
||||
|
||||
/*
|
||||
* Start a child process. Either (but not both) of appname and cmdline may
|
||||
* be NULL. cwd and env may be NULL. env is a pointer to an environment
|
||||
* block like that passed to CreateProcess.
|
||||
*
|
||||
* This function never modifies the cmdline, unlike CreateProcess.
|
||||
*
|
||||
* Only one child process may be started. After the child process exits, the
|
||||
* agent will scrape the console output one last time, then close the data pipe
|
||||
* once all remaining data has been sent.
|
||||
*
|
||||
* Returns 0 on success or a Win32 error code on failure.
|
||||
*/
|
||||
WINPTY_API int winpty_start_process(winpty_t *pc, const wchar_t *appname, const wchar_t *cmdline, const wchar_t *cwd,
|
||||
const wchar_t *env);
|
||||
|
||||
/*
|
||||
* Returns the exit code of the process started with winpty_start_process,
|
||||
* or -1 none is available.
|
||||
*/
|
||||
WINPTY_API int winpty_get_exit_code(winpty_t *pc);
|
||||
|
||||
/*
|
||||
* Returns the process id of the process started with winpty_start_process,
|
||||
* or -1 none is available.
|
||||
*/
|
||||
WINPTY_API int winpty_get_process_id(winpty_t *pc);
|
||||
|
||||
/*
|
||||
* Returns an overlapped-mode pipe handle that can be read and written
|
||||
* like a Unix terminal.
|
||||
*/
|
||||
WINPTY_API HANDLE winpty_get_data_pipe(winpty_t *pc);
|
||||
|
||||
/*
|
||||
* Change the size of the Windows console.
|
||||
*/
|
||||
WINPTY_API int winpty_set_size(winpty_t *pc, int cols, int rows);
|
||||
|
||||
/*
|
||||
* Toggle the console mode. If in console mode, no terminal escape sequences are send.
|
||||
*/
|
||||
WINPTY_API int winpty_set_console_mode(winpty_t *pc, int mode);
|
||||
|
||||
/*
|
||||
* Closes the winpty.
|
||||
*/
|
||||
WINPTY_API void winpty_close(winpty_t *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WINPTY_H */
|
|
@ -1,382 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013, 2016 Wind River Systems, Inc. and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
#include "org_eclipse_cdt_utils_pty_PTY.h"
|
||||
#include "org_eclipse_cdt_utils_pty_PTYInputStream.h"
|
||||
#include "org_eclipse_cdt_utils_pty_PTYOutputStream.h"
|
||||
#include "winpty.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <ctime>
|
||||
|
||||
static std::map<int, winpty_t *> fd2pty;
|
||||
static std::map<int, int> fd2rc;
|
||||
|
||||
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) {
|
||||
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();
|
||||
|
||||
/* Make sure masterFD does not exist */
|
||||
while (fd2pty.find(master) != fd2pty.end()) {
|
||||
master++;
|
||||
}
|
||||
|
||||
sprintf(line, "winpty_%i", master);
|
||||
|
||||
/* Remember the winpty handle for the generated masterFD */
|
||||
fd2pty.insert(std::pair<int, winpty_t *>(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) {
|
||||
return NULL;
|
||||
}
|
||||
env->SetIntField(jobj, fid, (jint)master);
|
||||
|
||||
/* Create a new String for the slave. */
|
||||
jstr = env->NewStringUTF(line);
|
||||
|
||||
return jstr;
|
||||
}
|
||||
|
||||
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<int, winpty_t *>::const_iterator fd2pty_Iter;
|
||||
|
||||
fd = fdm;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
if (winpty) {
|
||||
return winpty_set_size(winpty, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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<int, winpty_t *>::const_iterator fd2pty_Iter;
|
||||
|
||||
fd = jfd;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
if (winpty) {
|
||||
/* 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 && fd2pty.find(fd) != fd2pty.end()) {
|
||||
int rc = winpty_get_exit_code(winpty);
|
||||
fd2rc.insert(std::pair<int, int>(fd, rc));
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
env->ReleaseByteArrayElements(buf, data, 0);
|
||||
ResetEvent(over.hEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0(JNIEnv *env, jobject jobj, jint jfd) {
|
||||
int fd;
|
||||
std::map<int, winpty_t *>::iterator fd2pty_Iter;
|
||||
|
||||
fd = jfd;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
fd2pty.erase(fd2pty_Iter);
|
||||
if (winpty) {
|
||||
winpty_close(winpty);
|
||||
winpty = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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<int, winpty_t *>::iterator fd2pty_Iter;
|
||||
|
||||
fd = jfd;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
if (winpty) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0(JNIEnv *env, jobject jobj, jint jfd) {
|
||||
int fd;
|
||||
std::map<int, winpty_t *>::iterator fd2pty_Iter;
|
||||
|
||||
fd = jfd;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
fd2pty.erase(fd2pty_Iter);
|
||||
if (winpty) {
|
||||
winpty_close(winpty);
|
||||
winpty = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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<std::wstring> &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' ') || wcschr(arg, L'\t') || *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;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTY_exec2(JNIEnv *env, jobject jobj, jobjectArray jcmd,
|
||||
jobjectArray jenv, jstring jdir, jobjectArray jchannels,
|
||||
jstring jslaveName, jint masterFD, jboolean console) {
|
||||
int fd;
|
||||
std::map<int, winpty_t *>::iterator fd2pty_Iter;
|
||||
|
||||
const wchar_t *cwdW = (const wchar_t *)env->GetStringChars(jdir, NULL);
|
||||
const char *pts_name = env->GetStringUTFChars(jslaveName, NULL);
|
||||
|
||||
int pid = -1;
|
||||
|
||||
jint argc = env->GetArrayLength(jcmd);
|
||||
jint envc = env->GetArrayLength(jenv);
|
||||
|
||||
if (!jchannels || env->GetArrayLength(jchannels) != 3) {
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
fd = masterFD;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
if (winpty) {
|
||||
std::vector<std::wstring> argVector;
|
||||
|
||||
for (int 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 (int 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->ReleaseStringChars(jdir, (const jchar *)cwdW);
|
||||
env->ReleaseStringUTFChars(jslaveName, pts_name);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
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<int, winpty_t *>::iterator fd2pty_Iter;
|
||||
std::map<int, int>::iterator fd2rc_Iter;
|
||||
|
||||
fd = masterFD;
|
||||
fd2pty_Iter = fd2pty.find(fd);
|
||||
if (fd2pty_Iter != fd2pty.end()) {
|
||||
winpty_t *winpty = fd2pty_Iter->second;
|
||||
if (winpty) {
|
||||
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;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include <windows.h>
|
||||
#include <delayimp.h>
|
||||
#include <assert.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -28,12 +28,6 @@ import org.eclipse.core.runtime.Platform;
|
|||
*/
|
||||
public class PTY {
|
||||
|
||||
/**
|
||||
* Java property key that can be set to false disable ConPTY.
|
||||
*
|
||||
* Defaults to True.
|
||||
*/
|
||||
private static final String CONPTY_ENABLED_PROP = "org.eclipse.cdt.core.conpty_enabled"; //$NON-NLS-1$
|
||||
/**
|
||||
* Java property key that can be set to true to force console mode
|
||||
* to be allowed on Windows.
|
||||
|
@ -79,10 +73,6 @@ public class PTY {
|
|||
* On newer Windows 10 and later, use ConPTY API to connected a console.
|
||||
*/
|
||||
PTY_CONPTY,
|
||||
/**
|
||||
* On Windows, as a fallback use WinPTY.
|
||||
*/
|
||||
PTY_WINPTY,
|
||||
/**
|
||||
* On Linux/macOS PTY operations just work and no special API is needed.
|
||||
*/
|
||||
|
@ -191,7 +181,7 @@ public class PTY {
|
|||
}
|
||||
|
||||
inInit = new PTYInputStream(new MasterFD());
|
||||
outInit = new PTYOutputStream(new MasterFD(), ptyType != PTY_TYPE.PTY_WINPTY);
|
||||
outInit = new PTYOutputStream(new MasterFD(), true);
|
||||
}
|
||||
slave = slaveInit;
|
||||
in = inInit;
|
||||
|
@ -207,7 +197,7 @@ public class PTY {
|
|||
public void validateSlaveName() throws IOException {
|
||||
// on windows the slave name is just an internal identifier
|
||||
// and does not represent a real device
|
||||
if (ptyType == PTY_TYPE.PTY_CONPTY || ptyType == PTY_TYPE.PTY_WINPTY) {
|
||||
if (ptyType == PTY_TYPE.PTY_CONPTY) {
|
||||
throw new IOException("Slave name is not valid"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
@ -276,8 +266,6 @@ public class PTY {
|
|||
throws IOException {
|
||||
if (ptyType == PTY_TYPE.PTY_CONPTY) {
|
||||
return conPTY.exec(cmdarray, envp, dir);
|
||||
} else if (ptyType == PTY_TYPE.PTY_WINPTY) {
|
||||
return exec2(cmdarray, envp, dir, chan, slave, master, isConsole());
|
||||
} else {
|
||||
return spawner.exec2(cmdarray, envp, dir, chan, slave, master, isConsole());
|
||||
}
|
||||
|
@ -290,8 +278,6 @@ public class PTY {
|
|||
public int waitFor(Spawner spawner, int pid) {
|
||||
if (ptyType == PTY_TYPE.PTY_CONPTY) {
|
||||
return conPTY.waitFor();
|
||||
} else if (ptyType == PTY_TYPE.PTY_WINPTY) {
|
||||
return waitFor(master, pid);
|
||||
} else {
|
||||
return spawner.waitFor(pid);
|
||||
}
|
||||
|
@ -314,34 +300,16 @@ public class PTY {
|
|||
|
||||
static {
|
||||
if (Platform.OS_WIN32.equals(Platform.getOS())) {
|
||||
boolean conPtyEnabled = Boolean.parseBoolean(System.getProperty(CONPTY_ENABLED_PROP, "true")); //$NON-NLS-1$
|
||||
if (conPtyEnabled) {
|
||||
try {
|
||||
// Try creating and closing a ConPTY to see if the API is available.
|
||||
ConPTY pty = new ConPTY();
|
||||
pty.close();
|
||||
ptyType = PTY_TYPE.PTY_CONPTY;
|
||||
isConsoleModeSupported = Boolean.getBoolean(FORCE_CONSOLE_MODE_ENABLED_PROP);
|
||||
|
||||
} catch (NoClassDefFoundError e) {
|
||||
CNativePlugin.log(Messages.PTY_NoClassDefFoundError, e);
|
||||
} catch (Throwable e) {
|
||||
CNativePlugin.log(Messages.PTY_FailedToStartConPTY, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (ptyType == PTY_TYPE.PTY_UNKNOWN) {
|
||||
try {
|
||||
// When we used to build with VC++ we used DelayLoadDLLs (See Gerrit 167674 and Bug 521515) so that the winpty
|
||||
// could be found. When we ported to mingw we didn't port across this feature because it was simpler to just
|
||||
// manually load winpty first.
|
||||
System.loadLibrary("winpty"); //$NON-NLS-1$
|
||||
System.loadLibrary("pty"); //$NON-NLS-1$
|
||||
ptyType = PTY_TYPE.PTY_WINPTY;
|
||||
isConsoleModeSupported = Boolean.getBoolean(FORCE_CONSOLE_MODE_ENABLED_PROP);
|
||||
} catch (Throwable e) {
|
||||
CNativePlugin.log(Messages.PTY_FailedToStartWinPTY, e);
|
||||
}
|
||||
try {
|
||||
// Try creating and closing a ConPTY to see if the API is available.
|
||||
ConPTY pty = new ConPTY();
|
||||
pty.close();
|
||||
ptyType = PTY_TYPE.PTY_CONPTY;
|
||||
isConsoleModeSupported = Boolean.getBoolean(FORCE_CONSOLE_MODE_ENABLED_PROP);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
CNativePlugin.log(Messages.PTY_NoClassDefFoundError, e);
|
||||
} catch (Throwable e) {
|
||||
CNativePlugin.log(Messages.PTY_FailedToStartConPTY, e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
|
@ -355,7 +323,7 @@ public class PTY {
|
|||
|
||||
if (ptyType == PTY_TYPE.PTY_UNKNOWN) {
|
||||
ptyType = PTY_TYPE.PTY_BROKEN;
|
||||
isConsoleModeSupported = true;
|
||||
isConsoleModeSupported = false;
|
||||
CNativePlugin.log(Messages.PTY_FailedToStartPTY);
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue