Merge pull request #1798 from oni-link/fix.job.wait

job.c: Prevent early return from job_wait().
This commit is contained in:
Justin M. Keyes 2015-01-18 13:23:17 -05:00
commit c7f4e55362
2 changed files with 160 additions and 1 deletions

View File

@ -310,8 +310,15 @@ int job_wait(Job *job, int ms) FUNC_ATTR_NONNULL_ALL
// we'll assume that a user frantically hitting interrupt doesn't like // we'll assume that a user frantically hitting interrupt doesn't like
// the current job. Signal that it has to be killed. // the current job. Signal that it has to be killed.
if (got_int) { if (got_int) {
got_int = false;
job_stop(job); job_stop(job);
event_poll(0); if (ms == -1) {
// We can only return, if all streams/handles are closed and the job
// exited.
event_poll_until(-1, job->refcount == 1);
} else {
event_poll(0);
}
} }
if (job->refcount == 1) { if (job->refcount == 1) {

View File

@ -6,6 +6,8 @@ local helpers = require('test.functional.helpers')
local eq, clear, eval, feed, nvim = local eq, clear, eval, feed, nvim =
helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.nvim helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.nvim
local Screen = require('test.functional.ui.screen')
local function create_file_with_nuls(name) local function create_file_with_nuls(name)
return function() return function()
@ -42,6 +44,81 @@ describe('system()', function()
eq(127, eval('v:shell_error')) eq(127, eval('v:shell_error'))
end) end)
describe('executes shell function', function()
local screen
before_each(function()
clear()
screen = Screen.new()
screen:attach()
end)
after_each(function()
screen:detach()
end)
it('`echo` and waits for its return', function()
feed(':call system("echo")<cr>')
screen:expect([[
^ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
:call system("echo") |
]])
end)
it('`yes` and is directly interrupted with CTRL-C', function()
feed(':call system("yes")<cr><c-c>')
screen:expect([[
^ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
Type :quit<Enter> to exit Vim |
]])
end)
it('`yes` and is a little bit later interrupted with CTRL-C', function()
feed(':call system("yes")<cr>')
feed('<c-c>')
screen:expect([[
^ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
Type :quit<Enter> to exit Vim |
]])
end)
end)
describe('passing no input', function() describe('passing no input', function()
it('returns the program output', function() it('returns the program output', function()
eq("echoed", eval('system("echo -n echoed")')) eq("echoed", eval('system("echo -n echoed")'))
@ -137,6 +214,81 @@ describe('systemlist()', function()
eq(127, eval('v:shell_error')) eq(127, eval('v:shell_error'))
end) end)
describe('exectues shell function', function()
local screen
before_each(function()
clear()
screen = Screen.new()
screen:attach()
end)
after_each(function()
screen:detach()
end)
it('`echo` and waits for its return', function()
feed(':call systemlist("echo")<cr>')
screen:expect([[
^ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
:call systemlist("echo") |
]])
end)
it('`yes` and is directly interrupted with CTRL-C', function()
feed(':call systemlist("echo")<cr><c-c>')
screen:expect([[
^ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
Type :quit<Enter> to exit Vim |
]])
end)
it('`yes` and is a little bit later interrupted with CTRL-C', function()
feed(':call systemlist("echo")<cr>')
feed('<c-c>')
screen:expect([[
^ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
Type :quit<Enter> to exit Vim |
]])
end)
end)
describe('passing string with linefeed characters as input', function() describe('passing string with linefeed characters as input', function()
it('splits the output on linefeed characters', function() it('splits the output on linefeed characters', function()
eq({'abc', 'def', 'ghi'}, eval([[systemlist("cat -", "abc\ndef\nghi")]])) eq({'abc', 'def', 'ghi'}, eval([[systemlist("cat -", "abc\ndef\nghi")]]))