comparison src/os_win32.c @ 3363:756d712b3118 v7.3.448

updated for version 7.3.448 Problem: Win32: Still a problem with "!start /b". Solution: Escape only '|'. (Yasuhiro Matsumoto)
author Bram Moolenaar <bram@vim.org>
date Wed, 22 Feb 2012 13:07:05 +0100
parents 6a03b0ea2e12
children 3479ac596f6c
comparison
equal deleted inserted replaced
3362:dd78da101764 3363:756d712b3118
3931 x = mch_system(p_sh, options); 3931 x = mch_system(p_sh, options);
3932 } 3932 }
3933 else 3933 else
3934 { 3934 {
3935 /* we use "command" or "cmd" to start the shell; slow but easy */ 3935 /* we use "command" or "cmd" to start the shell; slow but easy */
3936 char_u *cmdbase = cmd; 3936 char_u *newcmd = NULL;
3937 char_u *cmdbase = cmd;
3938 long_u cmdlen;
3937 3939
3938 /* Skip a leading ", ( and "(. */ 3940 /* Skip a leading ", ( and "(. */
3939 if (*cmdbase == '"' ) 3941 if (*cmdbase == '"' )
3940 ++cmdbase; 3942 ++cmdbase;
3941 if (*cmdbase == '(') 3943 if (*cmdbase == '(')
3969 { 3971 {
3970 cmdbase = skipwhite(cmdbase + 2); 3972 cmdbase = skipwhite(cmdbase + 2);
3971 flags = CREATE_NO_WINDOW; 3973 flags = CREATE_NO_WINDOW;
3972 si.dwFlags = STARTF_USESTDHANDLES; 3974 si.dwFlags = STARTF_USESTDHANDLES;
3973 si.hStdInput = CreateFile("\\\\.\\NUL", // File name 3975 si.hStdInput = CreateFile("\\\\.\\NUL", // File name
3974 GENERIC_READ, // Access flags 3976 GENERIC_READ, // Access flags
3975 0, // Share flags 3977 0, // Share flags
3976 NULL, // Security att. 3978 NULL, // Security att.
3977 OPEN_EXISTING, // Open flags 3979 OPEN_EXISTING, // Open flags
3978 FILE_ATTRIBUTE_NORMAL, // File att. 3980 FILE_ATTRIBUTE_NORMAL, // File att.
3979 NULL); // Temp file 3981 NULL); // Temp file
3980 si.hStdOutput = si.hStdInput; 3982 si.hStdOutput = si.hStdInput;
3981 si.hStdError = si.hStdInput; 3983 si.hStdError = si.hStdInput;
3982 } 3984 }
3983 3985
3984 /* Remove a trailing ", ) and )" if they have a match 3986 /* Remove a trailing ", ) and )" if they have a match
3991 if (p > cmdbase && p[-1] == ')' 3993 if (p > cmdbase && p[-1] == ')'
3992 && (*cmd =='(' || cmd[1] == '(')) 3994 && (*cmd =='(' || cmd[1] == '('))
3993 *--p = NUL; 3995 *--p = NUL;
3994 } 3996 }
3995 3997
3998 newcmd = cmdbase;
3999 unescape_shellxquote(cmdbase, p_sxe);
4000
3996 /* 4001 /*
3997 * Unescape characters in shellxescape. This is workaround for 4002 * If creating new console, arguments are passed to the
3998 * /b option. Only redirect character should be unescaped. 4003 * 'cmd.exe' as-is. If it's not, arguments are not treated
4004 * correctly for current 'cmd.exe'. So unescape characters in
4005 * shellxescape except '|' for avoiding to be treated as
4006 * argument to them. Pass the arguments to sub-shell.
3999 */ 4007 */
4000 unescape_shellxquote(cmdbase, 4008 if (flags != CREATE_NEW_CONSOLE)
4001 (flags & CREATE_NEW_CONSOLE) ? p_sxe : "<>"); 4009 {
4010 char_u *subcmd;
4011 char_u *cmd_shell = default_shell();
4012
4013 subcmd = vim_strsave_escaped_ext(cmdbase, "|", '^', FALSE);
4014 if (subcmd != NULL)
4015 {
4016 /* make "cmd.exe /c arguments" */
4017 cmdlen = STRLEN(cmd_shell) + STRLEN(subcmd) + 5;
4018 vim_free(subcmd);
4019
4020 newcmd = lalloc(cmdlen, TRUE);
4021 if (newcmd != NULL)
4022 vim_snprintf((char *)newcmd, cmdlen, "%s /c %s",
4023 default_shell, subcmd);
4024 else
4025 newcmd = cmdbase;
4026 }
4027 }
4002 4028
4003 /* 4029 /*
4004 * Now, start the command as a process, so that it doesn't 4030 * Now, start the command as a process, so that it doesn't
4005 * inherit our handles which causes unpleasant dangling swap 4031 * inherit our handles which causes unpleasant dangling swap
4006 * files if we exit before the spawned process 4032 * files if we exit before the spawned process
4007 */ 4033 */
4008 if (CreateProcess(NULL, // Executable name 4034 if (CreateProcess(NULL, // Executable name
4009 cmdbase, // Command to execute 4035 newcmd, // Command to execute
4010 NULL, // Process security attributes 4036 NULL, // Process security attributes
4011 NULL, // Thread security attributes 4037 NULL, // Thread security attributes
4012 FALSE, // Inherit handles 4038 FALSE, // Inherit handles
4013 flags, // Creation flags 4039 flags, // Creation flags
4014 NULL, // Environment 4040 NULL, // Environment
4021 x = -1; 4047 x = -1;
4022 #ifdef FEAT_GUI_W32 4048 #ifdef FEAT_GUI_W32
4023 EMSG(_("E371: Command not found")); 4049 EMSG(_("E371: Command not found"));
4024 #endif 4050 #endif
4025 } 4051 }
4052
4053 if (newcmd != cmdbase)
4054 vim_free(newcmd);
4055
4026 if (si.hStdInput != NULL) 4056 if (si.hStdInput != NULL)
4027 { 4057 {
4028 /* Close the handle to \\.\NUL */ 4058 /* Close the handle to \\.\NUL */
4029 CloseHandle(si.hStdInput); 4059 CloseHandle(si.hStdInput);
4030 } 4060 }
4032 CloseHandle(pi.hThread); 4062 CloseHandle(pi.hThread);
4033 CloseHandle(pi.hProcess); 4063 CloseHandle(pi.hProcess);
4034 } 4064 }
4035 else 4065 else
4036 { 4066 {
4037 char_u *newcmd; 4067 cmdlen = (
4038 long_u cmdlen = (
4039 #ifdef FEAT_GUI_W32 4068 #ifdef FEAT_GUI_W32
4040 (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) + 4069 (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) +
4041 #endif 4070 #endif
4042 STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); 4071 STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
4043 4072