diff options
author | Daniel Hahler <git@thequod.de> | 2019-08-09 15:34:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-09 15:34:06 +0200 |
commit | 939d9053bdf2f56286640c581eb4e2ff5a856540 (patch) | |
tree | 8ba6e3bbda157caad29732b0b619566037db1644 | |
parent | fa0c677a63079e5d27ff037ea8f1e23a71fe6680 (diff) | |
download | rneovim-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.txt | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 1 | ||||
-rw-r--r-- | src/nvim/event/libuv_process.c | 6 | ||||
-rw-r--r-- | src/nvim/event/process.c | 6 | ||||
-rw-r--r-- | src/nvim/event/process.h | 1 | ||||
-rw-r--r-- | src/nvim/os/pty_process_unix.c | 2 | ||||
-rw-r--r-- | src/nvim/os/pty_process_win.c | 2 | ||||
-rw-r--r-- | test/functional/core/job_spec.lua | 21 |
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) |