]> git.pld-linux.org Git - packages/vim.git/blob - 7.3.447
- up to 7.3.600
[packages/vim.git] / 7.3.447
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    ///
This page took 0.08557 seconds and 3 git commands to generate.