From 9706664b8827614817a43f3a4ac4b6ae8463a906 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 18 Oct 2016 14:39:08 +0200 Subject: system('foo &', 'bar'): Show error, don't crash. Closes #3529 Closes #5241 In Vim, :echo system('cat - &', 'foo') works because for both system() and :! Vim writes input to a temp file and uses shell syntax to redirect the file to the backgrounded `cat` (get_cmd_output() .. make_filter_cmd()). In Nvim, :echo system('cat - &', 'foo') fails because we write the input directly via pipes (shell.c:do_os_system()), but (per POSIX[1]) backgrounded process input stream is redirected from /dev/null (unless overridden by shell redirection; supported only by some shells [2]), so our writes are ignored, the process exits quickly, and if we are writing data larger than the buffer size we'll see EPIPE. This still works: :%w !tee > foo1358.txt & but this does not: :%w !tee foo1358.txt & though it *should* (why doesn't it?) because we still do the temp file dance in do_bang() .. do_filter(). [1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_03_02 [2] http://unix.stackexchange.com/a/71218 --- src/nvim/event/rstream.c | 4 ++-- src/nvim/os/shell.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 5126dfd84e..92efc9fa2e 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -112,8 +112,8 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf) // to `alloc_cb` will return the same unused pointer(`rbuffer_produced` // won't be called) && cnt != 0) { - DLOG("Closing Stream(%p) because of %s(%zd)", stream, - uv_strerror((int)cnt), cnt); + DLOG("Closing Stream (%p): %s (%s)", stream, + uv_err_name((int)cnt), os_strerror((int)cnt)); // Read error or EOF, either way stop the stream and invoke the callback // with eof == true uv_read_stop(uvstream); diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index e9a3dcbff8..18ee008d66 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -545,6 +545,16 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer, static void shell_write_cb(Stream *stream, void *data, int status) { + if (status) { + // Can happen if system() tries to send input to a shell command that was + // backgrounded (:call system("cat - &", "foo")). #3529 #5241 + EMSG2(_("E5677: Error writing input to shell-command: %s"), + uv_err_name(status)); + } + if (stream->closed) { // Process may have exited before this write. + ELOG("stream was already closed"); + return; + } stream_close(stream, NULL, NULL); } -- cgit