]>
Commit | Line | Data |
---|---|---|
c6060300 MT |
1 | To: vim_dev@googlegroups.com |
2 | Subject: Patch 7.3.447 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
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) | |
13 | Files: src/os_win32.c | |
14 | ||
15 | ||
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 | |
18 | *************** | |
19 | *** 259,264 **** | |
20 | --- 259,287 ---- | |
21 | } | |
22 | ||
23 | /* | |
24 | + * Unescape characters in "p" that appear in "escaped". | |
25 | + */ | |
26 | + static void | |
27 | + unescape_shellxquote(char_u *p, char_u *escaped) | |
28 | + { | |
29 | + int l = STRLEN(p); | |
30 | + int n; | |
31 | + | |
32 | + while (*p != NUL) | |
33 | + { | |
34 | + if (*p == '^' && vim_strchr(escaped, p[1]) != NULL) | |
35 | + mch_memmove(p, p + 1, l--); | |
36 | + #ifdef FEAT_MBYTE | |
37 | + n = (*mb_ptr2len)(p); | |
38 | + #else | |
39 | + n = 1; | |
40 | + #endif | |
41 | + p += n; | |
42 | + l -= n; | |
43 | + } | |
44 | + } | |
45 | + | |
46 | + /* | |
47 | * Load library "name". | |
48 | */ | |
49 | HINSTANCE | |
50 | *************** | |
51 | *** 3559,3564 **** | |
52 | --- 3582,3588 ---- | |
53 | garray_T ga; | |
54 | int delay = 1; | |
55 | DWORD buffer_off = 0; /* valid bytes in buffer[] */ | |
56 | + char *p = NULL; | |
57 | ||
58 | SECURITY_ATTRIBUTES saAttr; | |
59 | ||
60 | *************** | |
61 | *** 3599,3607 **** | |
62 | if (options & SHELL_READ) | |
63 | ga_init2(&ga, 1, BUFLEN); | |
64 | ||
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 */ | |
70 | ||
71 | --- 3623,3640 ---- | |
72 | if (options & SHELL_READ) | |
73 | ga_init2(&ga, 1, BUFLEN); | |
74 | ||
75 | + if (cmd != NULL) | |
76 | + { | |
77 | + p = (char *)vim_strsave((char_u *)cmd); | |
78 | + if (p != NULL) | |
79 | + unescape_shellxquote((char_u *)p, p_sxe); | |
80 | + else | |
81 | + p = cmd; | |
82 | + } | |
83 | + | |
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 */ | |
89 | ||
90 | *************** | |
91 | *** 3616,3621 **** | |
92 | --- 3649,3656 ---- | |
93 | &si, /* Startup information */ | |
94 | &pi); /* Process information */ | |
95 | ||
96 | + if (p != cmd) | |
97 | + vim_free(p); | |
98 | ||
99 | /* Close our unused side of the pipes */ | |
100 | CloseHandle(g_hChildStd_IN_Rd); | |
101 | *************** | |
102 | *** 3898,4018 **** | |
103 | else | |
104 | { | |
105 | /* we use "command" or "cmd" to start the shell; slow but easy */ | |
106 | ! char_u *newcmd; | |
107 | ! long_u cmdlen = ( | |
108 | ! #ifdef FEAT_GUI_W32 | |
109 | ! (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) + | |
110 | ! #endif | |
111 | ! STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); | |
112 | ! | |
113 | ! newcmd = lalloc(cmdlen, TRUE); | |
114 | ! if (newcmd != NULL) | |
115 | ! { | |
116 | ! char_u *cmdbase = cmd; | |
117 | ! | |
118 | ! /* Skip a leading ", ( and "(. */ | |
119 | ! if (*cmdbase == '"' ) | |
120 | ! ++cmdbase; | |
121 | ! if (*cmdbase == '(') | |
122 | ! ++cmdbase; | |
123 | ! if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5])) | |
124 | ! { | |
125 | ! STARTUPINFO si; | |
126 | ! PROCESS_INFORMATION pi; | |
127 | ! DWORD flags = CREATE_NEW_CONSOLE; | |
128 | ! | |
129 | ! si.cb = sizeof(si); | |
130 | ! si.lpReserved = NULL; | |
131 | ! si.lpDesktop = NULL; | |
132 | ! si.lpTitle = NULL; | |
133 | ! si.dwFlags = 0; | |
134 | ! si.cbReserved2 = 0; | |
135 | ! si.lpReserved2 = NULL; | |
136 | ! | |
137 | ! cmdbase = skipwhite(cmdbase + 5); | |
138 | ! if ((STRNICMP(cmdbase, "/min", 4) == 0) | |
139 | ! && vim_iswhite(cmdbase[4])) | |
140 | ! { | |
141 | ! cmdbase = skipwhite(cmdbase + 4); | |
142 | ! si.dwFlags = STARTF_USESHOWWINDOW; | |
143 | ! si.wShowWindow = SW_SHOWMINNOACTIVE; | |
144 | ! } | |
145 | ! else if ((STRNICMP(cmdbase, "/b", 2) == 0) | |
146 | ! && vim_iswhite(cmdbase[2])) | |
147 | ! { | |
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 | |
153 | ! 0, // Share 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; | |
160 | ! } | |
161 | ||
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. */ | |
166 | ! if (cmdbase > cmd) | |
167 | ! { | |
168 | ! if (STRNCMP(cmd, p_sxq, cmd - cmdbase) != 0) | |
169 | ! { | |
170 | ! STRCPY(newcmd, cmd); | |
171 | ! } | |
172 | ! else | |
173 | ! { | |
174 | ! char_u *p; | |
175 | ||
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 == '"') | |
181 | ! *--p = NUL; | |
182 | ! if (p > newcmd && p[-1] == ')' | |
183 | ! && (*cmd =='(' || cmd[1] == '(')) | |
184 | ! *--p = NUL; | |
185 | ! } | |
186 | ! } | |
187 | ||
188 | ! /* | |
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 | |
192 | ! */ | |
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 | |
203 | ! x = 0; | |
204 | ! else | |
205 | ! { | |
206 | ! x = -1; | |
207 | #ifdef FEAT_GUI_W32 | |
208 | ! EMSG(_("E371: Command not found")); | |
209 | #endif | |
210 | - } | |
211 | - if (si.hStdInput != NULL) | |
212 | - { | |
213 | - /* Close the handle to \\.\NUL */ | |
214 | - CloseHandle(si.hStdInput); | |
215 | - } | |
216 | - /* Close the handles to the subprocess, so that it goes away */ | |
217 | - CloseHandle(pi.hThread); | |
218 | - CloseHandle(pi.hProcess); | |
219 | } | |
220 | ! else | |
221 | { | |
222 | #if defined(FEAT_GUI_W32) | |
223 | if (need_vimrun_warning) | |
224 | --- 3933,4048 ---- | |
225 | else | |
226 | { | |
227 | /* we use "command" or "cmd" to start the shell; slow but easy */ | |
228 | ! char_u *cmdbase = cmd; | |
229 | ||
230 | ! /* Skip a leading ", ( and "(. */ | |
231 | ! if (*cmdbase == '"' ) | |
232 | ! ++cmdbase; | |
233 | ! if (*cmdbase == '(') | |
234 | ! ++cmdbase; | |
235 | ! | |
236 | ! if ((STRNICMP(cmdbase, "start", 5) == 0) && vim_iswhite(cmdbase[5])) | |
237 | ! { | |
238 | ! STARTUPINFO si; | |
239 | ! PROCESS_INFORMATION pi; | |
240 | ! DWORD flags = CREATE_NEW_CONSOLE; | |
241 | ! char_u *p; | |
242 | ! | |
243 | ! si.cb = sizeof(si); | |
244 | ! si.lpReserved = NULL; | |
245 | ! si.lpDesktop = NULL; | |
246 | ! si.lpTitle = NULL; | |
247 | ! si.dwFlags = 0; | |
248 | ! si.cbReserved2 = 0; | |
249 | ! si.lpReserved2 = NULL; | |
250 | ! | |
251 | ! cmdbase = skipwhite(cmdbase + 5); | |
252 | ! if ((STRNICMP(cmdbase, "/min", 4) == 0) | |
253 | ! && vim_iswhite(cmdbase[4])) | |
254 | ! { | |
255 | ! cmdbase = skipwhite(cmdbase + 4); | |
256 | ! si.dwFlags = STARTF_USESHOWWINDOW; | |
257 | ! si.wShowWindow = SW_SHOWMINNOACTIVE; | |
258 | ! } | |
259 | ! else if ((STRNICMP(cmdbase, "/b", 2) == 0) | |
260 | ! && vim_iswhite(cmdbase[2])) | |
261 | ! { | |
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 | |
267 | ! 0, // Share 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; | |
274 | ! } | |
275 | ! | |
276 | ! /* Remove a trailing ", ) and )" if they have a match | |
277 | ! * at the start of the command. */ | |
278 | ! if (cmdbase > cmd) | |
279 | ! { | |
280 | ! p = cmdbase + STRLEN(cmdbase); | |
281 | ! if (p > cmdbase && p[-1] == '"' && *cmd == '"') | |
282 | ! *--p = NUL; | |
283 | ! if (p > cmdbase && p[-1] == ')' | |
284 | ! && (*cmd =='(' || cmd[1] == '(')) | |
285 | ! *--p = NUL; | |
286 | ! } | |
287 | ||
288 | ! /* | |
289 | ! * Unescape characters in shellxescape. This is workaround for | |
290 | ! * /b option. Only redirect character should be unescaped. | |
291 | ! */ | |
292 | ! unescape_shellxquote(cmdbase, | |
293 | ! (flags & CREATE_NEW_CONSOLE) ? p_sxe : "<>"); | |
294 | ||
295 | ! /* | |
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 | |
299 | ! */ | |
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 | |
310 | ! x = 0; | |
311 | ! else | |
312 | ! { | |
313 | ! x = -1; | |
314 | #ifdef FEAT_GUI_W32 | |
315 | ! EMSG(_("E371: Command not found")); | |
316 | #endif | |
317 | } | |
318 | ! if (si.hStdInput != NULL) | |
319 | ! { | |
320 | ! /* Close the handle to \\.\NUL */ | |
321 | ! CloseHandle(si.hStdInput); | |
322 | ! } | |
323 | ! /* Close the handles to the subprocess, so that it goes away */ | |
324 | ! CloseHandle(pi.hThread); | |
325 | ! CloseHandle(pi.hProcess); | |
326 | ! } | |
327 | ! else | |
328 | ! { | |
329 | ! char_u *newcmd; | |
330 | ! long_u cmdlen = ( | |
331 | ! #ifdef FEAT_GUI_W32 | |
332 | ! (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) + | |
333 | ! #endif | |
334 | ! STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); | |
335 | ! | |
336 | ! newcmd = lalloc(cmdlen, TRUE); | |
337 | ! if (newcmd != NULL) | |
338 | { | |
339 | #if defined(FEAT_GUI_W32) | |
340 | if (need_vimrun_warning) | |
341 | *************** | |
342 | *** 4038,4045 **** | |
343 | vim_snprintf((char *)newcmd, cmdlen, "%s %s %s", | |
344 | p_sh, p_shcf, cmd); | |
345 | x = mch_system((char *)newcmd, options); | |
346 | } | |
347 | - vim_free(newcmd); | |
348 | } | |
349 | } | |
350 | ||
351 | --- 4068,4075 ---- | |
352 | vim_snprintf((char *)newcmd, cmdlen, "%s %s %s", | |
353 | p_sh, p_shcf, cmd); | |
354 | x = mch_system((char *)newcmd, options); | |
355 | + vim_free(newcmd); | |
356 | } | |
357 | } | |
358 | } | |
359 | ||
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 | |
362 | *************** | |
363 | *** 716,717 **** | |
364 | --- 716,719 ---- | |
365 | { /* Add new patch number below this line */ | |
366 | + /**/ | |
367 | + 447, | |
368 | /**/ | |
369 | ||
370 | -- | |
371 | From "know your smileys": | |
372 | :----} You lie like Pinocchio | |
373 | ||
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 /// |