mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-02 23:18:44 +00:00
Add exponential backoff to rmdir() on Windows
This commit is contained in:
parent
bf8b1623c8
commit
eaca5b3e81
7 changed files with 38 additions and 16 deletions
|
@ -25,8 +25,9 @@ textwindows int chdir$nt(const char *path) {
|
|||
int len;
|
||||
char16_t path16[PATH_MAX];
|
||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||
if (path16[len - 1] != u'/' && path16[len - 1] != u'\\') {
|
||||
path16[len + 0] = u'/';
|
||||
if (path16[len - 1] != u'\\') {
|
||||
if (len + 1 + 1 > PATH_MAX) return enametoolong();
|
||||
path16[len + 0] = u'\\';
|
||||
path16[len + 1] = u'\0';
|
||||
}
|
||||
if (SetCurrentDirectory(path16)) {
|
||||
|
|
|
@ -92,10 +92,8 @@ static textwindows noinline DIR *opendir$nt(const char *name) {
|
|||
char16_t name16[PATH_MAX];
|
||||
if ((len = __mkntpath(name, name16)) == -1) return NULL;
|
||||
if (len + 2 + 1 > PATH_MAX) return PROGN(enametoolong(), NULL);
|
||||
if (name16[len - 1] == u'/' || name16[len - 1] == u'\\') {
|
||||
name16[--len] = u'\0';
|
||||
}
|
||||
name16[len++] = u'/';
|
||||
while (name16[len - 1] == u'\\') name16[--len] = u'\0';
|
||||
name16[len++] = u'\\';
|
||||
name16[len++] = u'*';
|
||||
name16[len] = u'\0';
|
||||
if (!(res = calloc(1, sizeof(DIR)))) return NULL;
|
||||
|
|
|
@ -17,15 +17,34 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int rmdir$nt(const char *path) {
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if (RemoveDirectory(path16)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
int e, ms, len;
|
||||
char16_t path16[PATH_MAX];
|
||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||
while (path16[len - 1] == u'\\') path16[--len] = u'\0';
|
||||
if (len + 2 + 1 > PATH_MAX) return enametoolong();
|
||||
for (ms = 1;; ms *= 2) {
|
||||
if (RemoveDirectory(path16)) 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 ((e = GetLastError()) == kNtErrorDirNotEmpty && ms <= 512) {
|
||||
Sleep(ms);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,5 @@
|
|||
int touch(const char *file, uint32_t mode) {
|
||||
int fd;
|
||||
if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1;
|
||||
fsync(fd); /* TODO(jart): do we need it? */
|
||||
return close(fd);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ syscon errno ERANGE 34 34 34 34 -1 # bsd consensus
|
|||
syscon errno EDEADLK 35 11 11 11 1131 # bsd consensus & kNtErrorPossibleDeadlock
|
||||
syscon errno ENAMETOOLONG 36 63 63 63 0x274f # bsd consensus & WSAENAMETOOLONG
|
||||
syscon errno ENOLCK 37 77 77 77 -1 # bsd consensus
|
||||
syscon errno ENOTEMPTY 39 66 66 66 0x2752 # bsd consensus & WSAENOTEMPTY
|
||||
syscon errno ENOTEMPTY 39 66 66 66 145 # bsd consensus & kNtErrorDirNotEmpty (TODO: What is WSAENOTEMPTY? 0x2752)
|
||||
syscon errno ELOOP 40 62 62 62 0x274e # bsd consensus & WSAELOOP
|
||||
syscon errno ENOMSG 42 91 83 90 -1
|
||||
syscon errno EIDRM 43 90 82 89 -1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "libc/sysv/consts/syscon.inc"
|
||||
.syscon errno ENOTEMPTY 39 66 66 66 0x2752
|
||||
.syscon errno ENOTEMPTY 39 66 66 66 145
|
||||
|
|
|
@ -37,7 +37,12 @@ static int rmrfdir(const char *dirpath) {
|
|||
if (!strcmp(e->d_name, "..")) continue;
|
||||
if (strchr(e->d_name, '/')) abort();
|
||||
path = xjoinpaths(dirpath, e->d_name);
|
||||
if ((e->d_type == DT_DIR ? rmrfdir(path) : unlink(path)) == -1) {
|
||||
if (e->d_type == DT_DIR) {
|
||||
rc = rmrfdir(path);
|
||||
} else {
|
||||
rc = unlink(path);
|
||||
}
|
||||
if (rc == -1) {
|
||||
free(path);
|
||||
closedir(d);
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Reference in a new issue