]> granicus.if.org Git - vim/commitdiff
patch 8.1.0087: v:shell_error is always zero when using terminal for "!cmd" v8.1.0087
authorBram Moolenaar <Bram@vim.org>
Tue, 19 Jun 2018 17:59:20 +0000 (19:59 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 19 Jun 2018 17:59:20 +0000 (19:59 +0200)
Problem:    v:shell_error is always zero when using terminal for "!cmd".
Solution:   Use "exitval" of terminal-job. (Ozaki Kiichi, closes #2994)

src/os_unix.c
src/os_win32.c
src/proto/terminal.pro
src/terminal.c
src/testdir/test_terminal.vim
src/version.c

index 05ad6b8dfd798bd080b12072e272d4663886ba0f..3649276c49877bf3bd18d76b316ad94c61db9942 100644 (file)
@@ -4365,6 +4365,7 @@ mch_call_shell_terminal(
     char_u     *tofree2 = NULL;
     int                retval = -1;
     buf_T      *buf;
+    job_T      *job;
     aco_save_T aco;
     oparg_T    oa;             /* operator arguments */
 
@@ -4374,6 +4375,11 @@ mch_call_shell_terminal(
     init_job_options(&opt);
     ch_log(NULL, "starting terminal for system command '%s'", cmd);
     buf = term_start(NULL, argv, &opt, TERM_START_SYSTEM);
+    if (buf == NULL)
+       goto theend;
+
+    job = term_getjob(buf->b_term);
+    ++job->jv_refcount;
 
     /* Find a window to make "buf" curbuf. */
     aucmd_prepbuf(&aco, buf);
@@ -4391,9 +4397,11 @@ mch_call_shell_terminal(
        else
            normal_cmd(&oa, TRUE);
     }
-    retval = 0;
+    retval = job->jv_exitval;
     ch_log(NULL, "system command finished");
 
+    job_unref(job);
+
     /* restore curwin/curbuf and a few other things */
     aucmd_restbuf(&aco);
 
index bece2c4c61fc98503976a83d152289d0db13fe51..f8884e401164b337d0256830ecdc3ea5837fce38 100644 (file)
@@ -4796,6 +4796,7 @@ mch_call_shell_terminal(
     long_u     cmdlen;
     int                retval = -1;
     buf_T      *buf;
+    job_T      *job;
     aco_save_T aco;
     oparg_T    oa;             /* operator arguments */
 
@@ -4826,6 +4827,9 @@ mch_call_shell_terminal(
     if (buf == NULL)
        return 255;
 
+    job = term_getjob(buf->b_term);
+    ++job->jv_refcount;
+
     /* Find a window to make "buf" curbuf. */
     aucmd_prepbuf(&aco, buf);
 
@@ -4842,9 +4846,11 @@ mch_call_shell_terminal(
        else
            normal_cmd(&oa, TRUE);
     }
-    retval = 0;
+    retval = job->jv_exitval;
     ch_log(NULL, "system command finished");
 
+    job_unref(job);
+
     /* restore curwin/curbuf and a few other things */
     aucmd_restbuf(&aco);
 
index 25f9647f25759e40640e4481dfa134bb38387c33..1031876c488b1d9fbaf2d2835020052c99ee843e 100644 (file)
@@ -55,5 +55,6 @@ void f_term_setkill(typval_T *argvars, typval_T *rettv);
 void f_term_start(typval_T *argvars, typval_T *rettv);
 void f_term_wait(typval_T *argvars, typval_T *rettv);
 void term_send_eof(channel_T *ch);
+job_T *term_getjob(term_T *term);
 int terminal_enabled(void);
 /* vim: set ft=c : */
index a67c87a4bed2d70ce2e4395f06731d457457b993..6195ad51dfb1c4a5b3c91ec16f24786bdd185722 100644 (file)
@@ -5336,6 +5336,12 @@ term_send_eof(channel_T *ch)
        }
 }
 
+    job_T *
+term_getjob(term_T *term)
+{
+    return term != NULL ? term->tl_job : NULL;
+}
+
 # if defined(WIN3264) || defined(PROTO)
 
 /**************************************
index c082b3b73e073a38b359418f3cd034e24e33056e..bce7e10dee20dabee0af8bdeef6a1725ebb7de35 100644 (file)
@@ -522,29 +522,6 @@ func Test_terminal_env()
   exe buf . 'bwipe'
 endfunc
 
-" must be last, we can't go back from GUI to terminal
-func Test_zz_terminal_in_gui()
-  if !CanRunGui()
-    return
-  endif
-
-  " Ignore the "failed to create input context" error.
-  call test_ignore_error('E285:')
-
-  gui -f
-
-  call assert_equal(1, winnr('$'))
-  let buf = Run_shell_in_terminal({'term_finish': 'close'})
-  call Stop_shell_in_terminal(buf)
-  call term_wait(buf)
-
-  " closing window wipes out the terminal buffer a with finished job
-  call WaitForAssert({-> assert_equal(1, winnr('$'))})
-  call assert_equal("", bufname(buf))
-
-  unlet g:job
-endfunc
-
 func Test_terminal_list_args()
   let buf = term_start([&shell, &shellcmdflag, 'echo "123"'])
   call assert_fails(buf . 'bwipe', 'E517')
@@ -1546,3 +1523,58 @@ func Test_terminwinscroll()
 
   exe buf . 'bwipe!'
 endfunc
+
+" must be nearly the last, we can't go back from GUI to terminal
+func Test_zz1_terminal_in_gui()
+  if !CanRunGui()
+    return
+  endif
+
+  " Ignore the "failed to create input context" error.
+  call test_ignore_error('E285:')
+
+  gui -f
+
+  call assert_equal(1, winnr('$'))
+  let buf = Run_shell_in_terminal({'term_finish': 'close'})
+  call Stop_shell_in_terminal(buf)
+  call term_wait(buf)
+
+  " closing window wipes out the terminal buffer a with finished job
+  call WaitForAssert({-> assert_equal(1, winnr('$'))})
+  call assert_equal("", bufname(buf))
+
+  unlet g:job
+endfunc
+
+func Test_zz2_terminal_guioptions_bang()
+  if !has('gui_running')
+    return
+  endif
+  set guioptions+=!
+
+  let filename = 'Xtestscript'
+  if has('win32')
+    let filename .= '.bat'
+    let prefix = ''
+    let contents = ['@echo off', 'exit %1']
+  else
+    let filename .= '.sh'
+    let prefix = './'
+    let contents = ['#!/bin/sh', 'exit $1']
+  endif
+  call writefile(contents, filename)
+  call setfperm(filename, 'rwxrwx---')
+
+  " Check if v:shell_error is equal to the exit status.
+  let exitval = 0
+  execute printf(':!%s%s %d', prefix, filename, exitval)
+  call assert_equal(exitval, v:shell_error)
+
+  let exitval = 9
+  execute printf(':!%s%s %d', prefix, filename, exitval)
+  call assert_equal(exitval, v:shell_error)
+
+  set guioptions&
+  call delete(filename)
+endfunc
index bd3bca11cb8b723b037783fa9e12ca2b46bd4c12..72a8238581c3e9bac832433f6d65faf3bdef884d 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    87,
 /**/
     86,
 /**/