mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-04 02:08:30 +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;
|
int len;
|
||||||
char16_t path16[PATH_MAX];
|
char16_t path16[PATH_MAX];
|
||||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||||
if (path16[len - 1] != u'/' && path16[len - 1] != u'\\') {
|
if (path16[len - 1] != u'\\') {
|
||||||
path16[len + 0] = u'/';
|
if (len + 1 + 1 > PATH_MAX) return enametoolong();
|
||||||
|
path16[len + 0] = u'\\';
|
||||||
path16[len + 1] = u'\0';
|
path16[len + 1] = u'\0';
|
||||||
}
|
}
|
||||||
if (SetCurrentDirectory(path16)) {
|
if (SetCurrentDirectory(path16)) {
|
||||||
|
|
|
@ -92,10 +92,8 @@ static textwindows noinline DIR *opendir$nt(const char *name) {
|
||||||
char16_t name16[PATH_MAX];
|
char16_t name16[PATH_MAX];
|
||||||
if ((len = __mkntpath(name, name16)) == -1) return NULL;
|
if ((len = __mkntpath(name, name16)) == -1) return NULL;
|
||||||
if (len + 2 + 1 > PATH_MAX) return PROGN(enametoolong(), NULL);
|
if (len + 2 + 1 > PATH_MAX) return PROGN(enametoolong(), NULL);
|
||||||
if (name16[len - 1] == u'/' || name16[len - 1] == u'\\') {
|
while (name16[len - 1] == u'\\') name16[--len] = u'\0';
|
||||||
name16[--len] = u'\0';
|
name16[len++] = u'\\';
|
||||||
}
|
|
||||||
name16[len++] = u'/';
|
|
||||||
name16[len++] = u'*';
|
name16[len++] = u'*';
|
||||||
name16[len] = u'\0';
|
name16[len] = u'\0';
|
||||||
if (!(res = calloc(1, sizeof(DIR)))) return NULL;
|
if (!(res = calloc(1, sizeof(DIR)))) return NULL;
|
||||||
|
|
|
@ -17,15 +17,34 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/nt/errors.h"
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
|
#include "libc/nt/synchronization.h"
|
||||||
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
textwindows int rmdir$nt(const char *path) {
|
textwindows int rmdir$nt(const char *path) {
|
||||||
uint16_t path16[PATH_MAX];
|
int e, ms, len;
|
||||||
if (__mkntpath(path, path16) == -1) return -1;
|
char16_t path16[PATH_MAX];
|
||||||
if (RemoveDirectory(path16)) {
|
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||||
return 0;
|
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 {
|
} else {
|
||||||
return __winerr();
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errno = e;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,5 @@
|
||||||
int touch(const char *file, uint32_t mode) {
|
int touch(const char *file, uint32_t mode) {
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1;
|
if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1;
|
||||||
fsync(fd); /* TODO(jart): do we need it? */
|
|
||||||
return close(fd);
|
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 EDEADLK 35 11 11 11 1131 # bsd consensus & kNtErrorPossibleDeadlock
|
||||||
syscon errno ENAMETOOLONG 36 63 63 63 0x274f # bsd consensus & WSAENAMETOOLONG
|
syscon errno ENAMETOOLONG 36 63 63 63 0x274f # bsd consensus & WSAENAMETOOLONG
|
||||||
syscon errno ENOLCK 37 77 77 77 -1 # bsd consensus
|
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 ELOOP 40 62 62 62 0x274e # bsd consensus & WSAELOOP
|
||||||
syscon errno ENOMSG 42 91 83 90 -1
|
syscon errno ENOMSG 42 91 83 90 -1
|
||||||
syscon errno EIDRM 43 90 82 89 -1
|
syscon errno EIDRM 43 90 82 89 -1
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
.include "libc/sysv/consts/syscon.inc"
|
.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 (!strcmp(e->d_name, "..")) continue;
|
||||||
if (strchr(e->d_name, '/')) abort();
|
if (strchr(e->d_name, '/')) abort();
|
||||||
path = xjoinpaths(dirpath, e->d_name);
|
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);
|
free(path);
|
||||||
closedir(d);
|
closedir(d);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue