Skip to content

Commit b3051ce

Browse files
committed
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)
1 parent 221cd9f commit b3051ce

6 files changed

Lines changed: 65 additions & 3 deletions

File tree

runtime/doc/eval.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5745,6 +5745,11 @@ job_info([{job}]) *job_info()*
57455745
"exit_cb" function to be called on exit
57465746
"stoponexit" |job-stoponexit|
57475747

5748+
Only in Unix:
5749+
"termsig" the signal which terminated the process
5750+
(See |job_stop()| for the values)
5751+
only valid when "status" is "dead"
5752+
57485753
Without any arguments, returns a List with all Job objects.
57495754

57505755
job_setoptions({job}, {options}) *job_setoptions()*

src/channel.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5152,6 +5152,9 @@ job_free_contents(job_T *job)
51525152
vim_free(job->jv_tty_in);
51535153
vim_free(job->jv_tty_out);
51545154
vim_free(job->jv_stoponexit);
5155+
#ifdef UNIX
5156+
vim_free(job->jv_termsig);
5157+
#endif
51555158
free_callback(job->jv_exit_cb, job->jv_exit_partial);
51565159
if (job->jv_argv != NULL)
51575160
{
@@ -5908,6 +5911,9 @@ job_info(job_T *job, dict_T *dict)
59085911
dict_add_number(dict, "exitval", job->jv_exitval);
59095912
dict_add_string(dict, "exit_cb", job->jv_exit_cb);
59105913
dict_add_string(dict, "stoponexit", job->jv_stoponexit);
5914+
#ifdef UNIX
5915+
dict_add_string(dict, "termsig", job->jv_termsig);
5916+
#endif
59115917

59125918
l = list_alloc();
59135919
if (l != NULL)

src/os_unix.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5655,6 +5655,23 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal)
56555655
close(pty_slave_fd);
56565656
}
56575657

5658+
static char_u *
5659+
get_signal_name(int sig)
5660+
{
5661+
int i;
5662+
char_u numbuf[NUMBUFLEN];
5663+
5664+
if (sig == SIGKILL)
5665+
return vim_strsave((char_u *)"kill");
5666+
5667+
for (i = 0; signal_info[i].sig != -1; i++)
5668+
if (sig == signal_info[i].sig)
5669+
return strlow_save((char_u *)signal_info[i].name);
5670+
5671+
vim_snprintf((char *)numbuf, NUMBUFLEN, "%d", sig);
5672+
return vim_strsave(numbuf);
5673+
}
5674+
56585675
char *
56595676
mch_job_status(job_T *job)
56605677
{
@@ -5691,8 +5708,10 @@ mch_job_status(job_T *job)
56915708
if (WIFSIGNALED(status))
56925709
{
56935710
job->jv_exitval = -1;
5694-
if (job->jv_status < JOB_ENDED)
5695-
ch_log(job->jv_channel, "Job terminated by a signal");
5711+
job->jv_termsig = get_signal_name(WTERMSIG(status));
5712+
if (job->jv_status < JOB_ENDED && job->jv_termsig != NULL)
5713+
ch_log(job->jv_channel, "Job terminated by signal \"%s\"",
5714+
job->jv_termsig);
56965715
goto return_dead;
56975716
}
56985717
return "run";
@@ -5738,7 +5757,10 @@ mch_detect_ended_job(job_T *job_list)
57385757
/* LINTED avoid "bitwise operation on signed value" */
57395758
job->jv_exitval = WEXITSTATUS(status);
57405759
else if (WIFSIGNALED(status))
5760+
{
57415761
job->jv_exitval = -1;
5762+
job->jv_termsig = get_signal_name(WTERMSIG(status));
5763+
}
57425764
if (job->jv_status < JOB_ENDED)
57435765
{
57445766
ch_log(job->jv_channel, "Job ended");

src/structs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,10 @@ struct jobvar_S
15501550
char_u *jv_tty_in; /* controlling tty input, allocated */
15511551
char_u *jv_tty_out; /* controlling tty output, allocated */
15521552
jobstatus_T jv_status;
1553-
char_u *jv_stoponexit; /* allocated */
1553+
char_u *jv_stoponexit; /* allocated */
1554+
#ifdef UNIX
1555+
char_u *jv_termsig; /* allocated */
1556+
#endif
15541557
int jv_exitval;
15551558
char_u *jv_exit_cb; /* allocated */
15561559
partial_T *jv_exit_partial;

src/testdir/test_channel.vim

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,3 +2002,27 @@ func Test_raw_large_data()
20022002
unlet g:out
20032003
endtry
20042004
endfunc
2005+
2006+
func Test_job_exitval_and_termsig()
2007+
if !has('unix')
2008+
return
2009+
endif
2010+
2011+
" Terminate job normally
2012+
let cmd = ['echo']
2013+
let job = job_start(cmd)
2014+
call WaitForAssert({-> assert_equal("dead", job_status(job))})
2015+
let info = job_info(job)
2016+
call assert_equal(0, info.exitval)
2017+
call assert_equal("", info.termsig)
2018+
2019+
" Terminate job by signal
2020+
let cmd = ['sleep', '10']
2021+
let job = job_start(cmd)
2022+
sleep 10m
2023+
call job_stop(job)
2024+
call WaitForAssert({-> assert_equal("dead", job_status(job))})
2025+
let info = job_info(job)
2026+
call assert_equal(-1, info.exitval)
2027+
call assert_equal("term", info.termsig)
2028+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,8 @@ static char *(features[]) =
783783

784784
static int included_patches[] =
785785
{ /* Add new patch number below this line */
786+
/**/
787+
863,
786788
/**/
787789
862,
788790
/**/

0 commit comments

Comments
 (0)