mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #2598 'set stdin as "blocking" on exit'
This commit is contained in:
commit
3dd166b203
@ -820,6 +820,7 @@ err_closing:
|
|||||||
if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1)
|
if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1)
|
||||||
PERROR(_("cs_create_connection exec failed"));
|
PERROR(_("cs_create_connection exec failed"));
|
||||||
|
|
||||||
|
stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
|
||||||
exit(127);
|
exit(127);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
default: /* parent. */
|
default: /* parent. */
|
||||||
|
@ -271,17 +271,15 @@ int main(int argc, char **argv)
|
|||||||
|| params.output_isatty || params.err_isatty);
|
|| params.output_isatty || params.err_isatty);
|
||||||
|
|
||||||
if (reading_input) {
|
if (reading_input) {
|
||||||
// Its possible that one of the startup commands(arguments, sourced scripts
|
// One of the startup commands (arguments, sourced scripts or plugins) may
|
||||||
// or plugins) will prompt the user, so start reading from a tty stream
|
// prompt the user, so start reading from a tty now.
|
||||||
// now.
|
|
||||||
int fd = fileno(stdin);
|
int fd = fileno(stdin);
|
||||||
if (!params.input_isatty || params.edit_type == EDIT_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
|
// 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 |
|
// read the "-" file (eg: cat file | nvim -)
|
||||||
// nvim -)
|
|
||||||
fd = params.err_isatty ? fileno(stderr) : fileno(stdout);
|
fd = params.err_isatty ? fileno(stderr) : fileno(stdout);
|
||||||
}
|
}
|
||||||
input_start_stdin(fd);
|
input_start(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// open terminals when opening files that start with term://
|
// open terminals when opening files that start with term://
|
||||||
@ -388,8 +386,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!params.headless) {
|
if (!params.headless) {
|
||||||
// Stop reading from stdin, the UI layer will take over now
|
// Stop reading from input stream, the UI layer will take over now.
|
||||||
input_stop_stdin();
|
input_stop();
|
||||||
ui_builtin_start();
|
ui_builtin_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2679,6 +2679,7 @@ void preserve_exit(void)
|
|||||||
|
|
||||||
// Prevent repeated calls into this method.
|
// Prevent repeated calls into this method.
|
||||||
if (really_exiting) {
|
if (really_exiting) {
|
||||||
|
stream_set_blocking(input_global_fd(), true); //normalize stream (#2598)
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ void event_teardown(void)
|
|||||||
// is required because the `process_events_from` above may call `event_push`
|
// is required because the `process_events_from` above may call `event_push`
|
||||||
// which will set the stop_flag to 1(uv_stop)
|
// which will set the stop_flag to 1(uv_stop)
|
||||||
uv_default_loop()->stop_flag = 0;
|
uv_default_loop()->stop_flag = 0;
|
||||||
input_stop_stdin();
|
input_stop();
|
||||||
channel_teardown();
|
channel_teardown();
|
||||||
job_teardown();
|
job_teardown();
|
||||||
server_teardown();
|
server_teardown();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
@ -34,6 +33,7 @@ typedef enum {
|
|||||||
static RStream *read_stream = NULL;
|
static RStream *read_stream = NULL;
|
||||||
static RBuffer *read_buffer = NULL, *input_buffer = NULL;
|
static RBuffer *read_buffer = NULL, *input_buffer = NULL;
|
||||||
static bool input_eof = false;
|
static bool input_eof = false;
|
||||||
|
static int global_fd = 0;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/input.c.generated.h"
|
# 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);
|
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) {
|
if (read_stream) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global_fd = fd;
|
||||||
read_buffer = rbuffer_new(READ_BUFFER_SIZE);
|
read_buffer = rbuffer_new(READ_BUFFER_SIZE);
|
||||||
read_stream = rstream_new(read_cb, read_buffer, NULL);
|
read_stream = rstream_new(read_cb, read_buffer, NULL);
|
||||||
rstream_set_file(read_stream, fd);
|
rstream_set_file(read_stream, fd);
|
||||||
rstream_start(read_stream);
|
rstream_start(read_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_stop_stdin(void)
|
void input_stop(void)
|
||||||
{
|
{
|
||||||
if (!read_stream) {
|
if (!read_stream) {
|
||||||
return;
|
return;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# include "os/mem.h.generated.h"
|
# include "os/mem.h.generated.h"
|
||||||
# include "os/env.h.generated.h"
|
# include "os/env.h.generated.h"
|
||||||
# include "os/users.h.generated.h"
|
# include "os/users.h.generated.h"
|
||||||
|
# include "os/stream.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // NVIM_OS_OS_H
|
#endif // NVIM_OS_OS_H
|
||||||
|
30
src/nvim/os/stream.c
Normal file
30
src/nvim/os/stream.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -181,6 +181,7 @@ void mch_exit(int r)
|
|||||||
ml_close_all(TRUE); /* remove all memfiles */
|
ml_close_all(TRUE); /* remove all memfiles */
|
||||||
|
|
||||||
event_teardown();
|
event_teardown();
|
||||||
|
stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
|
||||||
|
|
||||||
#ifdef EXITFREE
|
#ifdef EXITFREE
|
||||||
free_all_mem();
|
free_all_mem();
|
||||||
|
Loading…
Reference in New Issue
Block a user