0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

updated for version 7.3.447

Problem:    Win32: External commands with "start" do not work.
Solution:   Unescape part of the command. (Yasuhiro Matsumoto)
This commit is contained in:
Bram Moolenaar
2012-02-21 21:22:44 +01:00
parent f66b3fcf6c
commit 6b707b4b82
2 changed files with 144 additions and 112 deletions

View File

@@ -258,6 +258,29 @@ get_exe_name(void)
} }
} }
/*
* Unescape characters in "p" that appear in "escaped".
*/
static void
unescape_shellxquote(char_u *p, char_u *escaped)
{
int l = STRLEN(p);
int n;
while (*p != NUL)
{
if (*p == '^' && vim_strchr(escaped, p[1]) != NULL)
mch_memmove(p, p + 1, l--);
#ifdef FEAT_MBYTE
n = (*mb_ptr2len)(p);
#else
n = 1;
#endif
p += n;
l -= n;
}
}
/* /*
* Load library "name". * Load library "name".
*/ */
@@ -3559,6 +3582,7 @@ mch_system_piped(char *cmd, int options)
garray_T ga; garray_T ga;
int delay = 1; int delay = 1;
DWORD buffer_off = 0; /* valid bytes in buffer[] */ DWORD buffer_off = 0; /* valid bytes in buffer[] */
char *p = NULL;
SECURITY_ATTRIBUTES saAttr; SECURITY_ATTRIBUTES saAttr;
@@ -3599,9 +3623,18 @@ mch_system_piped(char *cmd, int options)
if (options & SHELL_READ) if (options & SHELL_READ)
ga_init2(&ga, 1, BUFLEN); ga_init2(&ga, 1, BUFLEN);
if (cmd != NULL)
{
p = (char *)vim_strsave((char_u *)cmd);
if (p != NULL)
unescape_shellxquote((char_u *)p, p_sxe);
else
p = cmd;
}
/* Now, run the command */ /* Now, run the command */
CreateProcess(NULL, /* Executable name */ CreateProcess(NULL, /* Executable name */
cmd, /* Command to execute */ p, /* Command to execute */
NULL, /* Process security attributes */ NULL, /* Process security attributes */
NULL, /* Thread security attributes */ NULL, /* Thread security attributes */
@@ -3616,6 +3649,8 @@ mch_system_piped(char *cmd, int options)
&si, /* Startup information */ &si, /* Startup information */
&pi); /* Process information */ &pi); /* Process information */
if (p != cmd)
vim_free(p);
/* Close our unused side of the pipes */ /* Close our unused side of the pipes */
CloseHandle(g_hChildStd_IN_Rd); CloseHandle(g_hChildStd_IN_Rd);
@@ -3898,16 +3933,6 @@ mch_call_shell(
else else
{ {
/* we use "command" or "cmd" to start the shell; slow but easy */ /* we use "command" or "cmd" to start the shell; slow but easy */
char_u *newcmd;
long_u cmdlen = (
#ifdef FEAT_GUI_W32
(allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) +
#endif
STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
newcmd = lalloc(cmdlen, TRUE);
if (newcmd != NULL)
{
char_u *cmdbase = cmd; char_u *cmdbase = cmd;
/* Skip a leading ", ( and "(. */ /* Skip a leading ", ( and "(. */
@@ -3915,11 +3940,13 @@ mch_call_shell(
++cmdbase; ++cmdbase;
if (*cmdbase == '(') if (*cmdbase == '(')
++cmdbase; ++cmdbase;
if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5])) if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5]))
{ {
STARTUPINFO si; STARTUPINFO si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
DWORD flags = CREATE_NEW_CONSOLE; DWORD flags = CREATE_NEW_CONSOLE;
char_u *p;
si.cb = sizeof(si); si.cb = sizeof(si);
si.lpReserved = NULL; si.lpReserved = NULL;
@@ -3954,31 +3981,24 @@ mch_call_shell(
si.hStdError = si.hStdInput; si.hStdError = si.hStdInput;
} }
/* When the command is in double quotes, but 'shellxquote' is
* empty, keep the double quotes around the command.
* Otherwise remove the double quotes, they aren't needed
* here, because we don't use a shell to run the command. */
if (cmdbase > cmd)
{
if (STRNCMP(cmd, p_sxq, cmd - cmdbase) != 0)
{
STRCPY(newcmd, cmd);
}
else
{
char_u *p;
STRCPY(newcmd, cmdbase);
/* Remove a trailing ", ) and )" if they have a match /* Remove a trailing ", ) and )" if they have a match
* at the start of the command. */ * at the start of the command. */
p = newcmd + STRLEN(newcmd); if (cmdbase > cmd)
if (p > newcmd && p[-1] == '"' && *cmd == '"') {
p = cmdbase + STRLEN(cmdbase);
if (p > cmdbase && p[-1] == '"' && *cmd == '"')
*--p = NUL; *--p = NUL;
if (p > newcmd && p[-1] == ')' if (p > cmdbase && p[-1] == ')'
&& (*cmd =='(' || cmd[1] == '(')) && (*cmd =='(' || cmd[1] == '('))
*--p = NUL; *--p = NUL;
} }
}
/*
* Unescape characters in shellxescape. This is workaround for
* /b option. Only redirect character should be unescaped.
*/
unescape_shellxquote(cmdbase,
(flags & CREATE_NEW_CONSOLE) ? p_sxe : "<>");
/* /*
* Now, start the command as a process, so that it doesn't * Now, start the command as a process, so that it doesn't
@@ -3986,7 +4006,7 @@ mch_call_shell(
* files if we exit before the spawned process * files if we exit before the spawned process
*/ */
if (CreateProcess(NULL, // Executable name if (CreateProcess(NULL, // Executable name
newcmd, // Command to execute cmdbase, // Command to execute
NULL, // Process security attributes NULL, // Process security attributes
NULL, // Thread security attributes NULL, // Thread security attributes
FALSE, // Inherit handles FALSE, // Inherit handles
@@ -4014,6 +4034,16 @@ mch_call_shell(
} }
else else
{ {
char_u *newcmd;
long_u cmdlen = (
#ifdef FEAT_GUI_W32
(allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) +
#endif
STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
newcmd = lalloc(cmdlen, TRUE);
if (newcmd != NULL)
{
#if defined(FEAT_GUI_W32) #if defined(FEAT_GUI_W32)
if (need_vimrun_warning) if (need_vimrun_warning)
{ {
@@ -4038,10 +4068,10 @@ mch_call_shell(
vim_snprintf((char *)newcmd, cmdlen, "%s %s %s", vim_snprintf((char *)newcmd, cmdlen, "%s %s %s",
p_sh, p_shcf, cmd); p_sh, p_shcf, cmd);
x = mch_system((char *)newcmd, options); x = mch_system((char *)newcmd, options);
}
vim_free(newcmd); vim_free(newcmd);
} }
} }
}
if (tmode == TMODE_RAW) if (tmode == TMODE_RAW)
settmode(TMODE_RAW); /* set to raw mode */ settmode(TMODE_RAW); /* set to raw mode */

View File

@@ -714,6 +714,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 */
/**/
447,
/**/ /**/
446, 446,
/**/ /**/