diff options
-rw-r--r-- | src/nvim/channel.c | 8 | ||||
-rw-r--r-- | src/nvim/channel.h | 2 | ||||
-rw-r--r-- | src/nvim/event/libuv_process.c | 3 | ||||
-rw-r--r-- | src/nvim/event/process.c | 3 | ||||
-rw-r--r-- | src/nvim/event/process.h | 5 | ||||
-rw-r--r-- | src/nvim/main.c | 17 | ||||
-rw-r--r-- | src/nvim/os/pty_process_unix.c | 8 | ||||
-rw-r--r-- | src/nvim/ui_client.c | 5 |
8 files changed, 40 insertions, 11 deletions
diff --git a/src/nvim/channel.c b/src/nvim/channel.c index f2e5a37b34..386ec832eb 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -377,6 +377,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader } else { has_out = rpc || callback_reader_set(chan->on_data); has_err = callback_reader_set(chan->on_stderr); + proc->fwd_err = chan->on_stderr.fwd_err; } 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); 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 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); diff --git a/src/nvim/channel.h b/src/nvim/channel.h index d7f32d8988..5743eaead5 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -66,6 +66,7 @@ typedef struct { garray_T buffer; bool eof; bool buffered; + bool fwd_err; const char *type; } CallbackReader; @@ -73,6 +74,7 @@ typedef struct { .self = NULL, \ .buffer = GA_EMPTY_INIT_VALUE, \ .buffered = false, \ + .fwd_err = false, \ .type = NULL }) static inline bool callback_reader_set(CallbackReader reader) { diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 811d96ff93..10a09275d9 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -85,6 +85,9 @@ int libuv_process_spawn(LibuvProcess *uvproc) uvproc->uvstdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; uvproc->uvstdio[2].data.stream = STRUCT_CAST(uv_stream_t, &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; diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 2fa789ac9a..9dfd6f329a 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -43,6 +43,9 @@ static int exit_need_delay = 0; int process_spawn(Process *proc, bool in, bool out, bool err) FUNC_ATTR_NONNULL_ALL { + // forwarding stderr contradicts with processing it internally + assert(!(err && proc->fwd_err)); + if (in) { uv_pipe_init(&proc->loop->uv, &proc->in.uv.pipe, 0); } else { diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 26e03ff4f3..e0057faffb 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -38,7 +38,7 @@ struct process { /// Exit handler. If set, user must call process_free(). process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; - bool closed, detach, overlapped; + bool closed, detach, overlapped, fwd_err; MultiQueue *events; }; @@ -62,7 +62,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data) .closed = false, .internal_close_cb = NULL, .internal_exit_cb = NULL, - .detach = false + .detach = false, + .fwd_err = false, }; } diff --git a/src/nvim/main.c b/src/nvim/main.c index 9bb9eea4f6..953385836b 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -279,6 +279,15 @@ int main(int argc, char **argv) // argument list "global_alist". 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); TIME_MSG("init lua interpreter"); @@ -1455,14 +1464,6 @@ static void check_and_set_isatty(mparm_T *paramp) stdout_isatty = paramp->output_isatty = os_isatty(STDOUT_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"); } diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 143f0b3900..cd2150a6a6 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -168,6 +168,14 @@ static struct termios termios_default; /// @param tty_fd TTY file descriptor, or -1 if not in a terminal. 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) { return; } diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index 2821054909..ff82fd3239 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -41,8 +41,11 @@ uint64_t ui_client_start_server(int argc, char **argv) } args[args_idx++] = NULL; + CallbackReader on_err = CALLBACK_READER_INIT; + on_err.fwd_err = true; + Channel *channel = channel_job_start(args, CALLBACK_READER_INIT, - CALLBACK_READER_INIT, CALLBACK_NONE, + on_err, CALLBACK_NONE, false, true, true, false, kChannelStdinPipe, NULL, 0, 0, NULL, &exit_status); if (ui_client_forward_stdin) { |