aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hahler <git@thequod.de>2019-08-09 15:34:06 +0200
committerGitHub <noreply@github.com>2019-08-09 15:34:06 +0200
commit939d9053bdf2f56286640c581eb4e2ff5a856540 (patch)
tree8ba6e3bbda157caad29732b0b619566037db1644
parentfa0c677a63079e5d27ff037ea8f1e23a71fe6680 (diff)
downloadrneovim-939d9053bdf2f56286640c581eb4e2ff5a856540.tar.gz
rneovim-939d9053bdf2f56286640c581eb4e2ff5a856540.tar.bz2
rneovim-939d9053bdf2f56286640c581eb4e2ff5a856540.zip
channels: reflect exit due to signals in exit status code (#10573)
Uses `128 + term_signal` in case of exit due to a signal. Fixes https://github.com/neovim/neovim/issues/10571.
-rw-r--r--runtime/doc/job_control.txt2
-rw-r--r--src/nvim/eval.c1
-rw-r--r--src/nvim/event/libuv_process.c6
-rw-r--r--src/nvim/event/process.c6
-rw-r--r--src/nvim/event/process.h1
-rw-r--r--src/nvim/os/pty_process_unix.c2
-rw-r--r--src/nvim/os/pty_process_win.c2
-rw-r--r--test/functional/core/job_spec.lua21
8 files changed, 18 insertions, 23 deletions
diff --git a/runtime/doc/job_control.txt b/runtime/doc/job_control.txt
index e5cd765e83..ae208c0755 100644
--- a/runtime/doc/job_control.txt
+++ b/runtime/doc/job_control.txt
@@ -67,7 +67,7 @@ For |on_stdout| and |on_stderr| see |channel-callback|.
*on_exit*
Arguments passed to on_exit callback:
0: |job-id|
- 1: Exit-code of the process.
+ 1: Exit-code of the process, or 128+SIGNUM if by signal (e.g. 143 on SIGTERM).
2: Event type: "exit"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 77347d4701..d0d447f053 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -12354,7 +12354,6 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-
Channel *data = find_job(argvars[0].vval.v_number, true);
if (!data) {
return;
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index ffe2db9b76..63efee59a8 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -101,6 +101,10 @@ static void close_cb(uv_handle_t *handle)
static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
{
Process *proc = handle->data;
- proc->status = (int)status;
+#if defined(WIN32)
+ // Use stored/expected signal.
+ term_signal = proc->exit_signal;
+#endif
+ proc->status = term_signal ? 128 + term_signal : (int)status;
proc->internal_exit_cb(proc);
}
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 4410deadef..c31ecdaddf 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -159,7 +159,7 @@ void process_close_streams(Process *proc) FUNC_ATTR_NONNULL_ALL
/// 0 for no wait. -1 to wait until the process quits.
/// @return Exit code of the process. proc->status will have the same value.
/// -1 if the timeout expired while the process is still running.
-/// -2 if the user interruped the wait.
+/// -2 if the user interrupted the wait.
int process_wait(Process *proc, int ms, MultiQueue *events)
FUNC_ATTR_NONNULL_ARG(1)
{
@@ -220,6 +220,7 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
return;
}
proc->stopped_time = os_hrtime();
+ proc->exit_signal = SIGTERM;
switch (proc->type) {
case kProcessTypeUv:
@@ -253,8 +254,10 @@ static void children_kill_cb(uv_timer_t *handle)
}
uint64_t term_sent = UINT64_MAX == proc->stopped_time;
if (kProcessTypePty != proc->type || term_sent) {
+ proc->exit_signal = SIGKILL;
os_proc_tree_kill(proc->pid, SIGKILL);
} else {
+ proc->exit_signal = SIGTERM;
os_proc_tree_kill(proc->pid, SIGTERM);
proc->stopped_time = UINT64_MAX; // Flag: SIGTERM was sent.
// Restart timer.
@@ -403,4 +406,3 @@ static void on_process_stream_close(Stream *stream, void *data)
Process *proc = data;
decref(proc);
}
-
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 13dc3839ce..ef9d953ab7 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -19,6 +19,7 @@ struct process {
Loop *loop;
void *data;
int pid, status, refcount;
+ uint8_t exit_signal; // Signal used when killing (on Windows).
uint64_t stopped_time; // process_stop() timestamp
const char *cwd;
char **argv;
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 5fdf0e6181..f0bc13783c 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -288,7 +288,7 @@ static void chld_handler(uv_signal_t *handle, int signum)
if (WIFEXITED(stat)) {
proc->status = WEXITSTATUS(stat);
} else if (WIFSIGNALED(stat)) {
- proc->status = WTERMSIG(stat);
+ proc->status = 128 + WTERMSIG(stat);
}
proc->internal_exit_cb(proc);
}
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
index c5f8efadff..290668bca3 100644
--- a/src/nvim/os/pty_process_win.c
+++ b/src/nvim/os/pty_process_win.c
@@ -252,7 +252,7 @@ static void pty_process_finish2(PtyProcess *ptyproc)
DWORD exit_code = 0;
GetExitCodeProcess(ptyproc->process_handle, &exit_code);
- proc->status = (int)exit_code;
+ proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code;
CloseHandle(ptyproc->process_handle);
ptyproc->process_handle = NULL;
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 212b76b5d9..180ed9aa02 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -183,7 +183,7 @@ describe('jobs', function()
)
nvim('command', "call jobstop(j)")
eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, iswin() and 15 or 0}}, next_msg())
+ eq({'notification', 'exit', {0, 143}}, next_msg())
end)
it('preserves NULs', function()
@@ -217,7 +217,7 @@ describe('jobs', function()
eq({'notification', 'stdout', {0, {'abc', 'xyz'}}}, next_msg())
nvim('command', "call jobstop(j)")
eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, iswin() and 15 or 0}}, next_msg())
+ eq({'notification', 'exit', {0, 143}}, next_msg())
end)
it('preserves newlines', function()
@@ -234,7 +234,7 @@ describe('jobs', function()
next_msg())
nvim('command', "call jobstop(j)")
eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, iswin() and 15 or 0}}, next_msg())
+ eq({'notification', 'exit', {0, 143}}, next_msg())
end)
it('avoids sending final newline', function()
@@ -244,7 +244,7 @@ describe('jobs', function()
next_msg())
nvim('command', "call jobstop(j)")
eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, iswin() and 15 or 0}}, next_msg())
+ eq({'notification', 'exit', {0, 143}}, next_msg())
end)
it('closes the job streams with jobclose', function()
@@ -284,18 +284,7 @@ describe('jobs', function()
neq(NIL, meths.get_proc(pid))
nvim('command', 'call jobstop(j)')
eq({'notification', 'stdout', {0, {''}}}, next_msg())
- if iswin() then
- expect_msg_seq(
- -- win64
- { {'notification', 'exit', {0, 1}}
- },
- -- win32
- { {'notification', 'exit', {0, 15}}
- }
- )
- else
- eq({'notification', 'exit', {0, 0}}, next_msg())
- end
+ eq({'notification', 'exit', {0, 143}}, next_msg())
eq(NIL, meths.get_proc(pid))
end)