# HG changeset patch # User Christian Brabandt # Date 1475523904 -7200 # Node ID 920c73a27ddaf508908408cf1f515cc66346fbb4 # Parent add2fae6e54b7c59f7749c0434bcd094b5d9ab0b commit https://github.com/vim/vim/commit/ec68a99464055029c01082762517e97245ddae0c Author: Bram Moolenaar Date: Mon Oct 3 21:37:41 2016 +0200 patch 8.0.0022 Problem: If a channel in NL mode is missing the NL at the end the remaining characters are dropped. Solution: When the channel is closed use the remaining text. (Ozaki Kiichi) diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -2355,8 +2355,9 @@ may_invoke_callback(channel_T *channel, typval_T *listtv = NULL; typval_T argv[CH_JSON_MAX_ARGS]; int seq_nr = -1; - ch_mode_T ch_mode = channel->ch_part[part].ch_mode; - cbq_T *cbhead = &channel->ch_part[part].ch_cb_head; + chanpart_T *ch_part = &channel->ch_part[part]; + ch_mode_T ch_mode = ch_part->ch_mode; + cbq_T *cbhead = &ch_part->ch_cb_head; cbq_T *cbitem; char_u *callback = NULL; partial_T *partial = NULL; @@ -2376,10 +2377,10 @@ may_invoke_callback(channel_T *channel, callback = cbitem->cq_callback; partial = cbitem->cq_partial; } - else if (channel->ch_part[part].ch_callback != NULL) + else if (ch_part->ch_callback != NULL) { - callback = channel->ch_part[part].ch_callback; - partial = channel->ch_part[part].ch_partial; + callback = ch_part->ch_callback; + partial = ch_part->ch_partial; } else { @@ -2387,11 +2388,11 @@ may_invoke_callback(channel_T *channel, partial = channel->ch_partial; } - buffer = channel->ch_part[part].ch_bufref.br_buf; - if (buffer != NULL && !bufref_valid(&channel->ch_part[part].ch_bufref)) + buffer = ch_part->ch_bufref.br_buf; + if (buffer != NULL && !bufref_valid(&ch_part->ch_bufref)) { /* buffer was wiped out */ - channel->ch_part[part].ch_bufref.br_buf = NULL; + ch_part->ch_bufref.br_buf = NULL; buffer = NULL; } @@ -2452,7 +2453,7 @@ may_invoke_callback(channel_T *channel, if (ch_mode == MODE_NL) { - char_u *nl; + char_u *nl = NULL; char_u *buf; readq_T *node; @@ -2465,10 +2466,25 @@ may_invoke_callback(channel_T *channel, if (nl != NULL) break; if (channel_collapse(channel, part, TRUE) == FAIL) + { + if (ch_part->ch_fd == INVALID_FD && node->rq_buflen > 0) + break; return FALSE; /* incomplete message */ + } } buf = node->rq_buffer; + if (nl == NULL) + { + /* Flush remaining message that is missing a NL. */ + buf = vim_realloc(buf, node->rq_buflen + 1); + if (buf == NULL) + return FALSE; + node->rq_buffer = buf; + nl = buf + node->rq_buflen++; + *nl = NUL; + } + /* Convert NUL to NL, the internal representation. */ for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) if (*p == NUL) diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -1484,6 +1484,27 @@ func Test_raw_passes_nul() bwipe! endfunc +func MyLineCountCb(ch, msg) + let g:linecount += 1 +endfunc + +func Test_read_nonl_line() + if !has('job') + return + endif + + let g:linecount = 0 + if has('win32') + " workaround: 'shellescape' does improper escaping double quotes + let arg = 'import sys;sys.stdout.write(\"1\n2\n3\")' + else + let arg = 'import sys;sys.stdout.write("1\n2\n3")' + endif + call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'}) + call WaitFor('3 <= g:linecount') + call assert_equal(3, g:linecount) +endfunc + function Ch_test_close_lambda(port) let handle = ch_open('localhost:' . a:port, s:chopt) if ch_status(handle) == "fail" diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 22, +/**/ 21, /**/ 20,