From e1a40783da8668a8bbb1a6840eefa15e15da7b83 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Wed, 8 Jun 2022 20:21:05 -0700 Subject: [PATCH] Fix fadvise() on Windows --- libc/calls/fadvise-nt.c | 15 ++++++++++++++- libc/calls/state.internal.h | 3 ++- libc/intrin/g_fds.c | 4 ---- libc/log/backtrace2.c | 4 ++-- libc/runtime/memtrack.greg.c | 6 ++++++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/libc/calls/fadvise-nt.c b/libc/calls/fadvise-nt.c index 2c0ec8c28..6646c7a18 100644 --- a/libc/calls/fadvise-nt.c +++ b/libc/calls/fadvise-nt.c @@ -21,6 +21,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/intrin/spinlock.h" #include "libc/nt/createfile.h" +#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" #include "libc/sysv/consts/madv.h" @@ -32,11 +33,13 @@ textwindows int sys_fadvise_nt(int fd, uint64_t offset, uint64_t len, int64_t h1, h2; int rc, flags, mode; uint32_t perm, share, attr; + if (!__isfdkind(fd, kFdFile)) return ebadf(); h1 = g_fds.p[fd].handle; mode = g_fds.p[fd].mode; flags = g_fds.p[fd].flags; flags &= ~(O_SEQUENTIAL | O_RANDOM); + switch (advice) { case MADV_NORMAL: break; @@ -50,7 +53,17 @@ textwindows int sys_fadvise_nt(int fd, uint64_t offset, uint64_t len, default: return einval(); } - if (GetNtOpenFlags(flags, mode, &perm, &share, 0, &attr) == -1) return -1; + + if (GetNtOpenFlags(flags, mode, &perm, &share, 0, &attr) == -1) { + return -1; + } + + // MSDN says only these are allowed, otherwise it returns EINVAL. + attr &= kNtFileFlagBackupSemantics | kNtFileFlagDeleteOnClose | + kNtFileFlagNoBuffering | kNtFileFlagOpenNoRecall | + kNtFileFlagOpenReparsePoint | kNtFileFlagOverlapped | + kNtFileFlagPosixSemantics | kNtFileFlagRandomAccess | + kNtFileFlagSequentialScan | kNtFileFlagWriteThrough; __fds_lock(); if ((h2 = ReOpenFile(h1, perm, share, attr)) != -1) { diff --git a/libc/calls/state.internal.h b/libc/calls/state.internal.h index ed8ef1437..6996ebbd2 100644 --- a/libc/calls/state.internal.h +++ b/libc/calls/state.internal.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_ +#include "libc/intrin/spinlock.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -12,7 +13,7 @@ hidden extern unsigned __sighandflags[NSIG]; hidden extern const struct NtSecurityAttributes kNtIsInheritable; void __fds_lock(void); -void __fds_unlock(void); +#define __fds_unlock() _spunlock(&__fds_lock_obj) COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/intrin/g_fds.c b/libc/intrin/g_fds.c index c0bb4e73f..e0ccecab2 100644 --- a/libc/intrin/g_fds.c +++ b/libc/intrin/g_fds.c @@ -32,10 +32,6 @@ void __fds_lock(void) { _spinlock(&__fds_lock_obj); } -void __fds_unlock(void) { - _spunlock(&__fds_lock_obj); -} - textstartup void InitializeFileDescriptors(void) { struct Fds *fds; fds = VEIL("r", &g_fds); diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c index 42606fc8b..618a8f569 100644 --- a/libc/log/backtrace2.c +++ b/libc/log/backtrace2.c @@ -80,13 +80,13 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { return -1; } + // backtrace_test.com failing on windows for some reason via runitd if (IsWindows()) { - // TODO: We need a way to *not* pass //?/C:/... paths to mingw return -1; } + // doesn't work on rhel5 if (IsLinux() && !__is_linux_2_6_23()) { - // we need the `addr2line -a` option return -1; } diff --git a/libc/runtime/memtrack.greg.c b/libc/runtime/memtrack.greg.c index 9ea60d1e1..b2ca98cce 100644 --- a/libc/runtime/memtrack.greg.c +++ b/libc/runtime/memtrack.greg.c @@ -95,7 +95,9 @@ static bool ExtendMemoryIntervals(struct MemoryIntervals *mm) { if (!dm.addr) return false; mm->n = (size + gran) / sizeof(*mm->p); } +#if IsModeDbg() assert(AreMemoryIntervalsOk(mm)); +#endif return true; } @@ -123,8 +125,10 @@ static int PunchHole(struct MemoryIntervals *mm, int x, int y, int i) { int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, void wf(struct MemoryIntervals *, int, int)) { unsigned l, r; +#if IsModeDbg() assert(y >= x); assert(AreMemoryIntervalsOk(mm)); +#endif if (!mm->i) return 0; // binary search for the lefthand side @@ -194,8 +198,10 @@ int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h, long offset, long size) { // asan runtime depends on this function unsigned i; +#if IsModeDbg() assert(y >= x); assert(AreMemoryIntervalsOk(mm)); +#endif i = FindMemoryInterval(mm, x);