mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #21675 from bfredl/nonstdio
fix(embed): handle stdio in server properly
This commit is contained in:
commit
df60ac9767
@ -377,6 +377,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
|
|||||||
} else {
|
} else {
|
||||||
has_out = rpc || callback_reader_set(chan->on_data);
|
has_out = rpc || callback_reader_set(chan->on_data);
|
||||||
has_err = callback_reader_set(chan->on_stderr);
|
has_err = callback_reader_set(chan->on_stderr);
|
||||||
|
proc->fwd_err = chan->on_stderr.fwd_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (stdin_mode) {
|
switch (stdin_mode) {
|
||||||
@ -519,6 +520,13 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, const char **err
|
|||||||
stdout_dup_fd = os_dup(STDOUT_FILENO);
|
stdout_dup_fd = os_dup(STDOUT_FILENO);
|
||||||
os_replace_stdout_and_stderr_to_conout();
|
os_replace_stdout_and_stderr_to_conout();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (embedded_mode) {
|
||||||
|
stdin_dup_fd = dup(STDIN_FILENO);
|
||||||
|
stdout_dup_fd = dup(STDOUT_FILENO);
|
||||||
|
dup2(STDERR_FILENO, STDOUT_FILENO);
|
||||||
|
dup2(STDERR_FILENO, STDIN_FILENO);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
rstream_init_fd(&main_loop, &channel->stream.stdio.in, stdin_dup_fd, 0);
|
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);
|
wstream_init_fd(&main_loop, &channel->stream.stdio.out, stdout_dup_fd, 0);
|
||||||
|
@ -66,6 +66,7 @@ typedef struct {
|
|||||||
garray_T buffer;
|
garray_T buffer;
|
||||||
bool eof;
|
bool eof;
|
||||||
bool buffered;
|
bool buffered;
|
||||||
|
bool fwd_err;
|
||||||
const char *type;
|
const char *type;
|
||||||
} CallbackReader;
|
} CallbackReader;
|
||||||
|
|
||||||
@ -73,6 +74,7 @@ typedef struct {
|
|||||||
.self = NULL, \
|
.self = NULL, \
|
||||||
.buffer = GA_EMPTY_INIT_VALUE, \
|
.buffer = GA_EMPTY_INIT_VALUE, \
|
||||||
.buffered = false, \
|
.buffered = false, \
|
||||||
|
.fwd_err = false, \
|
||||||
.type = NULL })
|
.type = NULL })
|
||||||
static inline bool callback_reader_set(CallbackReader reader)
|
static inline bool callback_reader_set(CallbackReader reader)
|
||||||
{
|
{
|
||||||
|
@ -85,6 +85,9 @@ int libuv_process_spawn(LibuvProcess *uvproc)
|
|||||||
uvproc->uvstdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
|
uvproc->uvstdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
|
||||||
uvproc->uvstdio[2].data.stream = STRUCT_CAST(uv_stream_t,
|
uvproc->uvstdio[2].data.stream = STRUCT_CAST(uv_stream_t,
|
||||||
&proc->err.uv.pipe);
|
&proc->err.uv.pipe);
|
||||||
|
} else if (proc->fwd_err) {
|
||||||
|
uvproc->uvstdio[2].flags = UV_INHERIT_FD;
|
||||||
|
uvproc->uvstdio[2].data.fd = STDERR_FILENO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
|
@ -43,6 +43,9 @@ static int exit_need_delay = 0;
|
|||||||
int process_spawn(Process *proc, bool in, bool out, bool err)
|
int process_spawn(Process *proc, bool in, bool out, bool err)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
|
// forwarding stderr contradicts with processing it internally
|
||||||
|
assert(!(err && proc->fwd_err));
|
||||||
|
|
||||||
if (in) {
|
if (in) {
|
||||||
uv_pipe_init(&proc->loop->uv, &proc->in.uv.pipe, 0);
|
uv_pipe_init(&proc->loop->uv, &proc->in.uv.pipe, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,7 +38,7 @@ struct process {
|
|||||||
/// Exit handler. If set, user must call process_free().
|
/// Exit handler. If set, user must call process_free().
|
||||||
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, overlapped;
|
bool closed, detach, overlapped, fwd_err;
|
||||||
MultiQueue *events;
|
MultiQueue *events;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,7 +62,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
|
|||||||
.closed = false,
|
.closed = false,
|
||||||
.internal_close_cb = NULL,
|
.internal_close_cb = NULL,
|
||||||
.internal_exit_cb = NULL,
|
.internal_exit_cb = NULL,
|
||||||
.detach = false
|
.detach = false,
|
||||||
|
.fwd_err = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +279,15 @@ int main(int argc, char **argv)
|
|||||||
// argument list "global_alist".
|
// argument list "global_alist".
|
||||||
command_line_scan(¶ms);
|
command_line_scan(¶ms);
|
||||||
|
|
||||||
|
#ifndef MSWIN
|
||||||
|
int tty_fd = params.input_isatty
|
||||||
|
? STDIN_FILENO
|
||||||
|
: (params.output_isatty
|
||||||
|
? STDOUT_FILENO
|
||||||
|
: (params.err_isatty ? STDERR_FILENO : -1));
|
||||||
|
pty_process_save_termios(tty_fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
nlua_init(argv, argc, params.lua_arg0);
|
nlua_init(argv, argc, params.lua_arg0);
|
||||||
TIME_MSG("init lua interpreter");
|
TIME_MSG("init lua interpreter");
|
||||||
|
|
||||||
@ -1455,14 +1464,6 @@ static void check_and_set_isatty(mparm_T *paramp)
|
|||||||
stdout_isatty
|
stdout_isatty
|
||||||
= paramp->output_isatty = os_isatty(STDOUT_FILENO);
|
= paramp->output_isatty = os_isatty(STDOUT_FILENO);
|
||||||
paramp->err_isatty = os_isatty(STDERR_FILENO);
|
paramp->err_isatty = os_isatty(STDERR_FILENO);
|
||||||
#ifndef MSWIN
|
|
||||||
int tty_fd = paramp->input_isatty
|
|
||||||
? STDIN_FILENO
|
|
||||||
: (paramp->output_isatty
|
|
||||||
? STDOUT_FILENO
|
|
||||||
: (paramp->err_isatty ? STDERR_FILENO : -1));
|
|
||||||
pty_process_save_termios(tty_fd);
|
|
||||||
#endif
|
|
||||||
TIME_MSG("window checked");
|
TIME_MSG("window checked");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +168,14 @@ static struct termios termios_default;
|
|||||||
/// @param tty_fd TTY file descriptor, or -1 if not in a terminal.
|
/// @param tty_fd TTY file descriptor, or -1 if not in a terminal.
|
||||||
void pty_process_save_termios(int tty_fd)
|
void pty_process_save_termios(int tty_fd)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
// TODO(bfredl): currently we cannot use the state of the host terminal in
|
||||||
|
// the server. when the TUI process launches the server, the state has already
|
||||||
|
// changed. we would need to serialize termios_default in the TUI process and
|
||||||
|
// transmit it. Altough, just always using the clean slate of init_termios() might
|
||||||
|
// be preferrable anyway.
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (tty_fd == -1) {
|
if (tty_fd == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,11 @@ uint64_t ui_client_start_server(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
args[args_idx++] = NULL;
|
args[args_idx++] = NULL;
|
||||||
|
|
||||||
|
CallbackReader on_err = CALLBACK_READER_INIT;
|
||||||
|
on_err.fwd_err = true;
|
||||||
|
|
||||||
Channel *channel = channel_job_start(args, CALLBACK_READER_INIT,
|
Channel *channel = channel_job_start(args, CALLBACK_READER_INIT,
|
||||||
CALLBACK_READER_INIT, CALLBACK_NONE,
|
on_err, CALLBACK_NONE,
|
||||||
false, true, true, false, kChannelStdinPipe,
|
false, true, true, false, kChannelStdinPipe,
|
||||||
NULL, 0, 0, NULL, &exit_status);
|
NULL, 0, 0, NULL, &exit_status);
|
||||||
if (ui_client_forward_stdin) {
|
if (ui_client_forward_stdin) {
|
||||||
|
Loading…
Reference in New Issue
Block a user