1
0
forked from aniani/vim

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)
This commit is contained in:
Bram Moolenaar
2019-09-28 15:51:37 +02:00
parent 0f1c6708fd
commit 1a61339806
4 changed files with 61 additions and 28 deletions

View File

@@ -1762,12 +1762,21 @@ make_filter_cmd(
STRCAT(buf, itmp); STRCAT(buf, itmp);
} }
#else #else
/* // For shells that don't understand braces around commands, at least allow
* For shells that don't understand braces around commands, at least allow // the use of commands in a pipe.
* the use of commands in a pipe. if (*p_sxe != NUL && *p_sxq == '(')
*/ {
STRCPY(buf, cmd); if (itmp != NULL || otmp != NULL)
if (itmp != NULL) vim_snprintf((char *)buf, len, "(%s)", (char *)cmd);
else
STRCPY(buf, cmd);
if (itmp != NULL)
{
STRCAT(buf, " < ");
STRCAT(buf, itmp);
}
}
else
{ {
char_u *p; char_u *p;
@@ -1819,18 +1828,20 @@ append_redir(
char_u *end; char_u *end;
end = buf + STRLEN(buf); end = buf + STRLEN(buf);
/* find "%s" */ // find "%s"
for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p) for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p)
{ {
if (p[1] == 's') /* found %s */ if (p[1] == 's') // found %s
break; break;
if (p[1] == '%') /* skip %% */ if (p[1] == '%') // skip %%
++p; ++p;
} }
if (p != NULL) if (p != NULL)
{ {
*end = ' '; /* not really needed? Not with sh, ksh or bash */ #ifdef MSWIN
vim_snprintf((char *)end + 1, (size_t)(buflen - (end + 1 - buf)), *end++ = ' '; // not really needed? Not with sh, ksh or bash
#endif
vim_snprintf((char *)end, (size_t)(buflen - (end - buf)),
(char *)opt, (char *)fname); (char *)opt, (char *)fname);
} }
else else
@@ -1838,7 +1849,7 @@ append_redir(
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
" %s %s", " %s %s",
#else #else
" %s%s", /* " > %s" causes problems on Amiga */ " %s%s", // " > %s" causes problems on Amiga
#endif #endif
(char *)opt, (char *)fname); (char *)opt, (char *)fname);
} }

View File

@@ -3157,7 +3157,7 @@ call_shell(char_u *cmd, int opt)
{ {
char_u *ecmd = cmd; char_u *ecmd = cmd;
if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) if (*p_sxe != NUL && *p_sxq == '(')
{ {
ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE); ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
if (ecmd == NULL) if (ecmd == NULL)
@@ -3168,11 +3168,11 @@ call_shell(char_u *cmd, int opt)
{ {
STRCPY(ncmd, p_sxq); STRCPY(ncmd, p_sxq);
STRCAT(ncmd, ecmd); STRCAT(ncmd, ecmd);
/* When 'shellxquote' is ( append ). // When 'shellxquote' is ( append ).
* When 'shellxquote' is "( append )". */ // When 'shellxquote' is "( append )".
STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")" STRCAT(ncmd, *p_sxq == '(' ? (char_u *)")"
: STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\"" : *p_sxq == '"' && *(p_sxq+1) == '(' ? (char_u *)")\""
: p_sxq); : p_sxq);
retval = mch_call_shell(ncmd, opt); retval = mch_call_shell(ncmd, opt);
vim_free(ncmd); vim_free(ncmd);
} }

View File

@@ -3,9 +3,24 @@
source shared.vim source shared.vim
func Test_System() func Test_System()
if !executable('echo') || !executable('cat') || !executable('wc') if !has('win32')
call assert_equal("123\n", system('echo 123'))
call assert_equal(['123'], systemlist('echo 123'))
call assert_equal('123', system('cat', '123'))
call assert_equal(['123'], systemlist('cat', '123'))
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
else
call assert_equal("123\n", system('echo 123'))
call assert_equal(["123\r"], systemlist('echo 123'))
call assert_equal("123", system('more', '123'))
call assert_equal(["123"], systemlist('more', '123'))
call assert_equal(["as\<NL>df"], systemlist('more', ["as\<NL>df"]))
endif
if !executable('cat') || !executable('wc')
return return
endif endif
let out = 'echo 123'->system() let out = 'echo 123'->system()
" On Windows we may get a trailing space. " On Windows we may get a trailing space.
if out != "123 \n" if out != "123 \n"
@@ -13,14 +28,17 @@ func Test_System()
endif endif
let out = 'echo 123'->systemlist() let out = 'echo 123'->systemlist()
" On Windows we may get a trailing space and CR. if !has('win32')
if out != ["123 \r"] call assert_equal(["123"], out)
call assert_equal(['123'], out) else
call assert_equal(["123\r"], out)
endif endif
call assert_equal('123', system('cat', '123')) if executable('cat')
call assert_equal(['123'], systemlist('cat', '123')) call assert_equal('123', system('cat', '123'))
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"])) call assert_equal(['123'], systemlist('cat', '123'))
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
endif
new Xdummy new Xdummy
call setline(1, ['asdf', "pw\<NL>er", 'xxxx']) call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
@@ -39,9 +57,11 @@ func Test_System()
call assert_equal(['3'], out) call assert_equal(['3'], out)
endif endif
let out = systemlist('cat', bufnr('%')) if !has('win32')
" On Windows we may get a trailing CR. let out = systemlist('cat', bufnr('%'))
if out != ["asdf\r", "pw\<NL>er\r", "xxxx\r"] call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
else
let out = systemlist('more', bufnr('%'))
call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out) call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
endif endif
bwipe! bwipe!

View File

@@ -757,6 +757,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2092,
/**/ /**/
2091, 2091,
/**/ /**/