aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/after_success.sh6
-rw-r--r--.travis.yml3
-rw-r--r--src/nvim/event/process.c25
-rw-r--r--test/functional/core/job_spec.lua (renamed from test/functional/job/job_spec.lua)49
-rw-r--r--test/functional/ui/output_spec.lua39
5 files changed, 98 insertions, 24 deletions
diff --git a/.ci/after_success.sh b/.ci/after_success.sh
index 580b988061..0215eb139b 100755
--- a/.ci/after_success.sh
+++ b/.ci/after_success.sh
@@ -3,8 +3,6 @@
set -e
set -o pipefail
-if [[ -n "${CI_TARGET}" ]]; then
- exit
+if [[ -n "${GCOV}" ]]; then
+ coveralls --gcov "$(which "${GCOV}")" --encoding iso-8859-1 || echo 'coveralls upload failed.'
fi
-
-[ "$USE_GCOV" = on ] && { coveralls --gcov "$(which "${GCOV}")" --encoding iso-8859-1 || echo 'coveralls upload failed.' ; }
diff --git a/.travis.yml b/.travis.yml
index 8334b03cdf..9d529c2632 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -61,6 +61,7 @@ matrix:
env: CI_TARGET=lint
- os: linux
compiler: gcc-5
+ env: GCOV=gcov-5 CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON"
- os: linux
compiler: gcc-5
env: FUNCTIONALTEST=functionaltest-lua
@@ -72,7 +73,7 @@ matrix:
env: BUILD_32BIT=ON
- os: linux
compiler: clang
- env: GCOV=llvm-cov CLANG_SANITIZER=ASAN_UBSAN CMAKE_FLAGS="$CMAKE_FLAGS -DUSE_GCOV=ON"
+ env: CLANG_SANITIZER=ASAN_UBSAN
- os: linux
compiler: clang
env: CLANG_SANITIZER=TSAN
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 1c4c9737c3..317e40e43a 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -116,23 +116,20 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
process_is_tearing_down = true;
kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data;
- if (proc->detach) {
+ if (proc->detach || proc->type == kProcessTypePty) {
// Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, 1, proc);
} else {
- if (proc->type == kProcessTypeUv) {
- uv_kill(proc->pid, SIGTERM);
- proc->term_sent = true;
- process_stop(proc);
- } else { // kProcessTypePty
- process_close_streams(proc);
- pty_process_close_master((PtyProcess *)proc);
- }
+ uv_kill(proc->pid, SIGTERM);
+ proc->term_sent = true;
+ process_stop(proc);
}
}
- // Wait until all children exit
- LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, kl_empty(loop->children));
+ // Wait until all children exit and all close events are processed.
+ LOOP_PROCESS_EVENTS_UNTIL(
+ loop, loop->events, -1,
+ kl_empty(loop->children) && queue_empty(loop->events));
pty_process_teardown(loop);
}
@@ -315,8 +312,10 @@ static void decref(Process *proc)
static void process_close(Process *proc)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (process_is_tearing_down && proc->detach && proc->closed) {
- // If a detached process dies while tearing down it might get closed twice.
+ if (process_is_tearing_down && (proc->detach || proc->type == kProcessTypePty)
+ && proc->closed) {
+ // If a detached/pty process dies while tearing down it might get closed
+ // twice.
return;
}
assert(!proc->closed);
diff --git a/test/functional/job/job_spec.lua b/test/functional/core/job_spec.lua
index b54d5166ac..61ecdd1835 100644
--- a/test/functional/job/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -1,4 +1,3 @@
-
local helpers = require('test.functional.helpers')(after_each)
local clear, eq, eval, execute, feed, insert, neq, next_msg, nvim,
nvim_dir, ok, source, write_file, mkdir, rmdir = helpers.clear,
@@ -120,7 +119,7 @@ describe('jobs', function()
{0, {'a', '', 'c', '', '', '', 'b', '', ''}}}, next_msg())
end)
- it('can preserve nuls', function()
+ it('can preserve NULs', function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
nvim('command', 'call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])')
eq({'notification', 'stdout', {0, {'\n123\n', 'abc\nxyz\n', ''}}},
@@ -144,7 +143,7 @@ describe('jobs', function()
eq({'notification', 'exit', {0, 0}}, next_msg())
end)
- it("won't allow jobsend with a job that closed stdin", function()
+ it("disallows jobsend on a job that closed stdin", function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
nvim('command', 'call jobclose(j, "stdin")')
eq(false, pcall(function()
@@ -152,12 +151,12 @@ describe('jobs', function()
end))
end)
- it('will not allow jobsend/stop on a non-existent job', function()
+ it('disallows jobsend/stop on a non-existent job', function()
eq(false, pcall(eval, "jobsend(-1, 'lol')"))
eq(false, pcall(eval, "jobstop(-1)"))
end)
- it('will not allow jobstop twice on the same job', function()
+ it('disallows jobstop twice on the same job', function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
neq(0, eval('j'))
eq(true, pcall(eval, "jobstop(j)"))
@@ -244,7 +243,7 @@ describe('jobs', function()
eq({'notification', 'exit', {45, 10}}, next_msg())
end)
- it('cant redefine callbacks being used by a job', function()
+ it('cannot redefine callbacks being used by a job', function()
local screen = Screen.new()
screen:attach()
local script = [[
@@ -467,3 +466,41 @@ describe('jobs', function()
end)
end)
end)
+
+describe("pty process teardown", function()
+ local screen
+ before_each(function()
+ clear()
+ screen = Screen.new(30, 6)
+ screen:attach()
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ end)
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("does not prevent/delay exit. #4798 #4900", function()
+ -- Use a nested nvim (in :term) to test without --headless.
+ execute(":terminal '"..helpers.nvim_prog
+ -- Use :term again in the _nested_ nvim to get a PTY process.
+ -- Use `sleep` to simulate a long-running child of the PTY.
+ .."' +terminal +'!(sleep 300 &)' +qa")
+
+ -- Exiting should terminate all descendants (PTY, its children, ...).
+ screen:expect([[
+ |
+ [Process exited 0] |
+ |
+ |
+ |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
new file mode 100644
index 0000000000..c7c8986527
--- /dev/null
+++ b/test/functional/ui/output_spec.lua
@@ -0,0 +1,39 @@
+local session = require('test.functional.helpers')(after_each)
+local child_session = require('test.functional.terminal.helpers')
+
+describe("shell command :!", function()
+ local screen
+ before_each(function()
+ session.clear()
+ screen = child_session.screen_setup(0, '["'..session.nvim_prog..
+ '", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile"]')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ |
+ -- TERMINAL -- |
+ ]])
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("displays output even without LF/EOF. #4646 #4569 #3772", function()
+ -- NOTE: We use a child nvim (within a :term buffer)
+ -- to avoid triggering a UI flush.
+ child_session.feed_data(":!printf foo; sleep 200\n")
+ screen:expect([[
+ ~ |
+ ~ |
+ [No Name] |
+ :!printf foo; sleep 200 |
+ |
+ foo |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)