diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 7449ac637c..1b279f18f5 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -244,6 +244,9 @@ static int shell(const char *cmd, job_stop(job); return -1; } + // close the input stream after everything is written + job_write_cb(job, shell_write_cb); + } else { // close the input stream, let the process know that no more input is // coming job_close_in(job); @@ -447,3 +450,9 @@ static void write_output(char *output, size_t remaining) curbuf->b_no_eol_lnum = 0; } } + +static void shell_write_cb(WStream *wstream, void *data, int status) +{ + Job *job = data; + job_close_in(job); +} diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua index b36b4691b9..91e115aedf 100644 --- a/test/functional/shell/viml_system_spec.lua +++ b/test/functional/shell/viml_system_spec.lua @@ -3,8 +3,8 @@ -- - `systemlist()` local helpers = require('test.functional.helpers') -local eq, clear, eval, feed = - helpers.eq, helpers.clear, helpers.eval, helpers.feed +local eq, clear, eval, feed, nvim = + helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.nvim local function create_file_with_nuls(name) @@ -55,6 +55,21 @@ describe('system()', function() end) end) + describe('passing a lot of input', function() + it('returns the program output', function() + local input = {} + -- write more than 1mb of data, which should be enough to overcome + -- the os buffer limit and force multiple event loop iterations to write + -- everything + for i = 1, 0xffff do + input[#input + 1] = '01234567890ABCDEFabcdef' + end + input = table.concat(input, '\n') + nvim('set_var', 'input', input) + eq(input, eval('system("cat -", g:input)')) + end) + end) + describe('passing number as input', function() it('stringifies the input', function() eq('1', eval('system("cat", 1)')) @@ -129,6 +144,17 @@ describe('systemlist()', function() end) end) + describe('passing a lot of input', function() + it('returns the program output', function() + local input = {} + for i = 1, 0xffff do + input[#input + 1] = '01234567890ABCDEFabcdef' + end + nvim('set_var', 'input', input) + eq(input, eval('systemlist("cat -", g:input)')) + end) + end) + describe('with output containing NULs', function() local fname = 'Xtest'