From 18964e5d76259cbd8f60dc1a0db401a154fc0da6 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 28 Jul 2024 15:02:11 -0700 Subject: [PATCH] Fix remove() directory on Windows --- libc/calls/unlinkat.c | 5 +++-- libc/intrin/ubsan.c | 14 ++++++++++---- test/libc/calls/mkdir_test.c | 5 +++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/libc/calls/unlinkat.c b/libc/calls/unlinkat.c index 33bd2f572..54a3a5be6 100644 --- a/libc/calls/unlinkat.c +++ b/libc/calls/unlinkat.c @@ -53,12 +53,13 @@ int unlinkat(int dirfd, const char *path, int flags) { // POSIX.1 says unlink(directory) raises EPERM but on Linux // 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; if (!fstatat(dirfd, path, &st, 0) && S_ISDIR(st.st_mode)) { errno = EISDIR; } else { - errno = EPERM; + errno = e; } } diff --git a/libc/intrin/ubsan.c b/libc/intrin/ubsan.c index e6107594a..bef84f828 100644 --- a/libc/intrin/ubsan.c +++ b/libc/intrin/ubsan.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/ubsan.h" #include "libc/calls/calls.h" +#include "libc/intrin/describebacktrace.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/pushpop.h" #include "libc/intrin/strace.h" @@ -31,6 +32,7 @@ #include "libc/nt/runtime.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/symbols.internal.h" #include "libc/stdio/stdio.h" #include "libc/str/str.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, const char *description) { - kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n", loc->file, - loc->line, SUBTLE, description, RESET); + kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n" + "cosmoaddr2line %s %s\n", + loc->file, loc->line, SUBTLE, description, RESET, __argv[0], + DescribeBacktrace(__builtin_frame_address(0))); if (__ubsan_strict) __ubsan_die()(); } __wur __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc, const char *description) { - kprintf("\n%s:%d: %subsan error%s: %s (tid %d)\n", loc->file, loc->line, RED2, - RESET, description, gettid()); + kprintf("\n%s:%d: %subsan error%s: %s (tid %d)\n" + "cosmoaddr2line %s %s\n", + loc->file, loc->line, RED2, RESET, description, gettid(), __argv[0], + DescribeBacktrace(__builtin_frame_address(0))); return __ubsan_die(); } diff --git a/test/libc/calls/mkdir_test.c b/test/libc/calls/mkdir_test.c index 3711b26fa..ff2e13aff 100644 --- a/test/libc/calls/mkdir_test.c +++ b/test/libc/calls/mkdir_test.c @@ -55,6 +55,11 @@ TEST(mkdir, testPathIsFile_EEXIST) { 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) { EXPECT_SYS(0, 0, mkdir("yo", 0755)); EXPECT_SYS(0, 0, mkdir("yo/yo", 0755));