aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2015-05-27 09:34:40 -0400
committerJustin M. Keyes <justinkz@gmail.com>2015-05-27 09:34:40 -0400
commit3dd166b20387607d73fee01507e7c9ddcfa9bcd4 (patch)
tree5647ea22f1e7fd35b56df9893ebfd5717481d857
parent5a9ad68b258f33ebd7fa0a5da47b308f50f1e5e7 (diff)
parentb2c400b3f2354b2765e1d6f3b5ce4b11f2ab75a3 (diff)
downloadrneovim-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.c1
-rw-r--r--src/nvim/main.c16
-rw-r--r--src/nvim/misc1.c1
-rw-r--r--src/nvim/os/event.c2
-rw-r--r--src/nvim/os/input.c13
-rw-r--r--src/nvim/os/os.h1
-rw-r--r--src/nvim/os/stream.c30
-rw-r--r--src/nvim/os_unix.c1
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();