Mercurial > vim
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 |