summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-31 15:52:11 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-31 15:52:11 +0100
commitb3051ce82f2e8af95ce3b6a41867f70aee5ecc82 (patch)
tree52f4e45e4fc81f14d02414e5c9e18036ed026dcf
parent221cd9f4dd866503777b2fffa721c1403716ad63 (diff)
downloadvim-git-b3051ce82f2e8af95ce3b6a41867f70aee5ecc82.tar.gz
patch 8.1.0863: cannot see what signal caused a job to endv8.1.0863
Problem: Cannot see what signal caused a job to end. Solution: Add "termsig" to job_info(). (Ozaki Kiichi, closes #3786)
-rw-r--r--runtime/doc/eval.txt5
-rw-r--r--src/channel.c6
-rw-r--r--src/os_unix.c26
-rw-r--r--src/structs.h5
-rw-r--r--src/testdir/test_channel.vim24
-rw-r--r--src/version.c2
6 files changed, 65 insertions, 3 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 46a503e88..d888d9c49 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -5745,6 +5745,11 @@ job_info([{job}]) *job_info()*
"exit_cb" function to be called on exit
"stoponexit" |job-stoponexit|
+ Only in Unix:
+ "termsig" the signal which terminated the process
+ (See |job_stop()| for the values)
+ only valid when "status" is "dead"
+
Without any arguments, returns a List with all Job objects.
job_setoptions({job}, {options}) *job_setoptions()*
diff --git a/src/channel.c b/src/channel.c
index cf6827192..20cf46238 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -5152,6 +5152,9 @@ job_free_contents(job_T *job)
vim_free(job->jv_tty_in);
vim_free(job->jv_tty_out);
vim_free(job->jv_stoponexit);
+#ifdef UNIX
+ vim_free(job->jv_termsig);
+#endif
free_callback(job->jv_exit_cb, job->jv_exit_partial);
if (job->jv_argv != NULL)
{
@@ -5908,6 +5911,9 @@ job_info(job_T *job, dict_T *dict)
dict_add_number(dict, "exitval", job->jv_exitval);
dict_add_string(dict, "exit_cb", job->jv_exit_cb);
dict_add_string(dict, "stoponexit", job->jv_stoponexit);
+#ifdef UNIX
+ dict_add_string(dict, "termsig", job->jv_termsig);
+#endif
l = list_alloc();
if (l != NULL)
diff --git a/src/os_unix.c b/src/os_unix.c
index c616e06fe..a17abe3d5 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5655,6 +5655,23 @@ failed:
close(pty_slave_fd);
}
+ static char_u *
+get_signal_name(int sig)
+{
+ int i;
+ char_u numbuf[NUMBUFLEN];
+
+ if (sig == SIGKILL)
+ return vim_strsave((char_u *)"kill");
+
+ for (i = 0; signal_info[i].sig != -1; i++)
+ if (sig == signal_info[i].sig)
+ return strlow_save((char_u *)signal_info[i].name);
+
+ vim_snprintf((char *)numbuf, NUMBUFLEN, "%d", sig);
+ return vim_strsave(numbuf);
+}
+
char *
mch_job_status(job_T *job)
{
@@ -5691,8 +5708,10 @@ mch_job_status(job_T *job)
if (WIFSIGNALED(status))
{
job->jv_exitval = -1;
- if (job->jv_status < JOB_ENDED)
- ch_log(job->jv_channel, "Job terminated by a signal");
+ job->jv_termsig = get_signal_name(WTERMSIG(status));
+ if (job->jv_status < JOB_ENDED && job->jv_termsig != NULL)
+ ch_log(job->jv_channel, "Job terminated by signal \"%s\"",
+ job->jv_termsig);
goto return_dead;
}
return "run";
@@ -5738,7 +5757,10 @@ mch_detect_ended_job(job_T *job_list)
/* LINTED avoid "bitwise operation on signed value" */
job->jv_exitval = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
+ {
job->jv_exitval = -1;
+ job->jv_termsig = get_signal_name(WTERMSIG(status));
+ }
if (job->jv_status < JOB_ENDED)
{
ch_log(job->jv_channel, "Job ended");
diff --git a/src/structs.h b/src/structs.h
index 459103d3a..ddc56bca4 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1550,7 +1550,10 @@ struct jobvar_S
char_u *jv_tty_in; /* controlling tty input, allocated */
char_u *jv_tty_out; /* controlling tty output, allocated */
jobstatus_T jv_status;
- char_u *jv_stoponexit; /* allocated */
+ char_u *jv_stoponexit; /* allocated */
+#ifdef UNIX
+ char_u *jv_termsig; /* allocated */
+#endif
int jv_exitval;
char_u *jv_exit_cb; /* allocated */
partial_T *jv_exit_partial;
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index f81701a07..2aef3e1dc 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -2002,3 +2002,27 @@ func Test_raw_large_data()
unlet g:out
endtry
endfunc
+
+func Test_job_exitval_and_termsig()
+ if !has('unix')
+ return
+ endif
+
+ " Terminate job normally
+ let cmd = ['echo']
+ let job = job_start(cmd)
+ call WaitForAssert({-> assert_equal("dead", job_status(job))})
+ let info = job_info(job)
+ call assert_equal(0, info.exitval)
+ call assert_equal("", info.termsig)
+
+ " Terminate job by signal
+ let cmd = ['sleep', '10']
+ let job = job_start(cmd)
+ sleep 10m
+ call job_stop(job)
+ call WaitForAssert({-> assert_equal("dead", job_status(job))})
+ let info = job_info(job)
+ call assert_equal(-1, info.exitval)
+ call assert_equal("term", info.termsig)
+endfunc
diff --git a/src/version.c b/src/version.c
index 1b4eef9f4..05b18ed7e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 863,
+/**/
862,
/**/
861,