diff options
author | erw7 <erw7.github@gmail.com> | 2020-02-05 16:04:45 +0900 |
---|---|---|
committer | erw7 <erw7.github@gmail.com> | 2020-06-10 22:21:14 +0900 |
commit | d17e38e48209c19b63d809c5b807613f15aa03c8 (patch) | |
tree | d65d1445fcf8befb2ea556b180bd3d05019f7bc1 | |
parent | d8c5d122f1ba95bc71a78c5d70465bfa88623bd7 (diff) | |
download | rneovim-d17e38e48209c19b63d809c5b807613f15aa03c8.tar.gz rneovim-d17e38e48209c19b63d809c5b807613f15aa03c8.tar.bz2 rneovim-d17e38e48209c19b63d809c5b807613f15aa03c8.zip |
Add overlapped option to jobstart
When UV_OVERLAPPED_PIPE was used for the pipe passed to the child process, a
problem occurred with the standard input of the .Net Framework application
(#11809). Therefore, add the overlapped option to jobstart() and change it so
that it is set only when necessary
-rw-r--r-- | runtime/autoload/provider.vim | 5 | ||||
-rw-r--r-- | runtime/autoload/provider/pythonx.vim | 2 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 5 | ||||
-rw-r--r-- | src/nvim/channel.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 20 | ||||
-rw-r--r-- | src/nvim/event/libuv_process.c | 7 | ||||
-rw-r--r-- | src/nvim/event/process.h | 2 |
7 files changed, 34 insertions, 11 deletions
diff --git a/runtime/autoload/provider.vim b/runtime/autoload/provider.vim index dc24e801d0..803c1a0b1c 100644 --- a/runtime/autoload/provider.vim +++ b/runtime/autoload/provider.vim @@ -3,8 +3,11 @@ " Start the provider and perform a 'poll' request " " Returns a valid channel on success -function! provider#Poll(argv, orig_name, log_env) abort +function! provider#Poll(argv, orig_name, log_env, ...) abort let job = {'rpc': v:true, 'stderr_buffered': v:true} + if a:0 + let job = extend(job, a:1) + endif try let channel_id = jobstart(a:argv, job) if channel_id > 0 && rpcrequest(channel_id, 'poll') ==# 'ok' diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index ffb9bf3021..e89d519790 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -19,7 +19,7 @@ function! provider#pythonx#Require(host) abort call add(args, plugin.path) endfor - return provider#Poll(args, a:host.orig_name, '$NVIM_PYTHON_LOG_FILE') + return provider#Poll(args, a:host.orig_name, '$NVIM_PYTHON_LOG_FILE', {'overlapped': v:true}) endfunction function! s:get_python_executable_from_host_var(major_version) abort diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 99bc526659..92f703a8a3 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -5506,6 +5506,11 @@ jobstart({cmd}[, {opts}]) *jobstart()* stdout data. |on_stderr|: (function) Callback invoked when the job emits stderr data. + overlapped: (boolean) Set FILE_FLAG_OVERLAPPED for the + standard input/output passed to the child process. + Normally you do not need to set this. + (Only available on MS-Windows, On other + platforms, this option is silently ignored.) pty: (boolean) Connect the job to a new pseudo terminal, and its streams to the master file descriptor. Then `on_stderr` is ignored, diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 5eb29a7290..37cbfb968b 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -301,7 +301,8 @@ static void close_cb(Stream *stream, void *data) /// @returns [allocated] channel Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader on_stderr, Callback on_exit, - bool pty, bool rpc, bool detach, const char *cwd, + bool pty, bool rpc, bool overlapped, bool detach, + const char *cwd, uint16_t pty_width, uint16_t pty_height, char *term_name, char **env, varnumber_T *status_out) { @@ -342,6 +343,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, proc->detach = detach; proc->cwd = cwd; proc->env = env; + proc->overlapped = overlapped; char *cmd = xstrdup(proc->argv[0]); bool has_out, has_err; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4526eecaba..1071e75c06 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -4862,6 +4862,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool rpc = false; bool pty = false; bool clear_env = false; + bool overlapped = false; CallbackReader on_stdout = CALLBACK_READER_INIT, on_stderr = CALLBACK_READER_INIT; Callback on_exit = CALLBACK_NONE; @@ -4873,12 +4874,23 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) rpc = tv_dict_get_number(job_opts, "rpc") != 0; pty = tv_dict_get_number(job_opts, "pty") != 0; clear_env = tv_dict_get_number(job_opts, "clear_env") != 0; + overlapped = tv_dict_get_number(job_opts, "overlapped") != 0; + if (pty && rpc) { EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set"); shell_free_argv(argv); return; } +#ifdef WIN32 + if (pty && overlapped) { + EMSG2(_(e_invarg2), + "job cannot have both 'pty' and 'overlapped' options set"); + shell_free_argv(argv); + return; + } +#endif + char *new_cwd = tv_dict_get_string(job_opts, "cwd", false); if (new_cwd && strlen(new_cwd) > 0) { cwd = new_cwd; @@ -4945,7 +4957,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty, - rpc, detach, cwd, width, height, + rpc, overlapped, detach, cwd, width, height, term_name, env, &rettv->vval.v_number); if (chan) { channel_create_event(chan, NULL); @@ -7372,8 +7384,8 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT, CALLBACK_READER_INIT, CALLBACK_NONE, - false, true, false, NULL, 0, 0, NULL, NULL, - &rettv->vval.v_number); + false, true, false, false, NULL, 0, 0, + NULL, NULL, &rettv->vval.v_number); if (chan) { channel_create_event(chan, NULL); } @@ -10461,7 +10473,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) uint16_t term_width = MAX(0, curwin->w_width_inner - win_col_off(curwin)); Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, - true, false, false, cwd, + true, false, false, false, cwd, term_width, curwin->w_height_inner, xstrdup("xterm-256color"), NULL, &rettv->vval.v_number); diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 37b9f73ba4..13517d3df1 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -52,7 +52,7 @@ int libuv_process_spawn(LibuvProcess *uvproc) if (!proc->in.closed) { uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; #ifdef WIN32 - uvproc->uvstdio[0].flags |= UV_OVERLAPPED_PIPE; + uvproc->uvstdio[0].flags |= proc->overlapped ? UV_OVERLAPPED_PIPE : 0; #endif uvproc->uvstdio[0].data.stream = STRUCT_CAST(uv_stream_t, &proc->in.uv.pipe); @@ -61,8 +61,9 @@ int libuv_process_spawn(LibuvProcess *uvproc) if (!proc->out.closed) { uvproc->uvstdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; #ifdef WIN32 - // pipe must be readable for IOCP to work. - uvproc->uvstdio[1].flags |= UV_READABLE_PIPE | UV_OVERLAPPED_PIPE; + // pipe must be readable for IOCP to work on Windows. + uvproc->uvstdio[1].flags |= proc->overlapped ? + (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0; #endif uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t, &proc->out.uv.pipe); diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index b677b80bfe..84e81238e9 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -27,7 +27,7 @@ struct process { Stream in, out, err; process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; - bool closed, detach; + bool closed, detach, overlapped; MultiQueue *events; }; |