mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +00:00
Fix msync() flags on FreeBSD
This commit is contained in:
parent
ebf784d4f5
commit
fffcd98b0e
7 changed files with 95 additions and 15 deletions
|
@ -25,6 +25,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Synchronize memory mapping changes to disk.
|
||||
|
@ -37,20 +38,61 @@
|
|||
* @return 0 on success or -1 w/ errno
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise EINTR if we needed to block and a signal was delivered instead
|
||||
* @raise EINVAL if `MS_SYNC` and `MS_ASYNC` were both specified
|
||||
* @raise EINVAL if unknown `flags` were passed
|
||||
* @cancellationpoint
|
||||
*/
|
||||
int msync(void *addr, size_t size, int flags) {
|
||||
int rc;
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
|
||||
unassert(((flags & MS_SYNC) ^ (flags & MS_ASYNC)) || !(MS_SYNC && MS_ASYNC));
|
||||
if (!IsWindows()) {
|
||||
rc = sys_msync(addr, size, flags);
|
||||
} else {
|
||||
rc = sys_msync_nt(addr, size, flags);
|
||||
if ((flags & ~(MS_SYNC | MS_ASYNC | MS_INVALIDATE)) ||
|
||||
(flags & (MS_SYNC | MS_ASYNC)) == (MS_SYNC | MS_ASYNC)) {
|
||||
rc = einval();
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
// According to POSIX, either MS_SYNC or MS_ASYNC must be specified
|
||||
// in flags, and indeed failure to include one of these flags will
|
||||
// cause msync() to fail on some systems. However, Linux permits a
|
||||
// call to msync() that specifies neither of these flags, with
|
||||
// semantics that are (currently) equivalent to specifying MS_ASYNC.
|
||||
// ──Quoth msync(2) of Linux Programmer's Manual
|
||||
int sysflags = flags;
|
||||
sysflags = flags;
|
||||
if (flags & MS_ASYNC) {
|
||||
sysflags = MS_ASYNC;
|
||||
} else if (flags & MS_SYNC) {
|
||||
sysflags = MS_SYNC;
|
||||
} else {
|
||||
sysflags = MS_ASYNC;
|
||||
}
|
||||
if (flags & MS_INVALIDATE) {
|
||||
sysflags |= MS_INVALIDATE;
|
||||
}
|
||||
|
||||
// FreeBSD's manual says "The flags argument was both MS_ASYNC and
|
||||
// MS_INVALIDATE. Only one of these flags is allowed." which makes
|
||||
// following the POSIX recommendation somewhat difficult.
|
||||
if (IsFreebsd()) {
|
||||
if (sysflags == (MS_ASYNC | MS_INVALIDATE)) {
|
||||
sysflags = MS_INVALIDATE;
|
||||
}
|
||||
}
|
||||
|
||||
// FreeBSD specifies MS_SYNC as 0 so we shift the Cosmo constants
|
||||
if (IsFreebsd()) {
|
||||
sysflags >>= 1;
|
||||
}
|
||||
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
if (!IsWindows()) {
|
||||
rc = sys_msync(addr, size, sysflags);
|
||||
} else {
|
||||
rc = sys_msync_nt(addr, size, sysflags);
|
||||
}
|
||||
END_CANCELLATION_POINT;
|
||||
|
||||
Finished:
|
||||
STRACE("msync(%p, %'zu, %#x) → %d% m", addr, size, flags, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -959,9 +959,9 @@ syscon pf PF_X25 9 9 0 0 0 0 0 0
|
|||
# msync() flags
|
||||
#
|
||||
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon ms MS_SYNC 4 4 16 16 0 2 4 4 # faked nt
|
||||
syscon ms MS_ASYNC 1 1 1 1 1 1 1 1 # consensus (faked nt)
|
||||
syscon ms MS_INVALIDATE 2 2 2 2 2 4 2 0
|
||||
syscon ms MS_SYNC 4 4 16 16 1 2 4 4 # faked nt; actually 0 on freebsd
|
||||
syscon ms MS_ASYNC 1 1 1 1 2 1 1 1 # faked nt; actually 1 on freebsd
|
||||
syscon ms MS_INVALIDATE 2 2 2 2 4 4 2 0 # actually 2 on freebsd
|
||||
|
||||
# statfs() flags
|
||||
#
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon ms,MS_ASYNC,1,1,1,1,1,1,1,1
|
||||
.syscon ms,MS_ASYNC,1,1,1,1,2,1,1,1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon ms,MS_INVALIDATE,2,2,2,2,2,4,2,0
|
||||
.syscon ms,MS_INVALIDATE,2,2,2,2,4,4,2,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon ms,MS_SYNC,4,4,16,16,0,2,4,4
|
||||
.syscon ms,MS_SYNC,4,4,16,16,1,2,4,4
|
||||
|
|
|
@ -7,11 +7,10 @@ extern const int MS_SYNC;
|
|||
extern const int MS_ASYNC;
|
||||
extern const int MS_INVALIDATE;
|
||||
|
||||
#define MS_ASYNC 1
|
||||
#define MS_SYNC MS_SYNC
|
||||
#define MS_ASYNC MS_ASYNC
|
||||
#define MS_INVALIDATE MS_INVALIDATE
|
||||
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MSYNC_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue