mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
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
This commit is contained in:
@ -3,8 +3,11 @@
|
|||||||
" Start the provider and perform a 'poll' request
|
" Start the provider and perform a 'poll' request
|
||||||
"
|
"
|
||||||
" Returns a valid channel on success
|
" 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}
|
let job = {'rpc': v:true, 'stderr_buffered': v:true}
|
||||||
|
if a:0
|
||||||
|
let job = extend(job, a:1)
|
||||||
|
endif
|
||||||
try
|
try
|
||||||
let channel_id = jobstart(a:argv, job)
|
let channel_id = jobstart(a:argv, job)
|
||||||
if channel_id > 0 && rpcrequest(channel_id, 'poll') ==# 'ok'
|
if channel_id > 0 && rpcrequest(channel_id, 'poll') ==# 'ok'
|
||||||
|
@ -19,7 +19,7 @@ function! provider#pythonx#Require(host) abort
|
|||||||
call add(args, plugin.path)
|
call add(args, plugin.path)
|
||||||
endfor
|
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
|
endfunction
|
||||||
|
|
||||||
function! s:get_python_executable_from_host_var(major_version) abort
|
function! s:get_python_executable_from_host_var(major_version) abort
|
||||||
|
@ -5506,6 +5506,11 @@ jobstart({cmd}[, {opts}]) *jobstart()*
|
|||||||
stdout data.
|
stdout data.
|
||||||
|on_stderr|: (function) Callback invoked when the job emits
|
|on_stderr|: (function) Callback invoked when the job emits
|
||||||
stderr data.
|
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
|
pty: (boolean) Connect the job to a new pseudo
|
||||||
terminal, and its streams to the master file
|
terminal, and its streams to the master file
|
||||||
descriptor. Then `on_stderr` is ignored,
|
descriptor. Then `on_stderr` is ignored,
|
||||||
|
@ -301,7 +301,8 @@ static void close_cb(Stream *stream, void *data)
|
|||||||
/// @returns [allocated] channel
|
/// @returns [allocated] channel
|
||||||
Channel *channel_job_start(char **argv, CallbackReader on_stdout,
|
Channel *channel_job_start(char **argv, CallbackReader on_stdout,
|
||||||
CallbackReader on_stderr, Callback on_exit,
|
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,
|
uint16_t pty_width, uint16_t pty_height,
|
||||||
char *term_name, char **env, varnumber_T *status_out)
|
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->detach = detach;
|
||||||
proc->cwd = cwd;
|
proc->cwd = cwd;
|
||||||
proc->env = env;
|
proc->env = env;
|
||||||
|
proc->overlapped = overlapped;
|
||||||
|
|
||||||
char *cmd = xstrdup(proc->argv[0]);
|
char *cmd = xstrdup(proc->argv[0]);
|
||||||
bool has_out, has_err;
|
bool has_out, has_err;
|
||||||
|
@ -4862,6 +4862,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
bool rpc = false;
|
bool rpc = false;
|
||||||
bool pty = false;
|
bool pty = false;
|
||||||
bool clear_env = false;
|
bool clear_env = false;
|
||||||
|
bool overlapped = false;
|
||||||
CallbackReader on_stdout = CALLBACK_READER_INIT,
|
CallbackReader on_stdout = CALLBACK_READER_INIT,
|
||||||
on_stderr = CALLBACK_READER_INIT;
|
on_stderr = CALLBACK_READER_INIT;
|
||||||
Callback on_exit = CALLBACK_NONE;
|
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;
|
rpc = tv_dict_get_number(job_opts, "rpc") != 0;
|
||||||
pty = tv_dict_get_number(job_opts, "pty") != 0;
|
pty = tv_dict_get_number(job_opts, "pty") != 0;
|
||||||
clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
|
clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
|
||||||
|
overlapped = tv_dict_get_number(job_opts, "overlapped") != 0;
|
||||||
|
|
||||||
if (pty && rpc) {
|
if (pty && rpc) {
|
||||||
EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
|
EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
|
||||||
shell_free_argv(argv);
|
shell_free_argv(argv);
|
||||||
return;
|
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);
|
char *new_cwd = tv_dict_get_string(job_opts, "cwd", false);
|
||||||
if (new_cwd && strlen(new_cwd) > 0) {
|
if (new_cwd && strlen(new_cwd) > 0) {
|
||||||
cwd = new_cwd;
|
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,
|
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);
|
term_name, env, &rettv->vval.v_number);
|
||||||
if (chan) {
|
if (chan) {
|
||||||
channel_create_event(chan, NULL);
|
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,
|
Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT,
|
||||||
CALLBACK_READER_INIT, CALLBACK_NONE,
|
CALLBACK_READER_INIT, CALLBACK_NONE,
|
||||||
false, true, false, NULL, 0, 0, NULL, NULL,
|
false, true, false, false, NULL, 0, 0,
|
||||||
&rettv->vval.v_number);
|
NULL, NULL, &rettv->vval.v_number);
|
||||||
if (chan) {
|
if (chan) {
|
||||||
channel_create_event(chan, NULL);
|
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));
|
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,
|
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,
|
term_width, curwin->w_height_inner,
|
||||||
xstrdup("xterm-256color"), NULL,
|
xstrdup("xterm-256color"), NULL,
|
||||||
&rettv->vval.v_number);
|
&rettv->vval.v_number);
|
||||||
|
@ -52,7 +52,7 @@ int libuv_process_spawn(LibuvProcess *uvproc)
|
|||||||
if (!proc->in.closed) {
|
if (!proc->in.closed) {
|
||||||
uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
|
uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
uvproc->uvstdio[0].flags |= UV_OVERLAPPED_PIPE;
|
uvproc->uvstdio[0].flags |= proc->overlapped ? UV_OVERLAPPED_PIPE : 0;
|
||||||
#endif
|
#endif
|
||||||
uvproc->uvstdio[0].data.stream = STRUCT_CAST(uv_stream_t,
|
uvproc->uvstdio[0].data.stream = STRUCT_CAST(uv_stream_t,
|
||||||
&proc->in.uv.pipe);
|
&proc->in.uv.pipe);
|
||||||
@ -61,8 +61,9 @@ int libuv_process_spawn(LibuvProcess *uvproc)
|
|||||||
if (!proc->out.closed) {
|
if (!proc->out.closed) {
|
||||||
uvproc->uvstdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
|
uvproc->uvstdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// pipe must be readable for IOCP to work.
|
// pipe must be readable for IOCP to work on Windows.
|
||||||
uvproc->uvstdio[1].flags |= UV_READABLE_PIPE | UV_OVERLAPPED_PIPE;
|
uvproc->uvstdio[1].flags |= proc->overlapped ?
|
||||||
|
(UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0;
|
||||||
#endif
|
#endif
|
||||||
uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t,
|
uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t,
|
||||||
&proc->out.uv.pipe);
|
&proc->out.uv.pipe);
|
||||||
|
@ -27,7 +27,7 @@ struct process {
|
|||||||
Stream in, out, err;
|
Stream in, out, err;
|
||||||
process_exit_cb cb;
|
process_exit_cb cb;
|
||||||
internal_process_cb internal_exit_cb, internal_close_cb;
|
internal_process_cb internal_exit_cb, internal_close_cb;
|
||||||
bool closed, detach;
|
bool closed, detach, overlapped;
|
||||||
MultiQueue *events;
|
MultiQueue *events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user