]> granicus.if.org Git - vim/commitdiff
patch 8.1.0863: cannot see what signal caused a job to end v8.1.0863
authorBram Moolenaar <Bram@vim.org>
Thu, 31 Jan 2019 14:52:11 +0000 (15:52 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 31 Jan 2019 14:52:11 +0000 (15:52 +0100)
Problem:    Cannot see what signal caused a job to end.
Solution:   Add "termsig" to job_info(). (Ozaki Kiichi, closes #3786)

runtime/doc/eval.txt
src/channel.c
src/os_unix.c
src/structs.h
src/testdir/test_channel.vim
src/version.c

index 46a503e8898ceabf7eb068172d321d9bf0b80f36..d888d9c491e5f0ce92276f2c041badfd4a27a581 100644 (file)
@@ -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()*
index cf68271925574bce64856feb2f90a9d007fedd0a..20cf46238c0771873923f5f6d0bff4ed27bf3dbe 100644 (file)
@@ -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)
index c616e06fe1cf7f7eab44abee2f444cb1a80995a7..a17abe3d52407058a68e8211d883a80cdb49c0ce 100644 (file)
@@ -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");
index 459103d3a4e3eceb290b33d221c71f041cc538ed..ddc56bca4d8bbc5c1b80df58cbabdc5b60bedbc9 100644 (file)
@@ -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;
index f81701a076026221f31249389af131910daaf3e6..2aef3e1dc4d82db24ecc45d82e9aa6cbf8c26e41 100644 (file)
@@ -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
index 1b4eef9f4026d1d1826513adbc13a0e19d17842d..05b18ed7e6c6197b7afb8f82c35c541d1fcf2d6d 100644 (file)
@@ -783,6 +783,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    863,
 /**/
     862,
 /**/