Fix remove() directory on Windows

This commit is contained in:
Justine Tunney 2024-07-28 15:02:11 -07:00
parent e18fe1e112
commit 18964e5d76
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
3 changed files with 18 additions and 6 deletions

View file

@ -53,12 +53,13 @@ int unlinkat(int dirfd, const char *path, int flags) {
// POSIX.1 says unlink(directory) raises EPERM but on Linux // POSIX.1 says unlink(directory) raises EPERM but on Linux
// it always raises EISDIR, which is so much less ambiguous // it always raises EISDIR, which is so much less ambiguous
if (!IsLinux() && rc == -1 && !flags && errno == EPERM) { int e = errno;
if (!IsLinux() && rc == -1 && !flags && (e == EPERM || e == EACCES)) {
struct stat st; struct stat st;
if (!fstatat(dirfd, path, &st, 0) && S_ISDIR(st.st_mode)) { if (!fstatat(dirfd, path, &st, 0) && S_ISDIR(st.st_mode)) {
errno = EISDIR; errno = EISDIR;
} else { } else {
errno = EPERM; errno = e;
} }
} }

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/intrin/ubsan.h" #include "libc/intrin/ubsan.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/intrin/describebacktrace.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/intrin/pushpop.h" #include "libc/intrin/pushpop.h"
#include "libc/intrin/strace.h" #include "libc/intrin/strace.h"
@ -31,6 +32,7 @@
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/fileno.h"
@ -240,16 +242,20 @@ __wur static __ubsan_die_f *__ubsan_die(void) {
static void __ubsan_warning(const struct UbsanSourceLocation *loc, static void __ubsan_warning(const struct UbsanSourceLocation *loc,
const char *description) { const char *description) {
kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n", loc->file, kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n"
loc->line, SUBTLE, description, RESET); "cosmoaddr2line %s %s\n",
loc->file, loc->line, SUBTLE, description, RESET, __argv[0],
DescribeBacktrace(__builtin_frame_address(0)));
if (__ubsan_strict) if (__ubsan_strict)
__ubsan_die()(); __ubsan_die()();
} }
__wur __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc, __wur __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) { const char *description) {
kprintf("\n%s:%d: %subsan error%s: %s (tid %d)\n", loc->file, loc->line, RED2, kprintf("\n%s:%d: %subsan error%s: %s (tid %d)\n"
RESET, description, gettid()); "cosmoaddr2line %s %s\n",
loc->file, loc->line, RED2, RESET, description, gettid(), __argv[0],
DescribeBacktrace(__builtin_frame_address(0)));
return __ubsan_die(); return __ubsan_die();
} }

View file

@ -55,6 +55,11 @@ TEST(mkdir, testPathIsFile_EEXIST) {
EXPECT_SYS(EEXIST, -1, mkdir("yo/yo/yo", 0755)); EXPECT_SYS(EEXIST, -1, mkdir("yo/yo/yo", 0755));
} }
TEST(mkdir, remove) {
EXPECT_SYS(0, 0, mkdir("yo", 0777));
EXPECT_SYS(0, 0, remove("yo"));
}
TEST(mkdir, testPathIsDirectory_EEXIST) { TEST(mkdir, testPathIsDirectory_EEXIST) {
EXPECT_SYS(0, 0, mkdir("yo", 0755)); EXPECT_SYS(0, 0, mkdir("yo", 0755));
EXPECT_SYS(0, 0, mkdir("yo/yo", 0755)); EXPECT_SYS(0, 0, mkdir("yo/yo", 0755));