return str;
}
-int escape_char = '\\';
+/* This value is never changed by the code. We keep the code that
+ supports also the value of '"', but let's allow the compiler to
+ optimize it out, until someone actually uses that. */
+const int escape_char = '\\';
/* Get next token from input, advancing pointer. */
int
/* End of string, but no ending quote found. We might want to
flag this as an error, but for now will consider the end as
the end of the token. */
+ if (escape_char == '\\')
+ {
+ /* Output literal backslashes. Note that if the
+ token ends with an unpaired backslash, we eat it
+ up here. But since this case invokes undefined
+ behavior anyway, it's okay. */
+ while (escape_char_run > 1)
+ {
+ *o++ = escape_char;
+ escape_char_run -= 2;
+ }
+ }
*o = '\0';
break;
}
else
{
+ if (escape_char == '\\')
+ {
+ /* Output literal backslashes. Note that we don't
+ treat a backslash as an escape character here,
+ since it doesn't preceed a quote. */
+ for ( ; escape_char_run > 0; escape_char_run--)
+ *o++ = escape_char;
+ }
*o++ = *p++;
}
}
int n_exts = sizeof (exts) / sizeof (char *);
char *dummy;
int i, rc;
+ const char *pext = strrchr (exec, '\\');
+
+ /* Does EXEC already include an extension? */
+ if (!pext)
+ pext = exec;
+ pext = strchr (pext, '.');
/* Search the directory for the program. */
- for (i = 0; i < n_exts; i++)
+ if (pext)
{
- rc = SearchPath (dir, exec, exts[i], bufsize, buffer, &dummy);
+ /* SearchPath will not append an extension if the file already
+ has an extension, so we must append it ourselves. */
+ char exec_ext[MAX_PATH], *p;
+
+ p = strcpy (exec_ext, exec) + strlen (exec);
+
+ /* Search first without any extension; if found, we are done. */
+ rc = SearchPath (dir, exec_ext, NULL, bufsize, buffer, &dummy);
if (rc > 0)
return rc;
+
+ /* Try the known extensions. */
+ for (i = 0; i < n_exts; i++)
+ {
+ strcpy (p, exts[i]);
+ rc = SearchPath (dir, exec_ext, NULL, bufsize, buffer, &dummy);
+ if (rc > 0)
+ return rc;
+ }
+ }
+ else
+ {
+ for (i = 0; i < n_exts; i++)
+ {
+ rc = SearchPath (dir, exec, exts[i], bufsize, buffer, &dummy);
+ if (rc > 0)
+ return rc;
+ }
}
return 0;
quotes, since they are illegal in path names). */
remlen = maxlen =
- strlen (progname) + extra_arg_space + strlen (cmdline) + 16;
+ strlen (progname) + extra_arg_space + strlen (cmdline) + 16 + 2;
buf = p = alloca (maxlen + 1);
/* Quote progname in case it contains spaces. */
remlen = maxlen - (p - buf);
}
+ /* Now that we know we will be invoking the shell, quote the
+ command line after the "/c" switch as the shell expects:
+ a single pair of quotes enclosing the entire command
+ tail, no matter whether quotes are used in the command
+ line, and how many of them are there. See the output of
+ "cmd /?" for how cmd.exe treats quotes. */
if (run_command_dot_com)
- _snprintf (p, remlen, " /e:%d /c %s", envsize, cmdline);
+ _snprintf (p, remlen, " /e:%d /c \"%s\"", envsize, cmdline);
else
- _snprintf (p, remlen, " /c %s", cmdline);
+ _snprintf (p, remlen, " /c \"%s\"", cmdline);
cmdline = buf;
}
else