From 5355cee77d7b3b62917036281406726832b6d7dc Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 9 Nov 2019 15:46:12 +0900 Subject: Change to use ConPTY, if available --- src/nvim/CMakeLists.txt | 4 + src/nvim/channel.c | 33 +++++++- src/nvim/main.c | 6 ++ src/nvim/option.c | 13 +++ src/nvim/option_defs.h | 1 + src/nvim/options.lua | 7 ++ src/nvim/os/os_win_conpty.c | 181 ++++++++++++++++++++++++++++++++++++++++++ src/nvim/os/os_win_conpty.h | 22 +++++ src/nvim/os/pty_process_win.c | 146 ++++++++++++++++++++++------------ src/nvim/os/pty_process_win.h | 15 +++- 10 files changed, 375 insertions(+), 53 deletions(-) create mode 100644 src/nvim/os/os_win_conpty.c create mode 100644 src/nvim/os/os_win_conpty.h (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index bc8e64dd41..1d4a01fa04 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -134,6 +134,9 @@ foreach(sfile ${NVIM_SOURCES}) if(NOT WIN32 AND ${f} MATCHES "^(pty_process_win.c)$") list(APPEND to_remove ${sfile}) endif() + if(NOT WIN32 AND ${f} MATCHES "^(os_win_conpty.c)$") + list(APPEND to_remove ${sfile}) + endif() endforeach() list(REMOVE_ITEM NVIM_SOURCES ${to_remove}) @@ -637,6 +640,7 @@ endfunction() set(NO_SINGLE_CHECK_HEADERS os/win_defs.h os/pty_process_win.h + os/os_win_conpty.h ) foreach(hfile ${NVIM_HEADERS}) get_test_target(test-includes "${hfile}" relative_path texe) diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 2bb568f025..b9ea36d397 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -11,6 +11,9 @@ #include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/server.h" #include "nvim/os/shell.h" +#ifdef WIN32 +# include "nvim/os/os_win_conpty.h" +#endif #include "nvim/path.h" #include "nvim/ascii.h" @@ -469,8 +472,34 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, Channel *channel = channel_alloc(kChannelStreamStdio); - rstream_init_fd(&main_loop, &channel->stream.stdio.in, 0, 0); - wstream_init_fd(&main_loop, &channel->stream.stdio.out, 1, 0); + int stdin_dup_fd = STDIN_FILENO; + int stdout_dup_fd = STDOUT_FILENO; +#ifdef WIN32 + // Strangely, ConPTY doesn't work if stdin and stdout are pipes. So replace + // stdin and stdout with CONIN$ and CONOUT$, respectively. + if (embedded_mode && os_has_conpty_working()) { + stdin_dup_fd = os_dup(STDIN_FILENO); + close(STDIN_FILENO); + const HANDLE conin_handle = + CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, 0, (HANDLE)NULL); + assert(conin_handle != INVALID_HANDLE_VALUE); + const int conin_fd = _open_osfhandle((intptr_t)conin_handle, _O_RDONLY); + assert(conin_fd == STDIN_FILENO); + stdout_dup_fd = os_dup(STDOUT_FILENO); + close(STDOUT_FILENO); + const HANDLE conout_handle = + CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, 0, (HANDLE)NULL); + assert(conout_handle != INVALID_HANDLE_VALUE); + const int conout_fd = _open_osfhandle((intptr_t)conout_handle, 0); + assert(conout_fd == STDOUT_FILENO); + } +#endif + rstream_init_fd(&main_loop, &channel->stream.stdio.in, stdin_dup_fd, 0); + wstream_init_fd(&main_loop, &channel->stream.stdio.out, stdout_dup_fd, 0); if (rpc) { rpc_start(channel); diff --git a/src/nvim/main.c b/src/nvim/main.c index c7011f4f4e..33c0466e1a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -46,6 +46,9 @@ #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/os/os_defs.h" +#ifdef WIN32 +# include "nvim/os/os_win_conpty.h" +#endif #include "nvim/path.h" #include "nvim/profile.h" #include "nvim/popupmnu.h" @@ -226,6 +229,9 @@ void early_init(void) init_signs(); ui_comp_syn_init(); +#ifdef WIN32 + os_dyn_conpty_init(); +#endif } #ifdef MAKE_LIB diff --git a/src/nvim/option.c b/src/nvim/option.c index 9d3e02949e..591c8234c3 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -76,6 +76,9 @@ #include "nvim/undo.h" #include "nvim/window.h" #include "nvim/os/os.h" +#ifdef WIN32 +# include "nvim/os/os_win_conpty.h" +#endif #include "nvim/api/private/helpers.h" #include "nvim/os/input.h" #include "nvim/os/lang.h" @@ -310,6 +313,9 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2", "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8", "yes:9", NULL }; +#ifdef WIN32 +static char *(p_twt_values[]) = { "conpty", "winpty", "", NULL }; +#endif /// All possible flags for 'shm'. static char_u SHM_ALL[] = { @@ -3282,6 +3288,13 @@ ambw_end: if (!parse_winhl_opt(curwin)) { errmsg = e_invarg; } +#ifdef WIN32 + } else if (varp == &p_twt) { + if (check_opt_strings(*varp, p_twt_values, false) != OK + || (!os_has_conpty_working() && STRCMP(*varp, "conpty") == 0)) { + errmsg = e_invarg; + } +#endif } else { // Options that are a list of flags. p = NULL; diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index fcad6836bf..1d4c31dc1c 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -654,6 +654,7 @@ EXTERN char_u *p_titleold; ///< 'titleold' EXTERN char_u *p_titlestring; ///< 'titlestring' EXTERN char_u *p_tsr; ///< 'thesaurus' EXTERN int p_tgc; ///< 'termguicolors' +EXTERN char_u *p_twt; ///< 'termwintype' EXTERN int p_ttimeout; ///< 'ttimeout' EXTERN long p_ttm; ///< 'ttimeoutlen' EXTERN char_u *p_udir; ///< 'undodir' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index a5a14a1a25..fe970ccba3 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2496,6 +2496,13 @@ return { varname='p_tgc', defaults={if_true={vi=false}} }, + { + full_name='termwintype', abbreviation='twt', + type='string', scope={'global'}, + vi_def=false, + varname='p_twt', + defaults={if_true={vi="",vim=""}} + }, { full_name='terse', type='bool', scope={'global'}, diff --git a/src/nvim/os/os_win_conpty.c b/src/nvim/os/os_win_conpty.c new file mode 100644 index 0000000000..9c6b7ad40f --- /dev/null +++ b/src/nvim/os/os_win_conpty.c @@ -0,0 +1,181 @@ +#include + +#include "nvim/vim.h" +#include "nvim/os/os.h" +#include "nvim/os/os_win_conpty.h" + +#ifndef EXTENDED_STARTUPINFO_PRESENT +# define EXTENDED_STARTUPINFO_PRESENT 0x00080000 +#endif +#ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE +# define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016 +#endif + +static bool conpty_working = false; + +HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON *); +HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); +HRESULT (WINAPI *pClosePseudoConsole)(HPCON); + +bool os_has_conpty_working(void) +{ + return conpty_working; +} + +void os_dyn_conpty_init(void) +{ + uv_lib_t kernel; + if (uv_dlopen("kernel32.dll", &kernel)) { + uv_dlclose(&kernel); + return; + } + static struct { + char *name; + FARPROC *ptr; + } conpty_entry[] = { + { "CreatePseudoConsole", (FARPROC *)&pCreatePseudoConsole }, + { "ResizePseudoConsole", (FARPROC *)&pResizePseudoConsole }, + { "ClosePseudoConsole", (FARPROC *)&pClosePseudoConsole }, + { NULL, NULL } + }; + for (int i = 0; + conpty_entry[i].name != NULL && conpty_entry[i].ptr != NULL; i++) { + if (uv_dlsym(&kernel, conpty_entry[i].name, (void **)conpty_entry[i].ptr)) { + uv_dlclose(&kernel); + return; + } + } + conpty_working = true; +} + +conpty_t *os_conpty_init(char **in_name, char **out_name, + uint16_t width, uint16_t height) +{ + static int count = 0; + conpty_t *conpty_object = xcalloc(1, sizeof(*conpty_object)); + const char *emsg = NULL; + HANDLE in_read = INVALID_HANDLE_VALUE; + HANDLE out_write = INVALID_HANDLE_VALUE; + char buf[MAXPATHL]; + SECURITY_ATTRIBUTES sa = { 0 }; + const DWORD mode = PIPE_ACCESS_INBOUND + | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; + + sa.nLength = sizeof(sa); + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-in-%d-%d", + os_get_pid(), count); + *in_name = xstrdup(buf); + if ((in_read = CreateNamedPipeA( + *in_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { + emsg = "create input pipe failed"; + goto failed; + } + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-out-%d-%d", + os_get_pid(), count); + *out_name = xstrdup(buf); + if ((out_write = CreateNamedPipeA( + *out_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { + emsg = "create output pipe failed"; + goto failed; + } + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + HRESULT hr; + hr = pCreatePseudoConsole(size, in_read, out_write, 0, &conpty_object->pty); + if (FAILED(hr)) { + emsg = "create psudo console failed"; + goto failed; + } + + conpty_object->si_ex.StartupInfo.cb = sizeof(conpty_object->si_ex); + size_t bytes_required; + InitializeProcThreadAttributeList(NULL, 1, 0, & bytes_required); + conpty_object->si_ex.lpAttributeList = + (PPROC_THREAD_ATTRIBUTE_LIST)xmalloc(bytes_required); + if (!InitializeProcThreadAttributeList( + conpty_object->si_ex.lpAttributeList, + 1, + 0, + &bytes_required)) { + emsg = "InitializeProcThreadAttributeList failed"; + goto failed; + } + if (!UpdateProcThreadAttribute( + conpty_object->si_ex.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + conpty_object->pty, + sizeof(conpty_object->pty), + NULL, + NULL)) { + emsg = "UpdateProcThreadAttribute failed"; + goto failed; + } + count++; + goto finished; + +failed: + ELOG("os_conpty_init:%s : error code: %d", + emsg, os_translate_sys_error((int)GetLastError())); + os_conpty_free(conpty_object); + conpty_object = NULL; +finished: + if (in_read != INVALID_HANDLE_VALUE) { + CloseHandle(in_read); + } + if (out_write != INVALID_HANDLE_VALUE) { + CloseHandle(out_write); + } + return conpty_object; +} + +bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, + wchar_t *name, wchar_t *cmd_line, wchar_t *cwd, + wchar_t *env) +{ + PROCESS_INFORMATION pi = { 0 }; + if (!CreateProcessW( + name, + cmd_line, + NULL, + NULL, + false, + EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, + env, + cwd, + &conpty_object->si_ex.StartupInfo, + &pi)) { + return false; + } + *process_handle = pi.hProcess; + return true; +} + +void os_conpty_free(conpty_t * conpty_object) +{ + if (conpty_object != NULL) { + if (conpty_object->si_ex.lpAttributeList != NULL) { + DeleteProcThreadAttributeList(conpty_object->si_ex.lpAttributeList); + xfree(conpty_object->si_ex.lpAttributeList); + } + if (conpty_object->pty != NULL) { + pClosePseudoConsole(conpty_object->pty); + } + } + xfree(conpty_object); +} diff --git a/src/nvim/os/os_win_conpty.h b/src/nvim/os/os_win_conpty.h new file mode 100644 index 0000000000..8e34d394a5 --- /dev/null +++ b/src/nvim/os/os_win_conpty.h @@ -0,0 +1,22 @@ +#ifndef NVIM_OS_OS_WIN_CONPTY_H +#define NVIM_OS_OS_WIN_CONPTY_H + +#ifndef HPCON +# define HPCON VOID * +#endif + +extern HRESULT (WINAPI *pCreatePseudoConsole) // NOLINT(whitespace/parens) + (COORD, HANDLE, HANDLE, DWORD, HPCON *); +extern HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); +extern HRESULT (WINAPI *pClosePseudoConsole)(HPCON); + +typedef struct conpty { + HPCON pty; + STARTUPINFOEXW si_ex; +} conpty_t; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/os_win_conpty.h.generated.h" +#endif + +#endif // NVIM_OS_OS_WIN_CONPTY_H diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 183219bd3e..f48fef76d3 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -12,6 +12,7 @@ #include "nvim/memory.h" #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 #include "nvim/os/pty_process_win.h" +#include "nvim/os/os_win_conpty.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_win.c.generated.h" @@ -23,6 +24,11 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) PtyProcess *ptyproc = (PtyProcess *)context; Process *proc = (Process *)ptyproc; + if (ptyproc->type == PTY_TYPE_CONPTY + && ptyproc->pty_object.conpty_object != NULL) { + os_conpty_free(ptyproc->pty_object.conpty_object); + ptyproc->pty_object.conpty_object = NULL; + } uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); ptyproc->wait_eof_timer.data = (void *)ptyproc; uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); @@ -38,6 +44,7 @@ int pty_process_spawn(PtyProcess *ptyproc) winpty_config_t *cfg = NULL; winpty_spawn_config_t *spawncfg = NULL; winpty_t *winpty_object = NULL; + conpty_t *conpty_object = NULL; char *in_name = NULL; char *out_name = NULL; HANDLE process_handle = NULL; @@ -49,29 +56,40 @@ int pty_process_spawn(PtyProcess *ptyproc) assert(proc->err.closed); - cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err); - if (cfg == NULL) { - emsg = "winpty_config_new failed"; - goto cleanup; + int pty_type = *p_twt; + if (pty_type == 'c' && os_has_conpty_working()) { + if ((conpty_object = + os_conpty_init(&in_name, &out_name, + ptyproc->width, ptyproc->height)) != NULL) { + ptyproc->type = PTY_TYPE_CONPTY; + } } - winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height); - winpty_object = winpty_open(cfg, &err); - if (winpty_object == NULL) { - emsg = "winpty_open failed"; - goto cleanup; - } + if (ptyproc->type == PTY_TYPE_WINPTY) { + cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err); + if (cfg == NULL) { + emsg = "winpty_config_new failed"; + goto cleanup; + } - status = utf16_to_utf8(winpty_conin_name(winpty_object), -1, &in_name); - if (status != 0) { - emsg = "utf16_to_utf8(winpty_conin_name) failed"; - goto cleanup; - } + winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height); + winpty_object = winpty_open(cfg, &err); + if (winpty_object == NULL) { + emsg = "winpty_open failed"; + goto cleanup; + } - status = utf16_to_utf8(winpty_conout_name(winpty_object), -1, &out_name); - if (status != 0) { - emsg = "utf16_to_utf8(winpty_conout_name) failed"; - goto cleanup; + status = utf16_to_utf8(winpty_conin_name(winpty_object), -1, &in_name); + if (status != 0) { + emsg = "utf16_to_utf8(winpty_conin_name) failed"; + goto cleanup; + } + + status = utf16_to_utf8(winpty_conout_name(winpty_object), -1, &out_name); + if (status != 0) { + emsg = "utf16_to_utf8(winpty_conout_name) failed"; + goto cleanup; + } } if (!proc->in.closed) { @@ -107,32 +125,45 @@ int pty_process_spawn(PtyProcess *ptyproc) goto cleanup; } - spawncfg = winpty_spawn_config_new( - WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, - NULL, // Optional application name - cmd_line, - cwd, - NULL, // Optional environment variables - &err); - if (spawncfg == NULL) { - emsg = "winpty_spawn_config_new failed"; - goto cleanup; - } + if (ptyproc->type == PTY_TYPE_CONPTY) { + if (!os_conpty_spawn(conpty_object, + &process_handle, + NULL, + cmd_line, + cwd, + NULL)) { + emsg = "os_conpty_spawn failed"; + status = (int)GetLastError(); + goto cleanup; + } + } else { + spawncfg = winpty_spawn_config_new( + WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, + NULL, // Optional application name + cmd_line, + cwd, + NULL, // Optional environment variables + &err); + if (spawncfg == NULL) { + emsg = "winpty_spawn_config_new failed"; + goto cleanup; + } - DWORD win_err = 0; - if (!winpty_spawn(winpty_object, - spawncfg, - &process_handle, - NULL, // Optional thread handle - &win_err, - &err)) { - if (win_err) { - status = (int)win_err; - emsg = "failed to spawn process"; - } else { - emsg = "winpty_spawn failed"; + DWORD win_err = 0; + if (!winpty_spawn(winpty_object, + spawncfg, + &process_handle, + NULL, // Optional thread handle + &win_err, + &err)) { + if (win_err) { + status = (int)win_err; + emsg = "failed to spawn process"; + } else { + emsg = "winpty_spawn failed"; + } + goto cleanup; } - goto cleanup; } proc->pid = (int)GetProcessId(process_handle); @@ -152,9 +183,14 @@ int pty_process_spawn(PtyProcess *ptyproc) uv_run(&proc->loop->uv, UV_RUN_ONCE); } - ptyproc->winpty_object = winpty_object; + if (ptyproc->type == PTY_TYPE_CONPTY) { + ptyproc->pty_object.conpty_object = conpty_object; + } else { + ptyproc->pty_object.winpty_object = winpty_object; + } ptyproc->process_handle = process_handle; winpty_object = NULL; + conpty_object = NULL; process_handle = NULL; cleanup: @@ -171,6 +207,7 @@ cleanup: winpty_config_free(cfg); winpty_spawn_config_free(spawncfg); winpty_free(winpty_object); + os_conpty_free(conpty_object); xfree(in_name); xfree(out_name); if (process_handle != NULL) { @@ -192,8 +229,18 @@ void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) FUNC_ATTR_NONNULL_ALL { - if (ptyproc->winpty_object != NULL) { - winpty_set_size(ptyproc->winpty_object, width, height, NULL); + if (ptyproc->type == PTY_TYPE_CONPTY + && ptyproc->pty_object.conpty_object != NULL) { + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + if (pResizePseudoConsole( + ptyproc->pty_object.conpty_object->pty, size) != S_OK) { + ELOG("ResizePseudoConsoel failed: error code: %d", + os_translate_sys_error((int)GetLastError())); + } + } else if (ptyproc->pty_object.winpty_object != NULL) { + winpty_set_size(ptyproc->pty_object.winpty_object, width, height, NULL); } } @@ -212,9 +259,10 @@ void pty_process_close(PtyProcess *ptyproc) void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { - if (ptyproc->winpty_object != NULL) { - winpty_free(ptyproc->winpty_object); - ptyproc->winpty_object = NULL; + if (ptyproc->type == PTY_TYPE_WINPTY + && ptyproc->pty_object.winpty_object != NULL) { + winpty_free(ptyproc->pty_object.winpty_object); + ptyproc->pty_object.winpty_object = NULL; } } diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h index 1a4019e654..49a0d420ad 100644 --- a/src/nvim/os/pty_process_win.h +++ b/src/nvim/os/pty_process_win.h @@ -6,12 +6,22 @@ #include "nvim/event/process.h" #include "nvim/lib/queue.h" +#include "nvim/os/os_win_conpty.h" + +typedef enum { + PTY_TYPE_WINPTY, + PTY_TYPE_CONPTY +} pty_type_t; typedef struct pty_process { Process process; char *term_name; uint16_t width, height; - winpty_t *winpty_object; + union { + winpty_t *winpty_object; + conpty_t *conpty_object; + } pty_object; + pty_type_t type; HANDLE finish_wait; HANDLE process_handle; uv_timer_t wait_eof_timer; @@ -30,7 +40,8 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data) rv.term_name = NULL; rv.width = 80; rv.height = 24; - rv.winpty_object = NULL; + rv.pty_object.winpty_object = NULL; + rv.type = PTY_TYPE_WINPTY; rv.finish_wait = NULL; rv.process_handle = NULL; return rv; -- cgit From ed37d1081c8adbd33832b4140ba5368fa876bdb8 Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 15 Nov 2019 12:51:41 +0900 Subject: Change union name from pty_object to object Co-Authored-By: Justin M. Keyes --- src/nvim/os/pty_process_win.c | 24 ++++++++++++------------ src/nvim/os/pty_process_win.h | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index f48fef76d3..0fbe3e5fad 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -25,9 +25,9 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) Process *proc = (Process *)ptyproc; if (ptyproc->type == PTY_TYPE_CONPTY - && ptyproc->pty_object.conpty_object != NULL) { - os_conpty_free(ptyproc->pty_object.conpty_object); - ptyproc->pty_object.conpty_object = NULL; + && ptyproc->object.conpty != NULL) { + os_conpty_free(ptyproc->object.conpty); + ptyproc->object.conpty = NULL; } uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); ptyproc->wait_eof_timer.data = (void *)ptyproc; @@ -184,9 +184,9 @@ int pty_process_spawn(PtyProcess *ptyproc) } if (ptyproc->type == PTY_TYPE_CONPTY) { - ptyproc->pty_object.conpty_object = conpty_object; + ptyproc->object.conpty = conpty_object; } else { - ptyproc->pty_object.winpty_object = winpty_object; + ptyproc->object.winpty = winpty_object; } ptyproc->process_handle = process_handle; winpty_object = NULL; @@ -230,17 +230,17 @@ void pty_process_resize(PtyProcess *ptyproc, uint16_t width, FUNC_ATTR_NONNULL_ALL { if (ptyproc->type == PTY_TYPE_CONPTY - && ptyproc->pty_object.conpty_object != NULL) { + && ptyproc->object.conpty != NULL) { assert(width <= SHRT_MAX); assert(height <= SHRT_MAX); COORD size = { (int16_t)width, (int16_t)height }; if (pResizePseudoConsole( - ptyproc->pty_object.conpty_object->pty, size) != S_OK) { + ptyproc->object.conpty->pty, size) != S_OK) { ELOG("ResizePseudoConsoel failed: error code: %d", os_translate_sys_error((int)GetLastError())); } - } else if (ptyproc->pty_object.winpty_object != NULL) { - winpty_set_size(ptyproc->pty_object.winpty_object, width, height, NULL); + } else if (ptyproc->object.winpty != NULL) { + winpty_set_size(ptyproc->object.winpty, width, height, NULL); } } @@ -260,9 +260,9 @@ void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { if (ptyproc->type == PTY_TYPE_WINPTY - && ptyproc->pty_object.winpty_object != NULL) { - winpty_free(ptyproc->pty_object.winpty_object); - ptyproc->pty_object.winpty_object = NULL; + && ptyproc->object.winpty != NULL) { + winpty_free(ptyproc->object.winpty); + ptyproc->object.winpty = NULL; } } diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h index 49a0d420ad..c7eaa23b1b 100644 --- a/src/nvim/os/pty_process_win.h +++ b/src/nvim/os/pty_process_win.h @@ -18,9 +18,9 @@ typedef struct pty_process { char *term_name; uint16_t width, height; union { - winpty_t *winpty_object; - conpty_t *conpty_object; - } pty_object; + winpty_t *winpty; + conpty_t *conpty; + } object; pty_type_t type; HANDLE finish_wait; HANDLE process_handle; @@ -40,7 +40,7 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data) rv.term_name = NULL; rv.width = 80; rv.height = 24; - rv.pty_object.winpty_object = NULL; + rv.object.winpty = NULL; rv.type = PTY_TYPE_WINPTY; rv.finish_wait = NULL; rv.process_handle = NULL; -- cgit From 7aff0340e1f0550ff1c04dc17474d7cb6e57a89b Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 15 Nov 2019 13:03:25 +0900 Subject: Move ConPTY resize to os_win_conpty.c --- src/nvim/os/os_win_conpty.c | 14 +++++++++++++- src/nvim/os/pty_process_win.c | 9 +-------- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/os/os_win_conpty.c b/src/nvim/os/os_win_conpty.c index 9c6b7ad40f..bf6ec62818 100644 --- a/src/nvim/os/os_win_conpty.c +++ b/src/nvim/os/os_win_conpty.c @@ -166,7 +166,19 @@ bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, return true; } -void os_conpty_free(conpty_t * conpty_object) +void os_conpty_set_size(conpty_t *conpty_object, + uint16_t width, uint16_t height) +{ + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { + ELOG("ResizePseudoConsoel failed: error code: %d", + os_translate_sys_error((int)GetLastError())); + } +} + +void os_conpty_free(conpty_t *conpty_object) { if (conpty_object != NULL) { if (conpty_object->si_ex.lpAttributeList != NULL) { diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 0fbe3e5fad..ffdececf94 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -231,14 +231,7 @@ void pty_process_resize(PtyProcess *ptyproc, uint16_t width, { if (ptyproc->type == PTY_TYPE_CONPTY && ptyproc->object.conpty != NULL) { - assert(width <= SHRT_MAX); - assert(height <= SHRT_MAX); - COORD size = { (int16_t)width, (int16_t)height }; - if (pResizePseudoConsole( - ptyproc->object.conpty->pty, size) != S_OK) { - ELOG("ResizePseudoConsoel failed: error code: %d", - os_translate_sys_error((int)GetLastError())); - } + os_conpty_set_size(ptyproc->object.conpty, width, height); } else if (ptyproc->object.winpty != NULL) { winpty_set_size(ptyproc->object.winpty, width, height, NULL); } -- cgit From b4ff583277ce16584f20868cef6697f52bebc7d4 Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 15 Nov 2019 13:12:48 +0900 Subject: Minor changes in reviewer's point --- src/nvim/os/os_win_conpty.c | 3 +++ src/nvim/os/pty_process_win.c | 8 +++----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/os/os_win_conpty.c b/src/nvim/os/os_win_conpty.c index bf6ec62818..887286b59f 100644 --- a/src/nvim/os/os_win_conpty.c +++ b/src/nvim/os/os_win_conpty.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #include #include "nvim/vim.h" diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index ffdececf94..0cd730401a 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -183,11 +183,9 @@ int pty_process_spawn(PtyProcess *ptyproc) uv_run(&proc->loop->uv, UV_RUN_ONCE); } - if (ptyproc->type == PTY_TYPE_CONPTY) { - ptyproc->object.conpty = conpty_object; - } else { - ptyproc->object.winpty = winpty_object; - } + (ptyproc->type == PTY_TYPE_CONPTY) ? + (void *)(ptyproc->object.conpty = conpty_object) : + (void *)(ptyproc->object.winpty = winpty_object); ptyproc->process_handle = process_handle; winpty_object = NULL; conpty_object = NULL; -- cgit From b25e42f7989aa0a071e3132ce992ab9a6251594e Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 15 Nov 2019 14:42:49 +0900 Subject: Fix function prototype --- src/nvim/os/os_win_conpty.c | 2 +- src/nvim/os/os_win_conpty.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/os/os_win_conpty.c b/src/nvim/os/os_win_conpty.c index 887286b59f..a73b1b65a0 100644 --- a/src/nvim/os/os_win_conpty.c +++ b/src/nvim/os/os_win_conpty.c @@ -18,7 +18,7 @@ static bool conpty_working = false; HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON *); HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); -HRESULT (WINAPI *pClosePseudoConsole)(HPCON); +void (WINAPI *pClosePseudoConsole)(HPCON); bool os_has_conpty_working(void) { diff --git a/src/nvim/os/os_win_conpty.h b/src/nvim/os/os_win_conpty.h index 8e34d394a5..8a5f45e2cd 100644 --- a/src/nvim/os/os_win_conpty.h +++ b/src/nvim/os/os_win_conpty.h @@ -8,7 +8,7 @@ extern HRESULT (WINAPI *pCreatePseudoConsole) // NOLINT(whitespace/parens) (COORD, HANDLE, HANDLE, DWORD, HPCON *); extern HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); -extern HRESULT (WINAPI *pClosePseudoConsole)(HPCON); +extern void (WINAPI *pClosePseudoConsole)(HPCON); typedef struct conpty { HPCON pty; -- cgit From 59ae38a9196d596e2fe511eeb216e314bfc3dac7 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 16 Nov 2019 12:59:07 +0900 Subject: Change to use TriState instead of bool Co-Authored-By: Justin M. Keyes --- src/nvim/main.c | 6 ------ src/nvim/os/os_win_conpty.c | 17 ++++++++++------- 2 files changed, 10 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 33c0466e1a..c7011f4f4e 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -46,9 +46,6 @@ #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/os/os_defs.h" -#ifdef WIN32 -# include "nvim/os/os_win_conpty.h" -#endif #include "nvim/path.h" #include "nvim/profile.h" #include "nvim/popupmnu.h" @@ -229,9 +226,6 @@ void early_init(void) init_signs(); ui_comp_syn_init(); -#ifdef WIN32 - os_dyn_conpty_init(); -#endif } #ifdef MAKE_LIB diff --git a/src/nvim/os/os_win_conpty.c b/src/nvim/os/os_win_conpty.c index a73b1b65a0..3d5ba83523 100644 --- a/src/nvim/os/os_win_conpty.c +++ b/src/nvim/os/os_win_conpty.c @@ -14,23 +14,26 @@ # define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016 #endif -static bool conpty_working = false; - HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON *); HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); void (WINAPI *pClosePseudoConsole)(HPCON); bool os_has_conpty_working(void) { - return conpty_working; + static TriState has_conpty = kNone; + if (has_conpty == kNone) { + has_conpty = os_dyn_conpty_init(); + } + + return has_conpty == kTrue; } -void os_dyn_conpty_init(void) +TriState os_dyn_conpty_init(void) { uv_lib_t kernel; if (uv_dlopen("kernel32.dll", &kernel)) { uv_dlclose(&kernel); - return; + return kFalse; } static struct { char *name; @@ -45,10 +48,10 @@ void os_dyn_conpty_init(void) conpty_entry[i].name != NULL && conpty_entry[i].ptr != NULL; i++) { if (uv_dlsym(&kernel, conpty_entry[i].name, (void **)conpty_entry[i].ptr)) { uv_dlclose(&kernel); - return; + return kFalse; } } - conpty_working = true; + return kTrue; } conpty_t *os_conpty_init(char **in_name, char **out_name, -- cgit From 60c7eabb2feeb95f405deca6680bdd59113edcaa Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 16 Nov 2019 13:16:52 +0900 Subject: Change enum to a name that follows naming convention --- src/nvim/os/pty_process_win.c | 14 +++++++------- src/nvim/os/pty_process_win.h | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 0cd730401a..7108d9c049 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -24,7 +24,7 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) PtyProcess *ptyproc = (PtyProcess *)context; Process *proc = (Process *)ptyproc; - if (ptyproc->type == PTY_TYPE_CONPTY + if (ptyproc->type == kConpty && ptyproc->object.conpty != NULL) { os_conpty_free(ptyproc->object.conpty); ptyproc->object.conpty = NULL; @@ -61,11 +61,11 @@ int pty_process_spawn(PtyProcess *ptyproc) if ((conpty_object = os_conpty_init(&in_name, &out_name, ptyproc->width, ptyproc->height)) != NULL) { - ptyproc->type = PTY_TYPE_CONPTY; + ptyproc->type = kConpty; } } - if (ptyproc->type == PTY_TYPE_WINPTY) { + if (ptyproc->type == kWinpty) { cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err); if (cfg == NULL) { emsg = "winpty_config_new failed"; @@ -125,7 +125,7 @@ int pty_process_spawn(PtyProcess *ptyproc) goto cleanup; } - if (ptyproc->type == PTY_TYPE_CONPTY) { + if (ptyproc->type == kConpty) { if (!os_conpty_spawn(conpty_object, &process_handle, NULL, @@ -183,7 +183,7 @@ int pty_process_spawn(PtyProcess *ptyproc) uv_run(&proc->loop->uv, UV_RUN_ONCE); } - (ptyproc->type == PTY_TYPE_CONPTY) ? + (ptyproc->type == kConpty) ? (void *)(ptyproc->object.conpty = conpty_object) : (void *)(ptyproc->object.winpty = winpty_object); ptyproc->process_handle = process_handle; @@ -227,7 +227,7 @@ void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) FUNC_ATTR_NONNULL_ALL { - if (ptyproc->type == PTY_TYPE_CONPTY + if (ptyproc->type == kConpty && ptyproc->object.conpty != NULL) { os_conpty_set_size(ptyproc->object.conpty, width, height); } else if (ptyproc->object.winpty != NULL) { @@ -250,7 +250,7 @@ void pty_process_close(PtyProcess *ptyproc) void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { - if (ptyproc->type == PTY_TYPE_WINPTY + if (ptyproc->type == kWinpty && ptyproc->object.winpty != NULL) { winpty_free(ptyproc->object.winpty); ptyproc->object.winpty = NULL; diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h index c7eaa23b1b..04c8439c6c 100644 --- a/src/nvim/os/pty_process_win.h +++ b/src/nvim/os/pty_process_win.h @@ -9,9 +9,9 @@ #include "nvim/os/os_win_conpty.h" typedef enum { - PTY_TYPE_WINPTY, - PTY_TYPE_CONPTY -} pty_type_t; + kWinpty, + kConpty +} PtyType; typedef struct pty_process { Process process; @@ -21,7 +21,7 @@ typedef struct pty_process { winpty_t *winpty; conpty_t *conpty; } object; - pty_type_t type; + PtyType type; HANDLE finish_wait; HANDLE process_handle; uv_timer_t wait_eof_timer; @@ -41,7 +41,7 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data) rv.width = 80; rv.height = 24; rv.object.winpty = NULL; - rv.type = PTY_TYPE_WINPTY; + rv.type = kWinpty; rv.finish_wait = NULL; rv.process_handle = NULL; return rv; -- cgit From 2c8016c7048051da9afd809b580cf8f2d2c69614 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 16 Nov 2019 13:45:37 +0900 Subject: Add stdin, stdout replacement functions --- src/nvim/CMakeLists.txt | 4 ++++ src/nvim/channel.c | 19 +++---------------- src/nvim/main.c | 11 ++++------- src/nvim/os/os_win_console.c | 38 ++++++++++++++++++++++++++++++++++++++ src/nvim/os/os_win_console.h | 8 ++++++++ src/nvim/tui/input.c | 11 ++++------- 6 files changed, 61 insertions(+), 30 deletions(-) create mode 100644 src/nvim/os/os_win_console.c create mode 100644 src/nvim/os/os_win_console.h (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 1d4a01fa04..62d45ff4a3 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -137,6 +137,9 @@ foreach(sfile ${NVIM_SOURCES}) if(NOT WIN32 AND ${f} MATCHES "^(os_win_conpty.c)$") list(APPEND to_remove ${sfile}) endif() + if(NOT WIN32 AND ${f} MATCHES "^(os_win_console.c)$") + list(APPEND to_remove ${sfile}) + endif() endforeach() list(REMOVE_ITEM NVIM_SOURCES ${to_remove}) @@ -641,6 +644,7 @@ set(NO_SINGLE_CHECK_HEADERS os/win_defs.h os/pty_process_win.h os/os_win_conpty.h + os/os_win_console.h ) foreach(hfile ${NVIM_HEADERS}) get_test_target(test-includes "${hfile}" relative_path texe) diff --git a/src/nvim/channel.c b/src/nvim/channel.c index b9ea36d397..b346845c66 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -13,6 +13,7 @@ #include "nvim/os/shell.h" #ifdef WIN32 # include "nvim/os/os_win_conpty.h" +# include "nvim/os/os_win_console.h" #endif #include "nvim/path.h" #include "nvim/ascii.h" @@ -479,23 +480,9 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, // stdin and stdout with CONIN$ and CONOUT$, respectively. if (embedded_mode && os_has_conpty_working()) { stdin_dup_fd = os_dup(STDIN_FILENO); - close(STDIN_FILENO); - const HANDLE conin_handle = - CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, 0, (HANDLE)NULL); - assert(conin_handle != INVALID_HANDLE_VALUE); - const int conin_fd = _open_osfhandle((intptr_t)conin_handle, _O_RDONLY); - assert(conin_fd == STDIN_FILENO); + os_replace_stdin_to_conin(); stdout_dup_fd = os_dup(STDOUT_FILENO); - close(STDOUT_FILENO); - const HANDLE conout_handle = - CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, 0, (HANDLE)NULL); - assert(conout_handle != INVALID_HANDLE_VALUE); - const int conout_fd = _open_osfhandle((intptr_t)conout_handle, 0); - assert(conout_fd == STDOUT_FILENO); + os_replace_stdout_to_conout(); } #endif rstream_init_fd(&main_loop, &channel->stream.stdio.in, stdin_dup_fd, 0); diff --git a/src/nvim/main.c b/src/nvim/main.c index c7011f4f4e..be279b449a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -64,6 +64,9 @@ #include "nvim/os/os.h" #include "nvim/os/time.h" #include "nvim/os/fileio.h" +#ifdef WIN32 +# include "nvim/os/os_win_console.h" +#endif #include "nvim/event/loop.h" #include "nvim/os/signal.h" #include "nvim/event/process.h" @@ -1120,13 +1123,7 @@ scripterror: const int stdin_dup_fd = os_dup(STDIN_FILENO); #ifdef WIN32 // Replace the original stdin with the console input handle. - close(STDIN_FILENO); - const HANDLE conin_handle = - CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, 0, (HANDLE)NULL); - const int conin_fd = _open_osfhandle(conin_handle, _O_RDONLY); - assert(conin_fd == STDIN_FILENO); + os_replace_stdin_to_conin(); #endif FileDescriptor *const stdin_dup = file_open_fd_new( &error, stdin_dup_fd, kFileReadOnly|kFileNonBlocking); diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c new file mode 100644 index 0000000000..50127248a4 --- /dev/null +++ b/src/nvim/os/os_win_console.c @@ -0,0 +1,38 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include "nvim/vim.h" + +int os_get_conin_fd(void) +{ + const HANDLE conin_handle = CreateFile("CONIN$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, 0, (HANDLE)NULL); + assert(conin_handle != INVALID_HANDLE_VALUE); + int conin_fd = _open_osfhandle((intptr_t)conin_handle, _O_RDONLY); + assert(conin_fd != -1); + return conin_fd; +} + +void os_replace_stdin_to_conin(void) +{ + close(STDIN_FILENO); + const int conin_fd = os_get_conin_fd(); + assert(conin_fd == STDIN_FILENO); +} + +void os_replace_stdout_to_conout(void) +{ + close(STDOUT_FILENO); + const HANDLE conout_handle = + CreateFile("CONOUT$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, 0, (HANDLE)NULL); + assert(conout_handle != INVALID_HANDLE_VALUE); + const int conout_fd = _open_osfhandle((intptr_t)conout_handle, 0); + assert(conout_fd == STDOUT_FILENO); +} diff --git a/src/nvim/os/os_win_console.h b/src/nvim/os/os_win_console.h new file mode 100644 index 0000000000..154ec83d8a --- /dev/null +++ b/src/nvim/os/os_win_console.h @@ -0,0 +1,8 @@ +#ifndef NVIM_OS_OS_WIN_CONSOLE_H +#define NVIM_OS_OS_WIN_CONSOLE_H + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/os_win_console.h.generated.h" +#endif + +#endif // NVIM_OS_OS_WIN_CONSOLE_H diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index c71378463f..951cb50c3c 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -14,6 +14,9 @@ #include "nvim/option.h" #include "nvim/os/os.h" #include "nvim/os/input.h" +#ifdef WIN32 +# include "nvim/os/os_win_console.h" +#endif #include "nvim/event/rstream.h" #define KEY_BUFFER_SIZE 0xfff @@ -37,13 +40,7 @@ void tinput_init(TermInput *input, Loop *loop) // ls *.md | xargs nvim #ifdef WIN32 if (!os_isatty(input->in_fd)) { - const HANDLE conin_handle = CreateFile("CONIN$", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, 0, (HANDLE)NULL); - input->in_fd = _open_osfhandle(conin_handle, _O_RDONLY); - assert(input->in_fd != -1); + input->in_fd = os_get_conin_fd(); } #else if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) { -- cgit From 8f91d709b0006e3fcfa4cb59abd9b77938096d76 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 16 Nov 2019 13:50:52 +0900 Subject: Rename from os_win_conpty.{c,h} to pty_conpty_win.{c,h} --- src/nvim/CMakeLists.txt | 4 +- src/nvim/channel.c | 2 +- src/nvim/option.c | 2 +- src/nvim/os/os_win_conpty.c | 199 ------------------------------------------ src/nvim/os/os_win_conpty.h | 22 ----- src/nvim/os/pty_conpty_win.c | 199 ++++++++++++++++++++++++++++++++++++++++++ src/nvim/os/pty_conpty_win.h | 22 +++++ src/nvim/os/pty_process_win.c | 2 +- src/nvim/os/pty_process_win.h | 2 +- 9 files changed, 227 insertions(+), 227 deletions(-) delete mode 100644 src/nvim/os/os_win_conpty.c delete mode 100644 src/nvim/os/os_win_conpty.h create mode 100644 src/nvim/os/pty_conpty_win.c create mode 100644 src/nvim/os/pty_conpty_win.h (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 62d45ff4a3..089dd537e9 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -134,7 +134,7 @@ foreach(sfile ${NVIM_SOURCES}) if(NOT WIN32 AND ${f} MATCHES "^(pty_process_win.c)$") list(APPEND to_remove ${sfile}) endif() - if(NOT WIN32 AND ${f} MATCHES "^(os_win_conpty.c)$") + if(NOT WIN32 AND ${f} MATCHES "^(pty_conpty_win.c)$") list(APPEND to_remove ${sfile}) endif() if(NOT WIN32 AND ${f} MATCHES "^(os_win_console.c)$") @@ -643,7 +643,7 @@ endfunction() set(NO_SINGLE_CHECK_HEADERS os/win_defs.h os/pty_process_win.h - os/os_win_conpty.h + os/pty_conpty_win.h os/os_win_console.h ) foreach(hfile ${NVIM_HEADERS}) diff --git a/src/nvim/channel.c b/src/nvim/channel.c index b346845c66..d3e2977eae 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -12,7 +12,7 @@ #include "nvim/msgpack_rpc/server.h" #include "nvim/os/shell.h" #ifdef WIN32 -# include "nvim/os/os_win_conpty.h" +# include "nvim/os/pty_conpty_win.h" # include "nvim/os/os_win_console.h" #endif #include "nvim/path.h" diff --git a/src/nvim/option.c b/src/nvim/option.c index 591c8234c3..014eb676a0 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -77,7 +77,7 @@ #include "nvim/window.h" #include "nvim/os/os.h" #ifdef WIN32 -# include "nvim/os/os_win_conpty.h" +# include "nvim/os/pty_conpty_win.h" #endif #include "nvim/api/private/helpers.h" #include "nvim/os/input.h" diff --git a/src/nvim/os/os_win_conpty.c b/src/nvim/os/os_win_conpty.c deleted file mode 100644 index 3d5ba83523..0000000000 --- a/src/nvim/os/os_win_conpty.c +++ /dev/null @@ -1,199 +0,0 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - -#include - -#include "nvim/vim.h" -#include "nvim/os/os.h" -#include "nvim/os/os_win_conpty.h" - -#ifndef EXTENDED_STARTUPINFO_PRESENT -# define EXTENDED_STARTUPINFO_PRESENT 0x00080000 -#endif -#ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE -# define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016 -#endif - -HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON *); -HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); -void (WINAPI *pClosePseudoConsole)(HPCON); - -bool os_has_conpty_working(void) -{ - static TriState has_conpty = kNone; - if (has_conpty == kNone) { - has_conpty = os_dyn_conpty_init(); - } - - return has_conpty == kTrue; -} - -TriState os_dyn_conpty_init(void) -{ - uv_lib_t kernel; - if (uv_dlopen("kernel32.dll", &kernel)) { - uv_dlclose(&kernel); - return kFalse; - } - static struct { - char *name; - FARPROC *ptr; - } conpty_entry[] = { - { "CreatePseudoConsole", (FARPROC *)&pCreatePseudoConsole }, - { "ResizePseudoConsole", (FARPROC *)&pResizePseudoConsole }, - { "ClosePseudoConsole", (FARPROC *)&pClosePseudoConsole }, - { NULL, NULL } - }; - for (int i = 0; - conpty_entry[i].name != NULL && conpty_entry[i].ptr != NULL; i++) { - if (uv_dlsym(&kernel, conpty_entry[i].name, (void **)conpty_entry[i].ptr)) { - uv_dlclose(&kernel); - return kFalse; - } - } - return kTrue; -} - -conpty_t *os_conpty_init(char **in_name, char **out_name, - uint16_t width, uint16_t height) -{ - static int count = 0; - conpty_t *conpty_object = xcalloc(1, sizeof(*conpty_object)); - const char *emsg = NULL; - HANDLE in_read = INVALID_HANDLE_VALUE; - HANDLE out_write = INVALID_HANDLE_VALUE; - char buf[MAXPATHL]; - SECURITY_ATTRIBUTES sa = { 0 }; - const DWORD mode = PIPE_ACCESS_INBOUND - | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; - - sa.nLength = sizeof(sa); - snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-in-%d-%d", - os_get_pid(), count); - *in_name = xstrdup(buf); - if ((in_read = CreateNamedPipeA( - *in_name, - mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 1, - 0, - 0, - 30000, - &sa)) == INVALID_HANDLE_VALUE) { - emsg = "create input pipe failed"; - goto failed; - } - snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-out-%d-%d", - os_get_pid(), count); - *out_name = xstrdup(buf); - if ((out_write = CreateNamedPipeA( - *out_name, - mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 1, - 0, - 0, - 30000, - &sa)) == INVALID_HANDLE_VALUE) { - emsg = "create output pipe failed"; - goto failed; - } - assert(width <= SHRT_MAX); - assert(height <= SHRT_MAX); - COORD size = { (int16_t)width, (int16_t)height }; - HRESULT hr; - hr = pCreatePseudoConsole(size, in_read, out_write, 0, &conpty_object->pty); - if (FAILED(hr)) { - emsg = "create psudo console failed"; - goto failed; - } - - conpty_object->si_ex.StartupInfo.cb = sizeof(conpty_object->si_ex); - size_t bytes_required; - InitializeProcThreadAttributeList(NULL, 1, 0, & bytes_required); - conpty_object->si_ex.lpAttributeList = - (PPROC_THREAD_ATTRIBUTE_LIST)xmalloc(bytes_required); - if (!InitializeProcThreadAttributeList( - conpty_object->si_ex.lpAttributeList, - 1, - 0, - &bytes_required)) { - emsg = "InitializeProcThreadAttributeList failed"; - goto failed; - } - if (!UpdateProcThreadAttribute( - conpty_object->si_ex.lpAttributeList, - 0, - PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, - conpty_object->pty, - sizeof(conpty_object->pty), - NULL, - NULL)) { - emsg = "UpdateProcThreadAttribute failed"; - goto failed; - } - count++; - goto finished; - -failed: - ELOG("os_conpty_init:%s : error code: %d", - emsg, os_translate_sys_error((int)GetLastError())); - os_conpty_free(conpty_object); - conpty_object = NULL; -finished: - if (in_read != INVALID_HANDLE_VALUE) { - CloseHandle(in_read); - } - if (out_write != INVALID_HANDLE_VALUE) { - CloseHandle(out_write); - } - return conpty_object; -} - -bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, - wchar_t *name, wchar_t *cmd_line, wchar_t *cwd, - wchar_t *env) -{ - PROCESS_INFORMATION pi = { 0 }; - if (!CreateProcessW( - name, - cmd_line, - NULL, - NULL, - false, - EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, - env, - cwd, - &conpty_object->si_ex.StartupInfo, - &pi)) { - return false; - } - *process_handle = pi.hProcess; - return true; -} - -void os_conpty_set_size(conpty_t *conpty_object, - uint16_t width, uint16_t height) -{ - assert(width <= SHRT_MAX); - assert(height <= SHRT_MAX); - COORD size = { (int16_t)width, (int16_t)height }; - if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { - ELOG("ResizePseudoConsoel failed: error code: %d", - os_translate_sys_error((int)GetLastError())); - } -} - -void os_conpty_free(conpty_t *conpty_object) -{ - if (conpty_object != NULL) { - if (conpty_object->si_ex.lpAttributeList != NULL) { - DeleteProcThreadAttributeList(conpty_object->si_ex.lpAttributeList); - xfree(conpty_object->si_ex.lpAttributeList); - } - if (conpty_object->pty != NULL) { - pClosePseudoConsole(conpty_object->pty); - } - } - xfree(conpty_object); -} diff --git a/src/nvim/os/os_win_conpty.h b/src/nvim/os/os_win_conpty.h deleted file mode 100644 index 8a5f45e2cd..0000000000 --- a/src/nvim/os/os_win_conpty.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef NVIM_OS_OS_WIN_CONPTY_H -#define NVIM_OS_OS_WIN_CONPTY_H - -#ifndef HPCON -# define HPCON VOID * -#endif - -extern HRESULT (WINAPI *pCreatePseudoConsole) // NOLINT(whitespace/parens) - (COORD, HANDLE, HANDLE, DWORD, HPCON *); -extern HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); -extern void (WINAPI *pClosePseudoConsole)(HPCON); - -typedef struct conpty { - HPCON pty; - STARTUPINFOEXW si_ex; -} conpty_t; - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/os_win_conpty.h.generated.h" -#endif - -#endif // NVIM_OS_OS_WIN_CONPTY_H diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c new file mode 100644 index 0000000000..5bcadd6490 --- /dev/null +++ b/src/nvim/os/pty_conpty_win.c @@ -0,0 +1,199 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include + +#include "nvim/vim.h" +#include "nvim/os/os.h" +#include "nvim/os/pty_conpty_win.h" + +#ifndef EXTENDED_STARTUPINFO_PRESENT +# define EXTENDED_STARTUPINFO_PRESENT 0x00080000 +#endif +#ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE +# define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016 +#endif + +HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON *); +HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); +void (WINAPI *pClosePseudoConsole)(HPCON); + +bool os_has_conpty_working(void) +{ + static TriState has_conpty = kNone; + if (has_conpty == kNone) { + has_conpty = os_dyn_conpty_init(); + } + + return has_conpty == kTrue; +} + +TriState os_dyn_conpty_init(void) +{ + uv_lib_t kernel; + if (uv_dlopen("kernel32.dll", &kernel)) { + uv_dlclose(&kernel); + return kFalse; + } + static struct { + char *name; + FARPROC *ptr; + } conpty_entry[] = { + { "CreatePseudoConsole", (FARPROC *)&pCreatePseudoConsole }, + { "ResizePseudoConsole", (FARPROC *)&pResizePseudoConsole }, + { "ClosePseudoConsole", (FARPROC *)&pClosePseudoConsole }, + { NULL, NULL } + }; + for (int i = 0; + conpty_entry[i].name != NULL && conpty_entry[i].ptr != NULL; i++) { + if (uv_dlsym(&kernel, conpty_entry[i].name, (void **)conpty_entry[i].ptr)) { + uv_dlclose(&kernel); + return kFalse; + } + } + return kTrue; +} + +conpty_t *os_conpty_init(char **in_name, char **out_name, + uint16_t width, uint16_t height) +{ + static int count = 0; + conpty_t *conpty_object = xcalloc(1, sizeof(*conpty_object)); + const char *emsg = NULL; + HANDLE in_read = INVALID_HANDLE_VALUE; + HANDLE out_write = INVALID_HANDLE_VALUE; + char buf[MAXPATHL]; + SECURITY_ATTRIBUTES sa = { 0 }; + const DWORD mode = PIPE_ACCESS_INBOUND + | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; + + sa.nLength = sizeof(sa); + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-in-%d-%d", + os_get_pid(), count); + *in_name = xstrdup(buf); + if ((in_read = CreateNamedPipeA( + *in_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { + emsg = "create input pipe failed"; + goto failed; + } + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-out-%d-%d", + os_get_pid(), count); + *out_name = xstrdup(buf); + if ((out_write = CreateNamedPipeA( + *out_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { + emsg = "create output pipe failed"; + goto failed; + } + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + HRESULT hr; + hr = pCreatePseudoConsole(size, in_read, out_write, 0, &conpty_object->pty); + if (FAILED(hr)) { + emsg = "create psudo console failed"; + goto failed; + } + + conpty_object->si_ex.StartupInfo.cb = sizeof(conpty_object->si_ex); + size_t bytes_required; + InitializeProcThreadAttributeList(NULL, 1, 0, & bytes_required); + conpty_object->si_ex.lpAttributeList = + (PPROC_THREAD_ATTRIBUTE_LIST)xmalloc(bytes_required); + if (!InitializeProcThreadAttributeList( + conpty_object->si_ex.lpAttributeList, + 1, + 0, + &bytes_required)) { + emsg = "InitializeProcThreadAttributeList failed"; + goto failed; + } + if (!UpdateProcThreadAttribute( + conpty_object->si_ex.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + conpty_object->pty, + sizeof(conpty_object->pty), + NULL, + NULL)) { + emsg = "UpdateProcThreadAttribute failed"; + goto failed; + } + count++; + goto finished; + +failed: + ELOG("os_conpty_init:%s : error code: %d", + emsg, os_translate_sys_error((int)GetLastError())); + os_conpty_free(conpty_object); + conpty_object = NULL; +finished: + if (in_read != INVALID_HANDLE_VALUE) { + CloseHandle(in_read); + } + if (out_write != INVALID_HANDLE_VALUE) { + CloseHandle(out_write); + } + return conpty_object; +} + +bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, + wchar_t *name, wchar_t *cmd_line, wchar_t *cwd, + wchar_t *env) +{ + PROCESS_INFORMATION pi = { 0 }; + if (!CreateProcessW( + name, + cmd_line, + NULL, + NULL, + false, + EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, + env, + cwd, + &conpty_object->si_ex.StartupInfo, + &pi)) { + return false; + } + *process_handle = pi.hProcess; + return true; +} + +void os_conpty_set_size(conpty_t *conpty_object, + uint16_t width, uint16_t height) +{ + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { + ELOG("ResizePseudoConsoel failed: error code: %d", + os_translate_sys_error((int)GetLastError())); + } +} + +void os_conpty_free(conpty_t *conpty_object) +{ + if (conpty_object != NULL) { + if (conpty_object->si_ex.lpAttributeList != NULL) { + DeleteProcThreadAttributeList(conpty_object->si_ex.lpAttributeList); + xfree(conpty_object->si_ex.lpAttributeList); + } + if (conpty_object->pty != NULL) { + pClosePseudoConsole(conpty_object->pty); + } + } + xfree(conpty_object); +} diff --git a/src/nvim/os/pty_conpty_win.h b/src/nvim/os/pty_conpty_win.h new file mode 100644 index 0000000000..c243db4fa5 --- /dev/null +++ b/src/nvim/os/pty_conpty_win.h @@ -0,0 +1,22 @@ +#ifndef NVIM_OS_PTY_CONPTY_WIN_H +#define NVIM_OS_PTY_CONPTY_WIN_H + +#ifndef HPCON +# define HPCON VOID * +#endif + +extern HRESULT (WINAPI *pCreatePseudoConsole) // NOLINT(whitespace/parens) + (COORD, HANDLE, HANDLE, DWORD, HPCON *); +extern HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD); +extern void (WINAPI *pClosePseudoConsole)(HPCON); + +typedef struct conpty { + HPCON pty; + STARTUPINFOEXW si_ex; +} conpty_t; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/pty_conpty_win.h.generated.h" +#endif + +#endif // NVIM_OS_PTY_CONPTY_WIN_H diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 7108d9c049..64d4408ece 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -12,7 +12,7 @@ #include "nvim/memory.h" #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 #include "nvim/os/pty_process_win.h" -#include "nvim/os/os_win_conpty.h" +#include "nvim/os/pty_conpty_win.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_win.c.generated.h" diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h index 04c8439c6c..8ad5ba7286 100644 --- a/src/nvim/os/pty_process_win.h +++ b/src/nvim/os/pty_process_win.h @@ -6,7 +6,7 @@ #include "nvim/event/process.h" #include "nvim/lib/queue.h" -#include "nvim/os/os_win_conpty.h" +#include "nvim/os/pty_conpty_win.h" typedef enum { kWinpty, -- cgit From a5a3d7160d7cb70ef2477f243d7a537fc4fa20e8 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 16 Nov 2019 13:55:27 +0900 Subject: Change option name from termwintype to termtype --- src/nvim/option.c | 6 +++--- src/nvim/option_defs.h | 2 +- src/nvim/options.lua | 4 ++-- src/nvim/os/pty_process_win.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 014eb676a0..959b4c41a5 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -314,7 +314,7 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2", "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8", "yes:9", NULL }; #ifdef WIN32 -static char *(p_twt_values[]) = { "conpty", "winpty", "", NULL }; +static char *(p_tmt_values[]) = { "conpty", "winpty", "", NULL }; #endif /// All possible flags for 'shm'. @@ -3289,8 +3289,8 @@ ambw_end: errmsg = e_invarg; } #ifdef WIN32 - } else if (varp == &p_twt) { - if (check_opt_strings(*varp, p_twt_values, false) != OK + } else if (varp == &p_tmt) { + if (check_opt_strings(*varp, p_tmt_values, false) != OK || (!os_has_conpty_working() && STRCMP(*varp, "conpty") == 0)) { errmsg = e_invarg; } diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 1d4c31dc1c..b66c4a7f02 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -654,7 +654,7 @@ EXTERN char_u *p_titleold; ///< 'titleold' EXTERN char_u *p_titlestring; ///< 'titlestring' EXTERN char_u *p_tsr; ///< 'thesaurus' EXTERN int p_tgc; ///< 'termguicolors' -EXTERN char_u *p_twt; ///< 'termwintype' +EXTERN char_u *p_tmt; ///< 'termtype' EXTERN int p_ttimeout; ///< 'ttimeout' EXTERN long p_ttm; ///< 'ttimeoutlen' EXTERN char_u *p_udir; ///< 'undodir' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index fe970ccba3..2e20b692e8 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2497,10 +2497,10 @@ return { defaults={if_true={vi=false}} }, { - full_name='termwintype', abbreviation='twt', + full_name='termtype', abbreviation='tmt', type='string', scope={'global'}, vi_def=false, - varname='p_twt', + varname='p_tmt', defaults={if_true={vi="",vim=""}} }, { diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 64d4408ece..93f1656029 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -56,8 +56,8 @@ int pty_process_spawn(PtyProcess *ptyproc) assert(proc->err.closed); - int pty_type = *p_twt; - if (pty_type == 'c' && os_has_conpty_working()) { + int pty_type = *p_tmt; + if (pty_type != 'w' && os_has_conpty_working()) { if ((conpty_object = os_conpty_init(&in_name, &out_name, ptyproc->width, ptyproc->height)) != NULL) { -- cgit From 4e06594c53645c9b3dc6c57850f712a810d071d3 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sun, 17 Nov 2019 12:20:24 +0900 Subject: Add missing include file --- src/nvim/os/os_win_console.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 50127248a4..6cabeb2c9a 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -2,6 +2,7 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include "nvim/vim.h" +#include "nvim/os/os_win_console.h" int os_get_conin_fd(void) { -- cgit From c86d5fa981b0651167f789aaff685b42cad7aaca Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 22 Nov 2019 13:51:14 +0900 Subject: Change to replace stderr with conout --- src/nvim/channel.c | 2 +- src/nvim/os/os_win_console.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/channel.c b/src/nvim/channel.c index d3e2977eae..c66a0682e3 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -482,7 +482,7 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, stdin_dup_fd = os_dup(STDIN_FILENO); os_replace_stdin_to_conin(); stdout_dup_fd = os_dup(STDOUT_FILENO); - os_replace_stdout_to_conout(); + os_replace_stdout_and_stderr_to_conout(); } #endif rstream_init_fd(&main_loop, &channel->stream.stdio.in, stdin_dup_fd, 0); diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 6cabeb2c9a..8a0aa2f5ae 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -24,9 +24,8 @@ void os_replace_stdin_to_conin(void) assert(conin_fd == STDIN_FILENO); } -void os_replace_stdout_to_conout(void) +void os_replace_stdout_and_stderr_to_conout(void) { - close(STDOUT_FILENO); const HANDLE conout_handle = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, @@ -34,6 +33,10 @@ void os_replace_stdout_to_conout(void) (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, (HANDLE)NULL); assert(conout_handle != INVALID_HANDLE_VALUE); + close(STDOUT_FILENO); const int conout_fd = _open_osfhandle((intptr_t)conout_handle, 0); assert(conout_fd == STDOUT_FILENO); + close(STDERR_FILENO); + const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0); + assert(conerr_fd == STDERR_FILENO); } -- cgit From 1e4f29069146cbab0be0559d87e399aefa433a29 Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 22 Nov 2019 14:01:12 +0900 Subject: Remove termtype option --- src/nvim/option.c | 10 ---------- src/nvim/option_defs.h | 1 - src/nvim/options.lua | 7 ------- src/nvim/os/pty_process_win.c | 3 +-- 4 files changed, 1 insertion(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 959b4c41a5..0c87a422dc 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -313,9 +313,6 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2", "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8", "yes:9", NULL }; -#ifdef WIN32 -static char *(p_tmt_values[]) = { "conpty", "winpty", "", NULL }; -#endif /// All possible flags for 'shm'. static char_u SHM_ALL[] = { @@ -3288,13 +3285,6 @@ ambw_end: if (!parse_winhl_opt(curwin)) { errmsg = e_invarg; } -#ifdef WIN32 - } else if (varp == &p_tmt) { - if (check_opt_strings(*varp, p_tmt_values, false) != OK - || (!os_has_conpty_working() && STRCMP(*varp, "conpty") == 0)) { - errmsg = e_invarg; - } -#endif } else { // Options that are a list of flags. p = NULL; diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index b66c4a7f02..fcad6836bf 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -654,7 +654,6 @@ EXTERN char_u *p_titleold; ///< 'titleold' EXTERN char_u *p_titlestring; ///< 'titlestring' EXTERN char_u *p_tsr; ///< 'thesaurus' EXTERN int p_tgc; ///< 'termguicolors' -EXTERN char_u *p_tmt; ///< 'termtype' EXTERN int p_ttimeout; ///< 'ttimeout' EXTERN long p_ttm; ///< 'ttimeoutlen' EXTERN char_u *p_udir; ///< 'undodir' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 2e20b692e8..a5a14a1a25 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2496,13 +2496,6 @@ return { varname='p_tgc', defaults={if_true={vi=false}} }, - { - full_name='termtype', abbreviation='tmt', - type='string', scope={'global'}, - vi_def=false, - varname='p_tmt', - defaults={if_true={vi="",vim=""}} - }, { full_name='terse', type='bool', scope={'global'}, diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 93f1656029..6f7100e846 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -56,8 +56,7 @@ int pty_process_spawn(PtyProcess *ptyproc) assert(proc->err.closed); - int pty_type = *p_tmt; - if (pty_type != 'w' && os_has_conpty_working()) { + if (os_has_conpty_working()) { if ((conpty_object = os_conpty_init(&in_name, &out_name, ptyproc->width, ptyproc->height)) != NULL) { -- cgit