Fix fadvise() on Windows

This commit is contained in:
Justine Tunney 2022-06-08 20:21:05 -07:00
parent adac64a52b
commit e1a40783da
5 changed files with 24 additions and 8 deletions

View file

@ -21,6 +21,7 @@
#include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/spinlock.h" #include "libc/intrin/spinlock.h"
#include "libc/nt/createfile.h" #include "libc/nt/createfile.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/files.h" #include "libc/nt/files.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/sysv/consts/madv.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; int64_t h1, h2;
int rc, flags, mode; int rc, flags, mode;
uint32_t perm, share, attr; uint32_t perm, share, attr;
if (!__isfdkind(fd, kFdFile)) return ebadf(); if (!__isfdkind(fd, kFdFile)) return ebadf();
h1 = g_fds.p[fd].handle; h1 = g_fds.p[fd].handle;
mode = g_fds.p[fd].mode; mode = g_fds.p[fd].mode;
flags = g_fds.p[fd].flags; flags = g_fds.p[fd].flags;
flags &= ~(O_SEQUENTIAL | O_RANDOM); flags &= ~(O_SEQUENTIAL | O_RANDOM);
switch (advice) { switch (advice) {
case MADV_NORMAL: case MADV_NORMAL:
break; break;
@ -50,7 +53,17 @@ textwindows int sys_fadvise_nt(int fd, uint64_t offset, uint64_t len,
default: default:
return einval(); 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(); __fds_lock();
if ((h2 = ReOpenFile(h1, perm, share, attr)) != -1) { if ((h2 = ReOpenFile(h1, perm, share, attr)) != -1) {

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_ #ifndef COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_
#include "libc/intrin/spinlock.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
@ -12,7 +13,7 @@ hidden extern unsigned __sighandflags[NSIG];
hidden extern const struct NtSecurityAttributes kNtIsInheritable; hidden extern const struct NtSecurityAttributes kNtIsInheritable;
void __fds_lock(void); void __fds_lock(void);
void __fds_unlock(void); #define __fds_unlock() _spunlock(&__fds_lock_obj)
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -32,10 +32,6 @@ void __fds_lock(void) {
_spinlock(&__fds_lock_obj); _spinlock(&__fds_lock_obj);
} }
void __fds_unlock(void) {
_spunlock(&__fds_lock_obj);
}
textstartup void InitializeFileDescriptors(void) { textstartup void InitializeFileDescriptors(void) {
struct Fds *fds; struct Fds *fds;
fds = VEIL("r", &g_fds); fds = VEIL("r", &g_fds);

View file

@ -80,13 +80,13 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
return -1; return -1;
} }
// backtrace_test.com failing on windows for some reason via runitd
if (IsWindows()) { if (IsWindows()) {
// TODO: We need a way to *not* pass //?/C:/... paths to mingw
return -1; return -1;
} }
// doesn't work on rhel5
if (IsLinux() && !__is_linux_2_6_23()) { if (IsLinux() && !__is_linux_2_6_23()) {
// we need the `addr2line -a` option
return -1; return -1;
} }

View file

@ -95,7 +95,9 @@ static bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
if (!dm.addr) return false; if (!dm.addr) return false;
mm->n = (size + gran) / sizeof(*mm->p); mm->n = (size + gran) / sizeof(*mm->p);
} }
#if IsModeDbg()
assert(AreMemoryIntervalsOk(mm)); assert(AreMemoryIntervalsOk(mm));
#endif
return true; 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, int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
void wf(struct MemoryIntervals *, int, int)) { void wf(struct MemoryIntervals *, int, int)) {
unsigned l, r; unsigned l, r;
#if IsModeDbg()
assert(y >= x); assert(y >= x);
assert(AreMemoryIntervalsOk(mm)); assert(AreMemoryIntervalsOk(mm));
#endif
if (!mm->i) return 0; if (!mm->i) return 0;
// binary search for the lefthand side // 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) { long offset, long size) {
// asan runtime depends on this function // asan runtime depends on this function
unsigned i; unsigned i;
#if IsModeDbg()
assert(y >= x); assert(y >= x);
assert(AreMemoryIntervalsOk(mm)); assert(AreMemoryIntervalsOk(mm));
#endif
i = FindMemoryInterval(mm, x); i = FindMemoryInterval(mm, x);