diff --git a/libc/calls/fixenotdir.c b/libc/calls/fixenotdir.c index 8787578a6..1537ea69c 100644 --- a/libc/calls/fixenotdir.c +++ b/libc/calls/fixenotdir.c @@ -23,10 +23,20 @@ #include "libc/nt/files.h" #include "libc/str/str.h" +static int IsAlpha(int c) { + return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); +} + static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) { char16_t *p; uint32_t attrs; while ((p = strrchr16(path, '\\'))) { + if (p == path) + // don't bother checking GetFileAttributes(u"\\") + break; + if (p == path + 2 && IsAlpha(path[0]) && path[1] == ':') + // don't bother checking GetFileAttributes(u"C:\\") + break; *p = u'\0'; if ((attrs = GetFileAttributes(path)) != -1u && !(attrs & kNtFileAttributeDirectory)) { diff --git a/libc/calls/mkntpathat.c b/libc/calls/mkntpathat.c index 1b9992704..a263cd838 100644 --- a/libc/calls/mkntpathat.c +++ b/libc/calls/mkntpathat.c @@ -75,6 +75,7 @@ static textwindows int __mkntpathath_impl(int64_t dirhand, const char *path, return n; } else { + filelen = __normntpath(file, filelen); return filelen; } } @@ -84,23 +85,20 @@ textwindows int __mkntpathath(int64_t dirhand, const char *path, int flags, // convert the path. int len; - if ((len = __mkntpathath_impl(dirhand, path, flags, file)) == -1) { + if ((len = __mkntpathath_impl(dirhand, path, flags, file)) == -1) return -1; - } // if path ends with a slash, then we need to manually do what linux // does and check to make sure it's a directory, and return ENOTDIR, // since WIN32 will reject the path with EINVAL if we don't do this. if (len && file[len - 1] == '\\') { uint32_t fattr; - if (len > 1 && !(len == 3 && file[1] == ':')) { + if (len > 1 && !(len == 3 && file[1] == ':')) file[--len] = 0; - } if ((fattr = GetFileAttributes(file)) != -1u && !(fattr & kNtFileAttributeReparsePoint) && - !(fattr & kNtFileAttributeDirectory)) { + !(fattr & kNtFileAttributeDirectory)) return enotdir(); - } } return len; diff --git a/libc/dlopen/dlopen.c b/libc/dlopen/dlopen.c index 03032ac3d..3f56cff8c 100644 --- a/libc/dlopen/dlopen.c +++ b/libc/dlopen/dlopen.c @@ -631,11 +631,11 @@ static dontinline bool foreign_compile(char exe[hasatleast PATH_MAX]) { errno = err; return false; } - while (waitpid(pid, &ws, 0) == -1) { - if (errno != EINTR) { - unlink(tmp); - return false; - } + if (waitpid(pid, &ws, 0) == -1) { + // signals and cancelation are blocked + // therefore this must be a real error + unlink(tmp); + return false; } if (ws) { unlink(tmp); diff --git a/libc/intrin/getfileattributes.c b/libc/intrin/getfileattributes.c index 976d0a2e3..67cb6808e 100644 --- a/libc/intrin/getfileattributes.c +++ b/libc/intrin/getfileattributes.c @@ -19,6 +19,7 @@ #include "libc/intrin/describeflags.h" #include "libc/intrin/strace.h" #include "libc/nt/files.h" +#include "libc/nt/runtime.h" #include "libc/nt/thunk/msabi.h" __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; @@ -30,7 +31,7 @@ __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; textwindows uint32_t GetFileAttributes(const char16_t *lpPathName) { uint32_t flags; flags = __imp_GetFileAttributesW(lpPathName); - NTTRACE("GetFileAttributes(%#hs) → %s", lpPathName, - DescribeNtFileFlagAttr(flags)); + NTTRACE("GetFileAttributes(%#hs) → {%s, %d}", lpPathName, + DescribeNtFileFlagAttr(flags), GetLastError()); return flags; } diff --git a/third_party/musl/pwd.c b/third_party/musl/pwd.c index fc54b77cf..3fb4203e2 100644 --- a/third_party/musl/pwd.c +++ b/third_party/musl/pwd.c @@ -91,8 +91,9 @@ __fopen_passwd(void) { FILE *f; char *s; - // MacOS has a fake /etc/passwd file without any user details. - if (!IsXnu() && (f = fopen("/etc/passwd", "rbe"))) + // MacOS has a fake /etc/passwd file without any user details + // GetFileAttributes(u"\\etc\\passwd") takes 2 seconds sometimes + if (!IsXnu() && !IsWindows() && (f = fopen("/etc/passwd", "rbe"))) return f; if (!(s = __create_synthetic_passwd_file())) return 0;