1 To: vim_dev@googlegroups.com
4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
10 Patch 7.3.447 (after 7.3.446)
11 Problem: Win32: External commands with "start" do not work.
12 Solution: Unescape part of the command. (Yasuhiro Matsumoto)
16 *** ../vim-7.3.446/src/os_win32.c 2012-02-19 18:19:24.000000000 +0100
17 --- src/os_win32.c 2012-02-21 20:56:51.000000000 +0100
24 + * Unescape characters in "p" that appear in "escaped".
27 + unescape_shellxquote(char_u *p, char_u *escaped)
34 + if (*p == '^' && vim_strchr(escaped, p[1]) != NULL)
35 + mch_memmove(p, p + 1, l--);
37 + n = (*mb_ptr2len)(p);
47 * Load library "name".
55 DWORD buffer_off = 0; /* valid bytes in buffer[] */
58 SECURITY_ATTRIBUTES saAttr;
62 if (options & SHELL_READ)
63 ga_init2(&ga, 1, BUFLEN);
65 /* Now, run the command */
66 CreateProcess(NULL, /* Executable name */
67 ! cmd, /* Command to execute */
68 NULL, /* Process security attributes */
69 NULL, /* Thread security attributes */
72 if (options & SHELL_READ)
73 ga_init2(&ga, 1, BUFLEN);
77 + p = (char *)vim_strsave((char_u *)cmd);
79 + unescape_shellxquote((char_u *)p, p_sxe);
84 /* Now, run the command */
85 CreateProcess(NULL, /* Executable name */
86 ! p, /* Command to execute */
87 NULL, /* Process security attributes */
88 NULL, /* Thread security attributes */
93 &si, /* Startup information */
94 &pi); /* Process information */
99 /* Close our unused side of the pipes */
100 CloseHandle(g_hChildStd_IN_Rd);
105 /* we use "command" or "cmd" to start the shell; slow but easy */
108 ! #ifdef FEAT_GUI_W32
109 ! (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) +
111 ! STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
113 ! newcmd = lalloc(cmdlen, TRUE);
114 ! if (newcmd != NULL)
116 ! char_u *cmdbase = cmd;
118 ! /* Skip a leading ", ( and "(. */
119 ! if (*cmdbase == '"' )
121 ! if (*cmdbase == '(')
123 ! if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5]))
126 ! PROCESS_INFORMATION pi;
127 ! DWORD flags = CREATE_NEW_CONSOLE;
129 ! si.cb = sizeof(si);
130 ! si.lpReserved = NULL;
131 ! si.lpDesktop = NULL;
134 ! si.cbReserved2 = 0;
135 ! si.lpReserved2 = NULL;
137 ! cmdbase = skipwhite(cmdbase + 5);
138 ! if ((STRNICMP(cmdbase, "/min", 4) == 0)
139 ! && vim_iswhite(cmdbase[4]))
141 ! cmdbase = skipwhite(cmdbase + 4);
142 ! si.dwFlags = STARTF_USESHOWWINDOW;
143 ! si.wShowWindow = SW_SHOWMINNOACTIVE;
145 ! else if ((STRNICMP(cmdbase, "/b", 2) == 0)
146 ! && vim_iswhite(cmdbase[2]))
148 ! cmdbase = skipwhite(cmdbase + 2);
149 ! flags = CREATE_NO_WINDOW;
150 ! si.dwFlags = STARTF_USESTDHANDLES;
151 ! si.hStdInput = CreateFile("\\\\.\\NUL", // File name
152 ! GENERIC_READ, // Access flags
154 ! NULL, // Security att.
155 ! OPEN_EXISTING, // Open flags
156 ! FILE_ATTRIBUTE_NORMAL, // File att.
157 ! NULL); // Temp file
158 ! si.hStdOutput = si.hStdInput;
159 ! si.hStdError = si.hStdInput;
162 ! /* When the command is in double quotes, but 'shellxquote' is
163 ! * empty, keep the double quotes around the command.
164 ! * Otherwise remove the double quotes, they aren't needed
165 ! * here, because we don't use a shell to run the command. */
168 ! if (STRNCMP(cmd, p_sxq, cmd - cmdbase) != 0)
170 ! STRCPY(newcmd, cmd);
176 ! STRCPY(newcmd, cmdbase);
177 ! /* Remove a trailing ", ) and )" if they have a match
178 ! * at the start of the command. */
179 ! p = newcmd + STRLEN(newcmd);
180 ! if (p > newcmd && p[-1] == '"' && *cmd == '"')
182 ! if (p > newcmd && p[-1] == ')'
183 ! && (*cmd =='(' || cmd[1] == '('))
189 ! * Now, start the command as a process, so that it doesn't
190 ! * inherit our handles which causes unpleasant dangling swap
191 ! * files if we exit before the spawned process
193 ! if (CreateProcess(NULL, // Executable name
194 ! newcmd, // Command to execute
195 ! NULL, // Process security attributes
196 ! NULL, // Thread security attributes
197 ! FALSE, // Inherit handles
198 ! flags, // Creation flags
199 ! NULL, // Environment
200 ! NULL, // Current directory
201 ! &si, // Startup information
202 ! &pi)) // Process information
208 ! EMSG(_("E371: Command not found"));
211 - if (si.hStdInput != NULL)
213 - /* Close the handle to \\.\NUL */
214 - CloseHandle(si.hStdInput);
216 - /* Close the handles to the subprocess, so that it goes away */
217 - CloseHandle(pi.hThread);
218 - CloseHandle(pi.hProcess);
222 #if defined(FEAT_GUI_W32)
223 if (need_vimrun_warning)
227 /* we use "command" or "cmd" to start the shell; slow but easy */
228 ! char_u *cmdbase = cmd;
230 ! /* Skip a leading ", ( and "(. */
231 ! if (*cmdbase == '"' )
233 ! if (*cmdbase == '(')
236 ! if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5]))
239 ! PROCESS_INFORMATION pi;
240 ! DWORD flags = CREATE_NEW_CONSOLE;
243 ! si.cb = sizeof(si);
244 ! si.lpReserved = NULL;
245 ! si.lpDesktop = NULL;
248 ! si.cbReserved2 = 0;
249 ! si.lpReserved2 = NULL;
251 ! cmdbase = skipwhite(cmdbase + 5);
252 ! if ((STRNICMP(cmdbase, "/min", 4) == 0)
253 ! && vim_iswhite(cmdbase[4]))
255 ! cmdbase = skipwhite(cmdbase + 4);
256 ! si.dwFlags = STARTF_USESHOWWINDOW;
257 ! si.wShowWindow = SW_SHOWMINNOACTIVE;
259 ! else if ((STRNICMP(cmdbase, "/b", 2) == 0)
260 ! && vim_iswhite(cmdbase[2]))
262 ! cmdbase = skipwhite(cmdbase + 2);
263 ! flags = CREATE_NO_WINDOW;
264 ! si.dwFlags = STARTF_USESTDHANDLES;
265 ! si.hStdInput = CreateFile("\\\\.\\NUL", // File name
266 ! GENERIC_READ, // Access flags
268 ! NULL, // Security att.
269 ! OPEN_EXISTING, // Open flags
270 ! FILE_ATTRIBUTE_NORMAL, // File att.
271 ! NULL); // Temp file
272 ! si.hStdOutput = si.hStdInput;
273 ! si.hStdError = si.hStdInput;
276 ! /* Remove a trailing ", ) and )" if they have a match
277 ! * at the start of the command. */
280 ! p = cmdbase + STRLEN(cmdbase);
281 ! if (p > cmdbase && p[-1] == '"' && *cmd == '"')
283 ! if (p > cmdbase && p[-1] == ')'
284 ! && (*cmd =='(' || cmd[1] == '('))
289 ! * Unescape characters in shellxescape. This is workaround for
290 ! * /b option. Only redirect character should be unescaped.
292 ! unescape_shellxquote(cmdbase,
293 ! (flags & CREATE_NEW_CONSOLE) ? p_sxe : "<>");
296 ! * Now, start the command as a process, so that it doesn't
297 ! * inherit our handles which causes unpleasant dangling swap
298 ! * files if we exit before the spawned process
300 ! if (CreateProcess(NULL, // Executable name
301 ! cmdbase, // Command to execute
302 ! NULL, // Process security attributes
303 ! NULL, // Thread security attributes
304 ! FALSE, // Inherit handles
305 ! flags, // Creation flags
306 ! NULL, // Environment
307 ! NULL, // Current directory
308 ! &si, // Startup information
309 ! &pi)) // Process information
315 ! EMSG(_("E371: Command not found"));
318 ! if (si.hStdInput != NULL)
320 ! /* Close the handle to \\.\NUL */
321 ! CloseHandle(si.hStdInput);
323 ! /* Close the handles to the subprocess, so that it goes away */
324 ! CloseHandle(pi.hThread);
325 ! CloseHandle(pi.hProcess);
331 ! #ifdef FEAT_GUI_W32
332 ! (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) +
334 ! STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
336 ! newcmd = lalloc(cmdlen, TRUE);
337 ! if (newcmd != NULL)
339 #if defined(FEAT_GUI_W32)
340 if (need_vimrun_warning)
343 vim_snprintf((char *)newcmd, cmdlen, "%s %s %s",
345 x = mch_system((char *)newcmd, options);
352 vim_snprintf((char *)newcmd, cmdlen, "%s %s %s",
354 x = mch_system((char *)newcmd, options);
360 *** ../vim-7.3.446/src/version.c 2012-02-20 22:18:23.000000000 +0100
361 --- src/version.c 2012-02-21 21:20:05.000000000 +0100
365 { /* Add new patch number below this line */
371 From "know your smileys":
372 :----} You lie like Pinocchio
374 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
375 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
376 \\\ an exciting new programming language -- http://www.Zimbu.org ///
377 \\\ help me help AIDS victims -- http://ICCF-Holland.org ///