patch 8.1.0863: cannot see what signal caused a job to end
Problem: Cannot see what signal caused a job to end.
Solution: Add "termsig" to job_info(). (Ozaki Kiichi, closes #3786)
diff --git a/src/channel.c b/src/channel.c
index cf68271..20cf462 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -5152,6 +5152,9 @@
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 @@
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 c616e06..a17abe3 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5655,6 +5655,23 @@
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 @@
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 @@
/* 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 459103d..ddc56bc 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1550,7 +1550,10 @@
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 f81701a..2aef3e1 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -2002,3 +2002,27 @@
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 1b4eef9..05b18ed 100644
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 863,
+/**/
862,
/**/
861,