From deb5e07b5a74f43c6b3b9504215ab6acca28886d Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 10 Sep 2024 21:21:52 -0700 Subject: [PATCH] Remove exponential backoff from chdir() This issue probably only impacted the earliest releases of Windows 7 and we only support Windows 10+ these days, so it's not worth adding 2000 ms of startup latency to vim when ~/.vim doesn't exist. --- libc/calls/chdir-nt.c | 64 +++++++++++++--------------------------- libc/calls/unlinkat-nt.c | 5 ++-- 2 files changed, 23 insertions(+), 46 deletions(-) diff --git a/libc/calls/chdir-nt.c b/libc/calls/chdir-nt.c index 2c1b40eed..86e104bc8 100644 --- a/libc/calls/chdir-nt.c +++ b/libc/calls/chdir-nt.c @@ -16,70 +16,48 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/errno.h" -#include "libc/macros.h" -#include "libc/nt/errors.h" +#include "libc/limits.h" #include "libc/nt/files.h" #include "libc/nt/process.h" -#include "libc/nt/runtime.h" -#include "libc/nt/synchronization.h" #include "libc/sysv/errfuns.h" textwindows int sys_chdir_nt_impl(char16_t path[hasatleast PATH_MAX], uint32_t len) { uint32_t n; - int e, ms, err; char16_t var[4]; - if (len && path[len - 1] != u'\\') { if (len + 2 > PATH_MAX) return enametoolong(); path[len + 0] = u'\\'; path[len + 1] = u'\0'; } - - /* - * chdir() seems flaky on windows 7 - * in a similar way to rmdir() sigh - */ - for (err = errno, ms = 1;; ms *= 2) { - if (SetCurrentDirectory(path)) { - /* - * Now we need to set a magic environment variable. - */ - if ((n = GetCurrentDirectory(PATH_MAX, path))) { - if (n < PATH_MAX) { - if (!((path[0] == '/' && path[1] == '/') || - (path[0] == '\\' && path[1] == '\\'))) { - var[0] = '='; - var[1] = path[0]; - var[2] = ':'; - var[3] = 0; - if (!SetEnvironmentVariable(var, path)) { - return __winerr(); - } - } - return 0; - } else { - return enametoolong(); + if (SetCurrentDirectory(path)) { + /* + * Now we need to set a magic environment variable. + */ + if ((n = GetCurrentDirectory(PATH_MAX, path))) { + if (n < PATH_MAX) { + if (!((path[0] == '/' && path[1] == '/') || + (path[0] == '\\' && path[1] == '\\'))) { + var[0] = '='; + var[1] = path[0]; + var[2] = ':'; + var[3] = 0; + if (!SetEnvironmentVariable(var, path)) + return __winerr(); } + return 0; } else { - return __winerr(); + return enametoolong(); } } else { - e = GetLastError(); - if (ms <= 512 && - (e == kNtErrorFileNotFound || e == kNtErrorAccessDenied)) { - Sleep(ms); - errno = err; - continue; - } else { - break; - } + return __winerr(); } + } else { + return __fix_enotdir(__winerr(), path); } - return __fix_enotdir(-1, path); } textwindows int sys_chdir_nt(const char *path) { diff --git a/libc/calls/unlinkat-nt.c b/libc/calls/unlinkat-nt.c index 536694bd3..a0209ed1c 100644 --- a/libc/calls/unlinkat-nt.c +++ b/libc/calls/unlinkat-nt.c @@ -57,15 +57,14 @@ static textwindows bool IsDirectorySymlink(const char16_t *path) { static textwindows int sys_rmdir_nt(const char16_t *path) { int ms; for (ms = 1;; ms *= 2) { - if (RemoveDirectory(path)) { + if (RemoveDirectory(path)) return 0; - } // Files can linger, for absolutely no reason. // Possibly some Windows Defender bug on Win7. // Sleep for up to one second w/ expo backoff. // Alternative is use Microsoft internal APIs. // Never could have imagined it'd be this bad. - if (GetLastError() == kNtErrorDirNotEmpty && ms <= 2048) { + if (GetLastError() == kNtErrorDirNotEmpty && ms <= 1024) { Sleep(ms); continue; } else {