diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2015-05-27 09:34:40 -0400 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2015-05-27 09:34:40 -0400 |
commit | 3dd166b20387607d73fee01507e7c9ddcfa9bcd4 (patch) | |
tree | 5647ea22f1e7fd35b56df9893ebfd5717481d857 | |
parent | 5a9ad68b258f33ebd7fa0a5da47b308f50f1e5e7 (diff) | |
parent | b2c400b3f2354b2765e1d6f3b5ce4b11f2ab75a3 (diff) | |
download | rneovim-3dd166b20387607d73fee01507e7c9ddcfa9bcd4.tar.gz rneovim-3dd166b20387607d73fee01507e7c9ddcfa9bcd4.tar.bz2 rneovim-3dd166b20387607d73fee01507e7c9ddcfa9bcd4.zip |
Merge #2598 'set stdin as "blocking" on exit'
-rw-r--r-- | src/nvim/if_cscope.c | 1 | ||||
-rw-r--r-- | src/nvim/main.c | 16 | ||||
-rw-r--r-- | src/nvim/misc1.c | 1 | ||||
-rw-r--r-- | src/nvim/os/event.c | 2 | ||||
-rw-r--r-- | src/nvim/os/input.c | 13 | ||||
-rw-r--r-- | src/nvim/os/os.h | 1 | ||||
-rw-r--r-- | src/nvim/os/stream.c | 30 | ||||
-rw-r--r-- | src/nvim/os_unix.c | 1 |
8 files changed, 52 insertions, 13 deletions
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 407709866c..99926ecf16 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -820,6 +820,7 @@ err_closing: if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) PERROR(_("cs_create_connection exec failed")); + stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) exit(127); /* NOTREACHED */ default: /* parent. */ diff --git a/src/nvim/main.c b/src/nvim/main.c index 5f0372f30e..fc72039b5f 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -271,17 +271,15 @@ int main(int argc, char **argv) || params.output_isatty || params.err_isatty); if (reading_input) { - // Its possible that one of the startup commands(arguments, sourced scripts - // or plugins) will prompt the user, so start reading from a tty stream - // now. + // One of the startup commands (arguments, sourced scripts or plugins) may + // prompt the user, so start reading from a tty now. int fd = fileno(stdin); if (!params.input_isatty || params.edit_type == EDIT_STDIN) { - // use stderr or stdout since stdin is not a tty and/or could be used to - // read the file we'll edit when the "-" argument is given(eg: cat file | - // nvim -) + // Use stderr or stdout since stdin is not a tty and/or could be used to + // read the "-" file (eg: cat file | nvim -) fd = params.err_isatty ? fileno(stderr) : fileno(stdout); } - input_start_stdin(fd); + input_start(fd); } // open terminals when opening files that start with term:// @@ -388,8 +386,8 @@ int main(int argc, char **argv) } if (!params.headless) { - // Stop reading from stdin, the UI layer will take over now - input_stop_stdin(); + // Stop reading from input stream, the UI layer will take over now. + input_stop(); ui_builtin_start(); } diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 3ae3d6e30e..0737caec5d 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2679,6 +2679,7 @@ void preserve_exit(void) // Prevent repeated calls into this method. if (really_exiting) { + stream_set_blocking(input_global_fd(), true); //normalize stream (#2598) exit(2); } diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c index 0560da1e2e..b0bd7ca55a 100644 --- a/src/nvim/os/event.c +++ b/src/nvim/os/event.c @@ -73,7 +73,7 @@ void event_teardown(void) // is required because the `process_events_from` above may call `event_push` // which will set the stop_flag to 1(uv_stop) uv_default_loop()->stop_flag = 0; - input_stop_stdin(); + input_stop(); channel_teardown(); job_teardown(); server_teardown(); diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 486171b48a..74a5d3bc2e 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -1,6 +1,5 @@ #include <assert.h> #include <string.h> -#include <stdint.h> #include <stdbool.h> #include <uv.h> @@ -34,6 +33,7 @@ typedef enum { static RStream *read_stream = NULL; static RBuffer *read_buffer = NULL, *input_buffer = NULL; static bool input_eof = false; +static int global_fd = 0; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/input.c.generated.h" @@ -46,19 +46,26 @@ void input_init(void) input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN); } -void input_start_stdin(int fd) +/// Gets the file from which input was gathered at startup. +int input_global_fd(void) +{ + return global_fd; +} + +void input_start(int fd) { if (read_stream) { return; } + global_fd = fd; read_buffer = rbuffer_new(READ_BUFFER_SIZE); read_stream = rstream_new(read_cb, read_buffer, NULL); rstream_set_file(read_stream, fd); rstream_start(read_stream); } -void input_stop_stdin(void) +void input_stop(void) { if (!read_stream) { return; diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 69bd1ff4fd..3dd099890c 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -12,6 +12,7 @@ # include "os/mem.h.generated.h" # include "os/env.h.generated.h" # include "os/users.h.generated.h" +# include "os/stream.h.generated.h" #endif #endif // NVIM_OS_OS_H diff --git a/src/nvim/os/stream.c b/src/nvim/os/stream.c new file mode 100644 index 0000000000..0c448872c3 --- /dev/null +++ b/src/nvim/os/stream.c @@ -0,0 +1,30 @@ +// Functions for working with stdio streams (as opposed to RStream/WStream). + +#include <stdio.h> +#include <stdbool.h> + +#include <uv.h> + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/stream.c.generated.h" +#endif + +/// Sets the stream associated with `fd` to "blocking" mode. +/// +/// @return `0` on success, or `-errno` on failure. +int stream_set_blocking(int fd, bool blocking) +{ + // Private loop to avoid conflict with existing watcher(s): + // uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed. + uv_loop_t loop; + uv_pipe_t stream; + uv_loop_init(&loop); + uv_pipe_init(&loop, &stream, 0); + uv_pipe_open(&stream, fd); + int retval = uv_stream_set_blocking((uv_stream_t *)&stream, blocking); + uv_close((uv_handle_t *)&stream, NULL); + uv_run(&loop, UV_RUN_NOWAIT); // not necessary, but couldn't hurt. + uv_loop_close(&loop); + return retval; +} + diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index b2d5bae477..ccd0073db1 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -181,6 +181,7 @@ void mch_exit(int r) ml_close_all(TRUE); /* remove all memfiles */ event_teardown(); + stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) #ifdef EXITFREE free_all_mem(); |