Skip to content

Commit f9c3883

Browse files
committed
patch 8.1.0087: v:shell_error is always zero when using terminal for "!cmd"
Problem: v:shell_error is always zero when using terminal for "!cmd". Solution: Use "exitval" of terminal-job. (Ozaki Kiichi, closes #2994)
1 parent 1ceebb4 commit f9c3883

6 files changed

Lines changed: 80 additions & 25 deletions

File tree

‎src/os_unix.c‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4365,6 +4365,7 @@ mch_call_shell_terminal(
43654365
char_u *tofree2 = NULL;
43664366
int retval = -1;
43674367
buf_T *buf;
4368+
job_T *job;
43684369
aco_save_T aco;
43694370
oparg_T oa; /* operator arguments */
43704371

@@ -4374,6 +4375,11 @@ mch_call_shell_terminal(
43744375
init_job_options(&opt);
43754376
ch_log(NULL, "starting terminal for system command '%s'", cmd);
43764377
buf = term_start(NULL, argv, &opt, TERM_START_SYSTEM);
4378+
if (buf == NULL)
4379+
goto theend;
4380+
4381+
job = term_getjob(buf->b_term);
4382+
++job->jv_refcount;
43774383

43784384
/* Find a window to make "buf" curbuf. */
43794385
aucmd_prepbuf(&aco, buf);
@@ -4391,9 +4397,11 @@ mch_call_shell_terminal(
43914397
else
43924398
normal_cmd(&oa, TRUE);
43934399
}
4394-
retval = 0;
4400+
retval = job->jv_exitval;
43954401
ch_log(NULL, "system command finished");
43964402

4403+
job_unref(job);
4404+
43974405
/* restore curwin/curbuf and a few other things */
43984406
aucmd_restbuf(&aco);
43994407

‎src/os_win32.c‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4796,6 +4796,7 @@ mch_call_shell_terminal(
47964796
long_u cmdlen;
47974797
int retval = -1;
47984798
buf_T *buf;
4799+
job_T *job;
47994800
aco_save_T aco;
48004801
oparg_T oa; /* operator arguments */
48014802

@@ -4826,6 +4827,9 @@ mch_call_shell_terminal(
48264827
if (buf == NULL)
48274828
return 255;
48284829

4830+
job = term_getjob(buf->b_term);
4831+
++job->jv_refcount;
4832+
48294833
/* Find a window to make "buf" curbuf. */
48304834
aucmd_prepbuf(&aco, buf);
48314835

@@ -4842,9 +4846,11 @@ mch_call_shell_terminal(
48424846
else
48434847
normal_cmd(&oa, TRUE);
48444848
}
4845-
retval = 0;
4849+
retval = job->jv_exitval;
48464850
ch_log(NULL, "system command finished");
48474851

4852+
job_unref(job);
4853+
48484854
/* restore curwin/curbuf and a few other things */
48494855
aucmd_restbuf(&aco);
48504856

‎src/proto/terminal.pro‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ void f_term_setkill(typval_T *argvars, typval_T *rettv);
5555
void f_term_start(typval_T *argvars, typval_T *rettv);
5656
void f_term_wait(typval_T *argvars, typval_T *rettv);
5757
void term_send_eof(channel_T *ch);
58+
job_T *term_getjob(term_T *term);
5859
int terminal_enabled(void);
5960
/* vim: set ft=c : */

‎src/terminal.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5336,6 +5336,12 @@ term_send_eof(channel_T *ch)
53365336
}
53375337
}
53385338

5339+
job_T *
5340+
term_getjob(term_T *term)
5341+
{
5342+
return term != NULL ? term->tl_job : NULL;
5343+
}
5344+
53395345
# if defined(WIN3264) || defined(PROTO)
53405346

53415347
/**************************************

‎src/testdir/test_terminal.vim‎

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -522,29 +522,6 @@ func Test_terminal_env()
522522
exe buf . 'bwipe'
523523
endfunc
524524

525-
" must be last, we can't go back from GUI to terminal
526-
func Test_zz_terminal_in_gui()
527-
if !CanRunGui()
528-
return
529-
endif
530-
531-
" Ignore the "failed to create input context" error.
532-
call test_ignore_error('E285:')
533-
534-
gui -f
535-
536-
call assert_equal(1, winnr('$'))
537-
let buf = Run_shell_in_terminal({'term_finish': 'close'})
538-
call Stop_shell_in_terminal(buf)
539-
call term_wait(buf)
540-
541-
" closing window wipes out the terminal buffer a with finished job
542-
call WaitForAssert({-> assert_equal(1, winnr('$'))})
543-
call assert_equal("", bufname(buf))
544-
545-
unlet g:job
546-
endfunc
547-
548525
func Test_terminal_list_args()
549526
let buf = term_start([&shell, &shellcmdflag, 'echo "123"'])
550527
call assert_fails(buf . 'bwipe', 'E517')
@@ -1546,3 +1523,58 @@ func Test_terminwinscroll()
15461523

15471524
exe buf . 'bwipe!'
15481525
endfunc
1526+
1527+
" must be nearly the last, we can't go back from GUI to terminal
1528+
func Test_zz1_terminal_in_gui()
1529+
if !CanRunGui()
1530+
return
1531+
endif
1532+
1533+
" Ignore the "failed to create input context" error.
1534+
call test_ignore_error('E285:')
1535+
1536+
gui -f
1537+
1538+
call assert_equal(1, winnr('$'))
1539+
let buf = Run_shell_in_terminal({'term_finish': 'close'})
1540+
call Stop_shell_in_terminal(buf)
1541+
call term_wait(buf)
1542+
1543+
" closing window wipes out the terminal buffer a with finished job
1544+
call WaitForAssert({-> assert_equal(1, winnr('$'))})
1545+
call assert_equal("", bufname(buf))
1546+
1547+
unlet g:job
1548+
endfunc
1549+
1550+
func Test_zz2_terminal_guioptions_bang()
1551+
if !has('gui_running')
1552+
return
1553+
endif
1554+
set guioptions+=!
1555+
1556+
let filename = 'Xtestscript'
1557+
if has('win32')
1558+
let filename .= '.bat'
1559+
let prefix = ''
1560+
let contents = ['@echo off', 'exit %1']
1561+
else
1562+
let filename .= '.sh'
1563+
let prefix = './'
1564+
let contents = ['#!/bin/sh', 'exit $1']
1565+
endif
1566+
call writefile(contents, filename)
1567+
call setfperm(filename, 'rwxrwx---')
1568+
1569+
" Check if v:shell_error is equal to the exit status.
1570+
let exitval = 0
1571+
execute printf(':!%s%s %d', prefix, filename, exitval)
1572+
call assert_equal(exitval, v:shell_error)
1573+
1574+
let exitval = 9
1575+
execute printf(':!%s%s %d', prefix, filename, exitval)
1576+
call assert_equal(exitval, v:shell_error)
1577+
1578+
set guioptions&
1579+
call delete(filename)
1580+
endfunc

‎src/version.c‎

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

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
87,
764766
/**/
765767
86,
766768
/**/

0 commit comments

Comments
 (0)