Skip to content

Commit 1a61339

Browse files
committed
patch 8.1.2092: MS-Windows: redirect in system() does not work
Problem: MS-Windows: redirect in system() does not work. Solution: Handle 'shellxescape' and 'shellxquote' better. (Yasuhiro Matsumoto, closes #2054)
1 parent 0f1c670 commit 1a61339

4 files changed

Lines changed: 61 additions & 28 deletions

File tree

src/ex_cmds.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,12 +1762,21 @@ make_filter_cmd(
17621762
STRCAT(buf, itmp);
17631763
}
17641764
#else
1765-
/*
1766-
* For shells that don't understand braces around commands, at least allow
1767-
* the use of commands in a pipe.
1768-
*/
1769-
STRCPY(buf, cmd);
1770-
if (itmp != NULL)
1765+
// For shells that don't understand braces around commands, at least allow
1766+
// the use of commands in a pipe.
1767+
if (*p_sxe != NUL && *p_sxq == '(')
1768+
{
1769+
if (itmp != NULL || otmp != NULL)
1770+
vim_snprintf((char *)buf, len, "(%s)", (char *)cmd);
1771+
else
1772+
STRCPY(buf, cmd);
1773+
if (itmp != NULL)
1774+
{
1775+
STRCAT(buf, " < ");
1776+
STRCAT(buf, itmp);
1777+
}
1778+
}
1779+
else
17711780
{
17721781
char_u *p;
17731782

@@ -1819,26 +1828,28 @@ append_redir(
18191828
char_u *end;
18201829

18211830
end = buf + STRLEN(buf);
1822-
/* find "%s" */
1831+
// find "%s"
18231832
for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p)
18241833
{
1825-
if (p[1] == 's') /* found %s */
1834+
if (p[1] == 's') // found %s
18261835
break;
1827-
if (p[1] == '%') /* skip %% */
1836+
if (p[1] == '%') // skip %%
18281837
++p;
18291838
}
18301839
if (p != NULL)
18311840
{
1832-
*end = ' '; /* not really needed? Not with sh, ksh or bash */
1833-
vim_snprintf((char *)end + 1, (size_t)(buflen - (end + 1 - buf)),
1841+
#ifdef MSWIN
1842+
*end++ = ' '; // not really needed? Not with sh, ksh or bash
1843+
#endif
1844+
vim_snprintf((char *)end, (size_t)(buflen - (end - buf)),
18341845
(char *)opt, (char *)fname);
18351846
}
18361847
else
18371848
vim_snprintf((char *)end, (size_t)(buflen - (end - buf)),
18381849
#ifdef FEAT_QUICKFIX
18391850
" %s %s",
18401851
#else
1841-
" %s%s", /* " > %s" causes problems on Amiga */
1852+
" %s%s", // " > %s" causes problems on Amiga
18421853
#endif
18431854
(char *)opt, (char *)fname);
18441855
}

src/misc2.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,7 +3157,7 @@ call_shell(char_u *cmd, int opt)
31573157
{
31583158
char_u *ecmd = cmd;
31593159

3160-
if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0)
3160+
if (*p_sxe != NUL && *p_sxq == '(')
31613161
{
31623162
ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
31633163
if (ecmd == NULL)
@@ -3168,11 +3168,11 @@ call_shell(char_u *cmd, int opt)
31683168
{
31693169
STRCPY(ncmd, p_sxq);
31703170
STRCAT(ncmd, ecmd);
3171-
/* When 'shellxquote' is ( append ).
3172-
* When 'shellxquote' is "( append )". */
3173-
STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")"
3174-
: STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\""
3175-
: p_sxq);
3171+
// When 'shellxquote' is ( append ).
3172+
// When 'shellxquote' is "( append )".
3173+
STRCAT(ncmd, *p_sxq == '(' ? (char_u *)")"
3174+
: *p_sxq == '"' && *(p_sxq+1) == '(' ? (char_u *)")\""
3175+
: p_sxq);
31763176
retval = mch_call_shell(ncmd, opt);
31773177
vim_free(ncmd);
31783178
}

src/testdir/test_system.vim

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,42 @@
33
source shared.vim
44

55
func Test_System()
6-
if !executable('echo') || !executable('cat') || !executable('wc')
6+
if !has('win32')
7+
call assert_equal("123\n", system('echo 123'))
8+
call assert_equal(['123'], systemlist('echo 123'))
9+
call assert_equal('123', system('cat', '123'))
10+
call assert_equal(['123'], systemlist('cat', '123'))
11+
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
12+
else
13+
call assert_equal("123\n", system('echo 123'))
14+
call assert_equal(["123\r"], systemlist('echo 123'))
15+
call assert_equal("123", system('more', '123'))
16+
call assert_equal(["123"], systemlist('more', '123'))
17+
call assert_equal(["as\<NL>df"], systemlist('more', ["as\<NL>df"]))
18+
endif
19+
20+
if !executable('cat') || !executable('wc')
721
return
822
endif
23+
924
let out = 'echo 123'->system()
1025
" On Windows we may get a trailing space.
1126
if out != "123 \n"
1227
call assert_equal("123\n", out)
1328
endif
1429

1530
let out = 'echo 123'->systemlist()
16-
" On Windows we may get a trailing space and CR.
17-
if out != ["123 \r"]
18-
call assert_equal(['123'], out)
31+
if !has('win32')
32+
call assert_equal(["123"], out)
33+
else
34+
call assert_equal(["123\r"], out)
1935
endif
2036

21-
call assert_equal('123', system('cat', '123'))
22-
call assert_equal(['123'], systemlist('cat', '123'))
23-
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
37+
if executable('cat')
38+
call assert_equal('123', system('cat', '123'))
39+
call assert_equal(['123'], systemlist('cat', '123'))
40+
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
41+
endif
2442

2543
new Xdummy
2644
call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
@@ -39,9 +57,11 @@ func Test_System()
3957
call assert_equal(['3'], out)
4058
endif
4159

42-
let out = systemlist('cat', bufnr('%'))
43-
" On Windows we may get a trailing CR.
44-
if out != ["asdf\r", "pw\<NL>er\r", "xxxx\r"]
60+
if !has('win32')
61+
let out = systemlist('cat', bufnr('%'))
62+
call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
63+
else
64+
let out = systemlist('more', bufnr('%'))
4565
call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
4666
endif
4767
bwipe!

src/version.c

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

758758
static int included_patches[] =
759759
{ /* Add new patch number below this line */
760+
/**/
761+
2092,
760762
/**/
761763
2091,
762764
/**/

0 commit comments

Comments
 (0)