diff options
Diffstat (limited to 'src/nvim/os')
| -rw-r--r-- | src/nvim/os/input.c | 2 | ||||
| -rw-r--r-- | src/nvim/os/pty_process_unix.c | 31 | ||||
| -rw-r--r-- | src/nvim/os/pty_process_win.c | 12 | ||||
| -rw-r--r-- | src/nvim/os/shell.c | 31 | 
4 files changed, 39 insertions, 37 deletions
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 31e06ce404..7d6f2abd7f 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -37,7 +37,7 @@ typedef enum {  static Stream read_stream = {.closed = true};  static RBuffer *input_buffer = NULL;  static bool input_eof = false; -static int global_fd = 0; +static int global_fd = -1;  static int events_enabled = 0;  static bool blocking = false; diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index ee3ab96a83..53301e4b53 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -36,23 +36,36 @@  # include "os/pty_process_unix.c.generated.h"  #endif +/// termios saved at startup (for TUI) or initialized by pty_process_spawn(). +static struct termios termios_default; + +/// Saves the termios properties associated with `tty_fd`. +/// +/// @param tty_fd   TTY file descriptor, or -1 if not in a terminal. +void pty_process_save_termios(int tty_fd) +{ +  if (tty_fd == -1 || tcgetattr(tty_fd, &termios_default) != 0) { +    return; +  } +} +  /// @returns zero on success, or negative error code  int pty_process_spawn(PtyProcess *ptyproc)    FUNC_ATTR_NONNULL_ALL  { -  static struct termios termios; -  if (!termios.c_cflag) { -    init_termios(&termios); +  if (!termios_default.c_cflag) { +    // TODO(jkeyes): We could pass NULL to forkpty() instead ... +    init_termios(&termios_default);    }    int status = 0;  // zero or negative error code (libuv convention)    Process *proc = (Process *)ptyproc; -  assert(!proc->err); +  assert(proc->err.closed);    uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD);    ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 };    uv_disable_stdio_inheritance();    int master; -  int pid = forkpty(&master, NULL, &termios, &ptyproc->winsize); +  int pid = forkpty(&master, NULL, &termios_default, &ptyproc->winsize);    if (pid < 0) {      status = -errno; @@ -83,12 +96,12 @@ int pty_process_spawn(PtyProcess *ptyproc)      goto error;    } -  if (proc->in -      && (status = set_duplicating_descriptor(master, &proc->in->uv.pipe))) { +  if (!proc->in.closed +      && (status = set_duplicating_descriptor(master, &proc->in.uv.pipe))) {      goto error;    } -  if (proc->out -      && (status = set_duplicating_descriptor(master, &proc->out->uv.pipe))) { +  if (!proc->out.closed +      && (status = set_duplicating_descriptor(master, &proc->out.uv.pipe))) {      goto error;    } diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index ef8a699c56..3c4839a076 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -44,7 +44,7 @@ int pty_process_spawn(PtyProcess *ptyproc)    wchar_t *cwd = NULL;    const char *emsg = NULL; -  assert(!proc->err); +  assert(proc->err.closed);    cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err);    if (cfg == NULL) { @@ -71,20 +71,20 @@ int pty_process_spawn(PtyProcess *ptyproc)      goto cleanup;    } -  if (proc->in != NULL) { +  if (!proc->in.closed) {      in_req = xmalloc(sizeof(uv_connect_t));      uv_pipe_connect(          in_req, -        &proc->in->uv.pipe, +        &proc->in.uv.pipe,          in_name,          pty_process_connect_cb);    } -  if (proc->out != NULL) { +  if (!proc->out.closed) {      out_req = xmalloc(sizeof(uv_connect_t));      uv_pipe_connect(          out_req, -        &proc->out->uv.pipe, +        &proc->out.uv.pipe,          out_name,          pty_process_connect_cb);    } @@ -228,7 +228,7 @@ static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)    PtyProcess *ptyproc = wait_eof_timer->data;    Process *proc = (Process *)ptyproc; -  if (!proc->out || !uv_is_readable(proc->out->uvstream)) { +  if (proc->out.closed || !uv_is_readable(proc->out.uvstream)) {      uv_timer_stop(&ptyproc->wait_eof_timer);      pty_process_finish2(ptyproc);    } diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 32e9a70e57..e32c6e05d2 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -207,16 +207,12 @@ static int do_os_system(char **argv,    char prog[MAXPATHL];    xstrlcpy(prog, argv[0], MAXPATHL); -  Stream in, out, err;    LibuvProcess uvproc = libuv_process_init(&main_loop, &buf);    Process *proc = &uvproc.process;    MultiQueue *events = multiqueue_new_child(main_loop.events);    proc->events = events;    proc->argv = argv; -  proc->in = input != NULL ? &in : NULL; -  proc->out = &out; -  proc->err = &err; -  int status = process_spawn(proc); +  int status = process_spawn(proc, input != NULL, true, true);    if (status) {      loop_poll_events(&main_loop, 0);      // Failed, probably 'shell' is not executable. @@ -231,32 +227,29 @@ static int do_os_system(char **argv,      return -1;    } -  // We want to deal with stream events as fast a possible while queueing -  // process events, so reset everything to NULL. It prevents closing the +  // Note: unlike process events, stream events are not queued, as we want to +  // deal with stream events as fast a possible.  It prevents closing the    // streams while there's still data in the OS buffer (due to the process    // exiting before all data is read).    if (input != NULL) { -    proc->in->events = NULL; -    wstream_init(proc->in, 0); +    wstream_init(&proc->in, 0);    } -  proc->out->events = NULL; -  rstream_init(proc->out, 0); -  rstream_start(proc->out, data_cb, &buf); -  proc->err->events = NULL; -  rstream_init(proc->err, 0); -  rstream_start(proc->err, data_cb, &buf); +  rstream_init(&proc->out, 0); +  rstream_start(&proc->out, data_cb, &buf); +  rstream_init(&proc->err, 0); +  rstream_start(&proc->err, data_cb, &buf);    // write the input, if any    if (input) {      WBuffer *input_buffer = wstream_new_buffer((char *) input, len, 1, NULL); -    if (!wstream_write(&in, input_buffer)) { +    if (!wstream_write(&proc->in, input_buffer)) {        // couldn't write, stop the process and tell the user about it        process_stop(proc);        return -1;      }      // close the input stream after everything is written -    wstream_set_write_cb(&in, shell_write_cb, NULL); +    wstream_set_write_cb(&proc->in, shell_write_cb, NULL);    }    // Invoke busy_start here so LOOP_PROCESS_EVENTS_UNTIL will not change the @@ -684,10 +677,6 @@ static void shell_write_cb(Stream *stream, void *data, int status)      msg_schedule_emsgf(_("E5677: Error writing input to shell-command: %s"),                         uv_err_name(status));    } -  if (stream->closed) {  // Process may have exited before this write. -    WLOG("stream was already closed"); -    return; -  }    stream_close(stream, NULL, NULL);  }  | 
