aboutsummaryrefslogtreecommitdiffstats
path: root/nt/cmdproxy.c
diff options
context:
space:
mode:
authorPaul Eggert2015-03-03 14:37:43 -0800
committerPaul Eggert2015-03-03 14:37:43 -0800
commite2ae1c5a40e2802fcd9f5ee26b4906be97c8b878 (patch)
treeb2d56b00e2ae8ba90167ede434561d4a3b1f273d /nt/cmdproxy.c
parentd8462361f2d087d6f7c745305c61a266843ee19c (diff)
parent4b0b27d0018f040bda6a2ec885fa54c666d9c083 (diff)
downloademacs-e2ae1c5a40e2802fcd9f5ee26b4906be97c8b878.tar.gz
emacs-e2ae1c5a40e2802fcd9f5ee26b4906be97c8b878.zip
Merge from origin/emacs-24
4b0b27d Fix invocation of commands whose file name includes extension 87fc99f Better support for the case of typing RET on the prompt in comint. a7b1c2f Don't lose frame's background color when setting foreground 20c817d Fix handling of frame color parameters in TTY sessions eca7da1 Complete the remaining documentation updates for 24.5 Conflicts: doc/lispref/ChangeLog etc/NEWS lisp/ChangeLog nt/ChangeLog src/ChangeLog
Diffstat (limited to 'nt/cmdproxy.c')
-rw-r--r--nt/cmdproxy.c72
1 files changed, 66 insertions, 6 deletions
diff --git a/nt/cmdproxy.c b/nt/cmdproxy.c
index faef2f83496..3157a69c1b6 100644
--- a/nt/cmdproxy.c
+++ b/nt/cmdproxy.c
@@ -135,7 +135,10 @@ skip_nonspace (const char *str)
135 return str; 135 return str;
136} 136}
137 137
138int escape_char = '\\'; 138/* This value is never changed by the code. We keep the code that
139 supports also the value of '"', but let's allow the compiler to
140 optimize it out, until someone actually uses that. */
141const int escape_char = '\\';
139 142
140/* Get next token from input, advancing pointer. */ 143/* Get next token from input, advancing pointer. */
141int 144int
@@ -196,11 +199,31 @@ get_next_token (char * buf, const char ** pSrc)
196 /* End of string, but no ending quote found. We might want to 199 /* End of string, but no ending quote found. We might want to
197 flag this as an error, but for now will consider the end as 200 flag this as an error, but for now will consider the end as
198 the end of the token. */ 201 the end of the token. */
202 if (escape_char == '\\')
203 {
204 /* Output literal backslashes. Note that if the
205 token ends with an unpaired backslash, we eat it
206 up here. But since this case invokes undefined
207 behavior anyway, it's okay. */
208 while (escape_char_run > 1)
209 {
210 *o++ = escape_char;
211 escape_char_run -= 2;
212 }
213 }
199 *o = '\0'; 214 *o = '\0';
200 break; 215 break;
201 } 216 }
202 else 217 else
203 { 218 {
219 if (escape_char == '\\')
220 {
221 /* Output literal backslashes. Note that we don't
222 treat a backslash as an escape character here,
223 since it doesn't preceed a quote. */
224 for ( ; escape_char_run > 0; escape_char_run--)
225 *o++ = escape_char;
226 }
204 *o++ = *p++; 227 *o++ = *p++;
205 } 228 }
206 } 229 }
@@ -251,13 +274,44 @@ search_dir (const char *dir, const char *exec, int bufsize, char *buffer)
251 int n_exts = sizeof (exts) / sizeof (char *); 274 int n_exts = sizeof (exts) / sizeof (char *);
252 char *dummy; 275 char *dummy;
253 int i, rc; 276 int i, rc;
277 const char *pext = strrchr (exec, '\\');
278
279 /* Does EXEC already include an extension? */
280 if (!pext)
281 pext = exec;
282 pext = strchr (pext, '.');
254 283
255 /* Search the directory for the program. */ 284 /* Search the directory for the program. */
256 for (i = 0; i < n_exts; i++) 285 if (pext)
257 { 286 {
258 rc = SearchPath (dir, exec, exts[i], bufsize, buffer, &dummy); 287 /* SearchPath will not append an extension if the file already
288 has an extension, so we must append it ourselves. */
289 char exec_ext[MAX_PATH], *p;
290
291 p = strcpy (exec_ext, exec) + strlen (exec);
292
293 /* Search first without any extension; if found, we are done. */
294 rc = SearchPath (dir, exec_ext, NULL, bufsize, buffer, &dummy);
259 if (rc > 0) 295 if (rc > 0)
260 return rc; 296 return rc;
297
298 /* Try the known extensions. */
299 for (i = 0; i < n_exts; i++)
300 {
301 strcpy (p, exts[i]);
302 rc = SearchPath (dir, exec_ext, NULL, bufsize, buffer, &dummy);
303 if (rc > 0)
304 return rc;
305 }
306 }
307 else
308 {
309 for (i = 0; i < n_exts; i++)
310 {
311 rc = SearchPath (dir, exec, exts[i], bufsize, buffer, &dummy);
312 if (rc > 0)
313 return rc;
314 }
261 } 315 }
262 316
263 return 0; 317 return 0;
@@ -798,7 +852,7 @@ main (int argc, char ** argv)
798 quotes, since they are illegal in path names). */ 852 quotes, since they are illegal in path names). */
799 853
800 remlen = maxlen = 854 remlen = maxlen =
801 strlen (progname) + extra_arg_space + strlen (cmdline) + 16; 855 strlen (progname) + extra_arg_space + strlen (cmdline) + 16 + 2;
802 buf = p = alloca (maxlen + 1); 856 buf = p = alloca (maxlen + 1);
803 857
804 /* Quote progname in case it contains spaces. */ 858 /* Quote progname in case it contains spaces. */
@@ -813,10 +867,16 @@ main (int argc, char ** argv)
813 remlen = maxlen - (p - buf); 867 remlen = maxlen - (p - buf);
814 } 868 }
815 869
870 /* Now that we know we will be invoking the shell, quote the
871 command line after the "/c" switch as the shell expects:
872 a single pair of quotes enclosing the entire command
873 tail, no matter whether quotes are used in the command
874 line, and how many of them are there. See the output of
875 "cmd /?" for how cmd.exe treats quotes. */
816 if (run_command_dot_com) 876 if (run_command_dot_com)
817 _snprintf (p, remlen, " /e:%d /c %s", envsize, cmdline); 877 _snprintf (p, remlen, " /e:%d /c \"%s\"", envsize, cmdline);
818 else 878 else
819 _snprintf (p, remlen, " /c %s", cmdline); 879 _snprintf (p, remlen, " /c \"%s\"", cmdline);
820 cmdline = buf; 880 cmdline = buf;
821 } 881 }
822 else 882 else