mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-09 10:26:21 +00:00
Perform better fixups of NT paths in execve()
This change ensures we do a better job translating /c/foo.bar paths into c:/foo.bar paths on Windows when generating the CreateProcess() cmd line thus fixing a regression that happened in the last two months when using the help() feature of Actually Portable Python in the CMD.EXE shell.
This commit is contained in:
parent
cfb5d3e406
commit
701564de19
4 changed files with 50 additions and 10 deletions
|
@ -41,6 +41,10 @@ static bool NeedsQuotes(const char *s) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int IsAlpha(int c) {
|
||||||
|
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts System V argv to Windows-style command line.
|
* Converts System V argv to Windows-style command line.
|
||||||
*
|
*
|
||||||
|
@ -86,8 +90,27 @@ textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!x) break;
|
if (!x) break;
|
||||||
if (!i && x == '/') {
|
if (x == '/' || x == '\\') {
|
||||||
x = '\\';
|
if (!i) {
|
||||||
|
// turn / into \ for first arg
|
||||||
|
x = '\\';
|
||||||
|
// turn \c\... into c:\ for first arg
|
||||||
|
if (k == 2 && IsAlpha(cmdline[1]) && cmdline[0] == '\\') {
|
||||||
|
cmdline[0] = cmdline[1];
|
||||||
|
cmdline[1] = ':';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// turn stuff like `less /c/...`
|
||||||
|
// into `less c:/...`
|
||||||
|
// turn stuff like `more <\\\"/c/...\\\"`
|
||||||
|
// into `more <\\\"c:/...\\\"`
|
||||||
|
if (k > 3 && IsAlpha(cmdline[k - 1]) &&
|
||||||
|
(cmdline[k - 2] == '/' || cmdline[k - 2] == '\\') &&
|
||||||
|
(cmdline[k - 3] == '"' || cmdline[k - 3] == ' ')) {
|
||||||
|
cmdline[k - 2] = cmdline[k - 1];
|
||||||
|
cmdline[k - 1] = ':';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (x == '\\') {
|
if (x == '\\') {
|
||||||
++slashes;
|
++slashes;
|
||||||
|
|
|
@ -72,12 +72,14 @@ static textwindows void FixPath(char *path) {
|
||||||
|
|
||||||
// turn \c\... into c:\...
|
// turn \c\... into c:\...
|
||||||
p = path;
|
p = path;
|
||||||
if (p[0] == '/' && IsAlpha(p[1]) && p[2] == '/') {
|
if ((p[0] == '/' | p[0] == '\\') && IsAlpha(p[1]) &&
|
||||||
|
(p[2] == '/' || p[2] == '\\')) {
|
||||||
p[0] = p[1];
|
p[0] = p[1];
|
||||||
p[1] = ':';
|
p[1] = ':';
|
||||||
}
|
}
|
||||||
for (; *p; ++p) {
|
for (; *p; ++p) {
|
||||||
if (p[0] == ';' && p[1] == '/' && IsAlpha(p[2]) && p[3] == '/') {
|
if (p[0] == ';' && (p[1] == '/' || p[1] == '\\') && IsAlpha(p[2]) &&
|
||||||
|
(p[3] == '/' || p[3] == '\\')) {
|
||||||
p[1] = p[2];
|
p[1] = p[2];
|
||||||
p[2] = ':';
|
p[2] = ':';
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,8 +79,10 @@ const char *DescribeStat(int rc, const struct stat *st) {
|
||||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%'lu", "blksize", st->st_blksize);
|
i += ksnprintf(buf + i, n - i, ", .st_%s=%'lu", "blksize", st->st_blksize);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i++] = '}';
|
if (n - i >= 2) {
|
||||||
buf[i] = 0;
|
buf[i + 0] = '}';
|
||||||
|
buf[i + 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,16 +78,29 @@ TEST(mkntcmdline, testUnicode) {
|
||||||
cmdline);
|
cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(mkntcmdline, fix) {
|
TEST(mkntcmdline, fixAsBestAsWeCanForNow1) {
|
||||||
char *argv1[] = {
|
char *argv1[] = {
|
||||||
"C:/WINDOWS/system32/cmd.exe",
|
"/C/WINDOWS/system32/cmd.exe",
|
||||||
"/C",
|
"/C",
|
||||||
"more < \"C:\\Users\\jart\\AppData\\Local\\Temp\\tmplquaa_d6\"",
|
"more < \"/C/Users/jart/AppData/Local/Temp/tmplquaa_d6\"",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
EXPECT_NE(-1, mkntcmdline(cmdline, argv1[0], argv1));
|
EXPECT_NE(-1, mkntcmdline(cmdline, argv1[0], argv1));
|
||||||
EXPECT_STREQ(u"C:\\WINDOWS\\system32\\cmd.exe /C \"more < "
|
EXPECT_STREQ(u"C:\\WINDOWS\\system32\\cmd.exe /C \"more < "
|
||||||
u"\\\"C:\\Users\\jart\\AppData\\Local\\Temp\\tmplquaa_d6\\\"\"",
|
u"\\\"C:/Users/jart/AppData/Local/Temp/tmplquaa_d6\\\"\"",
|
||||||
|
cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mkntcmdline, fixAsBestAsWeCanForNow2) {
|
||||||
|
char *argv1[] = {
|
||||||
|
"/C/WINDOWS/system32/cmd.exe",
|
||||||
|
"/C",
|
||||||
|
"less /C/Users/jart/AppData/Local/Temp/tmplquaa_d6",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
EXPECT_NE(-1, mkntcmdline(cmdline, argv1[0], argv1));
|
||||||
|
EXPECT_STREQ(u"C:\\WINDOWS\\system32\\cmd.exe /C \"less "
|
||||||
|
u"C:/Users/jart/AppData/Local/Temp/tmplquaa_d6\"",
|
||||||
cmdline);
|
cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue