mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
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.
This commit is contained in:
parent
4d05060aac
commit
deb5e07b5a
2 changed files with 23 additions and 46 deletions
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue