aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/shell.c
diff options
context:
space:
mode:
authoroni-link <knil.ino@gmail.com>2015-08-11 13:40:07 +0200
committerJustin M. Keyes <justinkz@gmail.com>2015-08-11 09:36:06 -0400
commitc6af09c5663f31a43bbf02f16089437fe41574f7 (patch)
tree806945c59fb2135270147426a3ebf63d47b0609a /src/nvim/os/shell.c
parent7d9472ab1b7dc4eb2bb838fb8febcc7a1aab649d (diff)
downloadrneovim-c6af09c5663f31a43bbf02f16089437fe41574f7.tar.gz
rneovim-c6af09c5663f31a43bbf02f16089437fe41574f7.tar.bz2
rneovim-c6af09c5663f31a43bbf02f16089437fe41574f7.zip
shell.c: A full RBuffer with no NL can freeze shell output. #3156
out_data_cb() can return without emptying the full RBuffer (no NL was seen). Because the shell output stream is stopped until space in the Rbuffer is freed up, no more shell output is written. To prevent this, output the full RBuffer when write_output() did not write anything. write_output() can also process the same RBuffer content more than once, if no NL was seen. To prevent NUL bytes from producing new lines (if lines are not written to a buffer), translate NUL to SOH(1). Fixes #2983
Diffstat (limited to 'src/nvim/os/shell.c')
-rw-r--r--src/nvim/os/shell.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index e0d67d4951..b9c5db4261 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -297,14 +297,22 @@ static void system_data_cb(Stream *stream, RBuffer *buf, void *data, bool eof)
static void out_data_cb(Stream *stream, RBuffer *buf, void *data, bool eof)
{
- RBUFFER_UNTIL_EMPTY(buf, ptr, len) {
- size_t written = write_output(ptr, len, false,
- eof && len <= rbuffer_size(buf));
- if (written) {
- rbuffer_consumed(buf, written);
- } else {
- break;
- }
+ size_t cnt;
+ char *ptr = rbuffer_read_ptr(buf, &cnt);
+
+ if (!cnt) {
+ return;
+ }
+
+ size_t written = write_output(ptr, cnt, false, eof);
+ // No output written, force emptying the Rbuffer if it is full.
+ if (!written && rbuffer_size(buf) == rbuffer_capacity(buf)) {
+ screen_del_lines(0, 0, 1, (int)Rows, NULL);
+ screen_puts_len((char_u *)ptr, (int)cnt, (int)Rows - 1, 0, 0);
+ written = cnt;
+ }
+ if (written) {
+ rbuffer_consumed(buf, written);
}
}
@@ -421,6 +429,7 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
if (!output) {
return 0;
}
+ char replacement_NUL = to_buffer ? NL : 1;
char *start = output;
size_t off = 0;
@@ -428,9 +437,10 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
while (off < remaining) {
if (output[off] == NL) {
// Insert the line
- output[off] = NUL;
if (to_buffer) {
- ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false);
+ output[off] = NUL;
+ ml_append(curwin->w_cursor.lnum++, (char_u *)output, (int)off + 1,
+ false);
} else {
screen_del_lines(0, 0, 1, (int)Rows, NULL);
screen_puts_len((char_u *)output, (int)off, lastrow, 0, 0);
@@ -444,7 +454,7 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
if (output[off] == NUL) {
// Translate NUL to NL
- output[off] = NL;
+ output[off] = replacement_NUL;
}
off++;
}