summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-09-01 14:35:22 +0200
committerBram Moolenaar <Bram@vim.org>2016-09-01 14:35:22 +0200
commitd8b554904d18fe19bd9fa79dbda880845cb017d2 (patch)
tree7bcf2fe534f819d804f078e8a9a56bace1682958
parentf37506f60f87d52a9e8850e30067645e2b13783c (diff)
patch 7.4.2297v7.4.2297
Problem: When starting a job that reads from a buffer and reaching the end, the job hangs. Solution: Close the pipe or socket when all lines were read.
-rw-r--r--src/channel.c5
-rw-r--r--src/testdir/test_channel.vim40
-rw-r--r--src/version.c2
3 files changed, 46 insertions, 1 deletions
diff --git a/src/channel.c b/src/channel.c
index 25406e184e..dbed659329 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1424,11 +1424,14 @@ channel_write_in(channel_T *channel)
ch_logn(channel, "written %d lines to channel", written);
in_part->ch_buf_top = lnum;
- if (lnum > buf->b_ml.ml_line_count)
+ if (lnum > buf->b_ml.ml_line_count || lnum > in_part->ch_buf_bot)
{
/* Writing is done, no longer need the buffer. */
in_part->ch_bufref.br_buf = NULL;
ch_log(channel, "Finished writing all lines to channel");
+
+ /* Close the pipe/socket, so that the other side gets EOF. */
+ may_close_part(&channel->CH_IN_FD);
}
else
ch_logn(channel, "Still %d more lines to write",
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index a038d4a2df..6bea0e8b96 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -792,6 +792,46 @@ func Test_pipe_from_buffer_nr()
call Run_test_pipe_from_buffer(0)
endfunc
+func Run_pipe_through_sort(all)
+ if !executable('sort') || !has('job')
+ return
+ endif
+ split sortin
+ call setline(1, ['ccc', 'aaa', 'ddd', 'bbb', 'eee'])
+ let options = {'in_io': 'buffer', 'in_name': 'sortin',
+ \ 'out_io': 'buffer', 'out_name': 'sortout'}
+ if !a:all
+ let options.in_top = 2
+ let options.in_bot = 4
+ endif
+ let g:job = job_start('sort', options)
+ call assert_equal("run", job_status(g:job))
+ call WaitFor('job_status(g:job) == "dead"')
+ call assert_equal("dead", job_status(g:job))
+ sp sortout
+ call assert_equal('Reading from channel output...', getline(1))
+ if a:all
+ call assert_equal(['aaa', 'bbb', 'ccc', 'ddd', 'eee'], getline(2, 6))
+ else
+ call assert_equal(['aaa', 'bbb', 'ddd'], getline(2, 4))
+ endif
+
+ call job_stop(g:job)
+ unlet g:job
+ bwipe! sortin
+ bwipe! sortout
+endfunc
+
+func Test_pipe_through_sort_all()
+ call ch_log('Test_pipe_through_sort_all()')
+ call Run_pipe_through_sort(1)
+endfunc
+
+func Test_pipe_through_sort_some()
+ call ch_log('Test_pipe_through_sort_some()')
+ call Run_pipe_through_sort(0)
+endfunc
+
func Test_pipe_to_nameless_buffer()
if !has('job')
return
diff --git a/src/version.c b/src/version.c
index 95eec668fd..3162f330fb 100644
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2297,
+/**/
2296,
/**/
2295,