mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-26 12:30:30 +00:00
Make redbean StoreAsset() work better
- Better UBSAN error messages - POSIX Advisory Locks polyfills - Move redbean manual to /.help.txt - System call memory safety in ASAN mode - Character classification now does UNICODE
This commit is contained in:
parent
919b6fec10
commit
690be544da
228 changed files with 3653 additions and 3015 deletions
|
@ -137,8 +137,8 @@ int mlockall(int);
|
|||
int munlock(const void *, size_t);
|
||||
int munlockall(void);
|
||||
int nice(int);
|
||||
int open(const char *, int, ...) nodiscard;
|
||||
int openanon(char *, unsigned) nodiscard;
|
||||
int open(const char *, int, ...);
|
||||
int openanon(char *, unsigned);
|
||||
int openat(int, const char *, int, ...);
|
||||
int pause(void);
|
||||
int personality(uint64_t);
|
||||
|
@ -176,7 +176,7 @@ int stat(const char *, struct stat *);
|
|||
int symlink(const char *, const char *);
|
||||
int symlinkat(const char *, int, const char *);
|
||||
int sync_file_range(int, int64_t, int64_t, unsigned);
|
||||
int sysinfo(struct sysinfo *) paramsnonnull();
|
||||
int sysinfo(struct sysinfo *);
|
||||
int touch(const char *, uint32_t);
|
||||
int truncate(const char *, uint64_t);
|
||||
int ttyname_r(int, char *, size_t);
|
||||
|
|
|
@ -18,45 +18,98 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/flock.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/filelockflags.h"
|
||||
#include "libc/nt/enum/filesharemode.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/struct/byhandlefileinformation.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_fcntl_nt(int fd, int cmd, unsigned arg) {
|
||||
static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) {
|
||||
uint32_t flags;
|
||||
struct flock *l;
|
||||
struct NtOverlapped ov;
|
||||
int64_t pos, off, len, size;
|
||||
struct NtByHandleFileInformation info;
|
||||
l = (struct flock *)arg;
|
||||
len = l->l_len;
|
||||
off = l->l_start;
|
||||
if (!len || l->l_whence == SEEK_END) {
|
||||
if (!GetFileInformationByHandle(f->handle, &info)) return __winerr();
|
||||
size = (uint64_t)info.nFileSizeHigh << 32 | info.nFileSizeLow;
|
||||
} else {
|
||||
size = 0;
|
||||
}
|
||||
if (l->l_whence != SEEK_SET) {
|
||||
if (l->l_whence == SEEK_CUR) {
|
||||
if (!SetFilePointerEx(f->handle, 0, &pos, SEEK_CUR)) return __winerr();
|
||||
off = pos + off;
|
||||
} else if (l->l_whence == SEEK_END) {
|
||||
off = size - off;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
if (!len) len = size - off;
|
||||
if (off < 0 || len < 0) return einval();
|
||||
offset2overlap(off, &ov);
|
||||
if (l->l_type == F_RDLCK || l->l_type == F_WRLCK) {
|
||||
flags = 0;
|
||||
if (cmd == F_SETLK) flags |= kNtLockfileFailImmediately;
|
||||
if (l->l_type == F_WRLCK) flags |= kNtLockfileExclusiveLock;
|
||||
if (LockFileEx(f->handle, flags, 0, len, len >> 32, &ov)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
} else if (l->l_type == F_UNLCK) {
|
||||
if (UnlockFileEx(f->handle, 0, len, len >> 32, &ov)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
||||
textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
|
||||
uint32_t flags;
|
||||
if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdSocket)) {
|
||||
switch (cmd) {
|
||||
case F_GETFL:
|
||||
return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT |
|
||||
O_NOATIME | O_NONBLOCK);
|
||||
case F_SETFL:
|
||||
/*
|
||||
* - O_APPEND doesn't appear to be tunable at cursory glance
|
||||
* - O_NONBLOCK might require we start doing all i/o in threads
|
||||
* - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything
|
||||
*/
|
||||
return einval();
|
||||
case F_GETFD:
|
||||
if (g_fds.p[fd].flags & O_CLOEXEC) {
|
||||
return FD_CLOEXEC;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case F_SETFD:
|
||||
if (arg & FD_CLOEXEC) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
return FD_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return einval();
|
||||
if (cmd == F_GETFL) {
|
||||
return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT |
|
||||
O_NOATIME | O_NONBLOCK);
|
||||
} else if (cmd == F_SETFL) {
|
||||
/*
|
||||
* - O_APPEND doesn't appear to be tunable at cursory glance
|
||||
* - O_NONBLOCK might require we start doing all i/o in threads
|
||||
* - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything
|
||||
*/
|
||||
return einval();
|
||||
} else if (cmd == F_GETFD) {
|
||||
if (g_fds.p[fd].flags & O_CLOEXEC) {
|
||||
return FD_CLOEXEC;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (cmd == F_SETFD) {
|
||||
if (arg & FD_CLOEXEC) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
return FD_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
return 0;
|
||||
}
|
||||
} else if (cmd == F_SETLK || cmd == F_SETLKW) {
|
||||
return sys_fcntl_nt_lock(g_fds.p + fd, cmd, arg);
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else {
|
||||
return ebadf();
|
||||
|
|
31
libc/calls/fcntl-sysv.c
Normal file
31
libc/calls/fcntl-sysv.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/flock.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
|
||||
int sys_fcntl(int fd, int cmd, uintptr_t arg) {
|
||||
int rc;
|
||||
bool islock;
|
||||
islock = cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK;
|
||||
if (islock) cosmo2flock(arg);
|
||||
rc = __sys_fcntl(fd, cmd, arg);
|
||||
if (islock) flock2cosmo(arg);
|
||||
return rc;
|
||||
}
|
|
@ -25,6 +25,12 @@
|
|||
*
|
||||
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
|
||||
*
|
||||
* This function implements POSIX Advisory Locks, e.g.
|
||||
*
|
||||
* CHECK_NE(-1, fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK}));
|
||||
* // ...
|
||||
* CHECK_NE(-1, fcntl(zfd, F_SETLK, &(struct flock){F_UNLCK}));
|
||||
*
|
||||
* @param cmd can be F_{GET,SET}{FD,FL}, etc.
|
||||
* @param arg can be FD_CLOEXEC, etc. depending
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
|
@ -32,9 +38,9 @@
|
|||
*/
|
||||
int fcntl(int fd, int cmd, ...) {
|
||||
va_list va;
|
||||
unsigned arg;
|
||||
uintptr_t arg;
|
||||
va_start(va, cmd);
|
||||
arg = va_arg(va, unsigned);
|
||||
arg = va_arg(va, uintptr_t);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return sys_fcntl(fd, cmd, arg);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
int __fixupnewfd(int fd, int flags) {
|
||||
if (fd != -1) {
|
||||
if (flags & O_CLOEXEC) {
|
||||
sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
__sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
/**
|
||||
* Acquires lock on file.
|
||||
*
|
||||
* Please note multiple file descriptors means multiple locks.
|
||||
*
|
||||
* @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive,
|
||||
* non-blocking, and unlocking
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
|
@ -28,6 +29,7 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstat(int fd, struct stat *st) {
|
||||
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
return weaken(__zipos_fstat)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
|
@ -36,6 +38,7 @@
|
|||
*/
|
||||
int fstatat(int dirfd, const char *path, struct stat *st, uint32_t flags) {
|
||||
struct ZiposUri zipname;
|
||||
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
|
||||
if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||
return weaken(__zipos_stat)(&zipname, st);
|
||||
} else if (!IsWindows()) {
|
||||
|
|
|
@ -34,7 +34,7 @@ char *sys_getcwd_xnu(char *res, size_t size) {
|
|||
if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) {
|
||||
if (sys_fstat(fd, &st[0]) != -1) {
|
||||
if (st[0].st_dev && st[0].st_ino) {
|
||||
if (sys_fcntl(fd, XNU_F_GETPATH, buf) != -1) {
|
||||
if (__sys_fcntl(fd, XNU_F_GETPATH, (uintptr_t)buf) != -1) {
|
||||
if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
|
||||
if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) {
|
||||
if (memccpy(res, buf, '\0', size)) {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Returns parent process id.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int32_t getppid(void) {
|
||||
int getppid(void) {
|
||||
if (!IsWindows()) {
|
||||
if (!IsNetbsd()) {
|
||||
return sys_getppid();
|
||||
|
|
|
@ -109,6 +109,7 @@ char *sys_getcwd(char *, u64) hidden;
|
|||
char *sys_getcwd_xnu(char *, u64) hidden;
|
||||
i32 __sys_dup3(i32, i32, i32) hidden;
|
||||
i32 __sys_execve(const char *, char *const[], char *const[]) hidden;
|
||||
i32 __sys_fcntl(i32, i32, u64) hidden;
|
||||
i32 __sys_fstat(i32, struct stat *) hidden;
|
||||
i32 __sys_fstatat(i32, const char *, struct stat *, i32) hidden;
|
||||
i32 __sys_getrusage(i32, struct rusage *) hidden;
|
||||
|
@ -131,7 +132,7 @@ i32 sys_fchmod(i32, u32) hidden;
|
|||
i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
|
||||
i32 sys_fchown(i64, u32, u32) hidden;
|
||||
i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
|
||||
i32 sys_fcntl(i32, i32, ...) hidden;
|
||||
i32 sys_fcntl(i32, i32, u64) hidden;
|
||||
i32 sys_fdatasync(i32) hidden;
|
||||
i32 sys_flock(i32, i32) hidden;
|
||||
i32 sys_fstat(i32, struct stat *) hidden;
|
||||
|
@ -229,6 +230,8 @@ int gethostname_nt(char *, size_t) hidden;
|
|||
size_t __iovec_size(const struct iovec *, size_t) hidden;
|
||||
void __rusage2linux(struct rusage *) hidden;
|
||||
ssize_t WritevUninterruptible(int, struct iovec *, int);
|
||||
void flock2cosmo(uintptr_t);
|
||||
void cosmo2flock(uintptr_t);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » windows nt » veneers ─╬─│┼
|
||||
|
@ -245,7 +248,7 @@ int sys_execve_nt(const char *, char *const[], char *const[]) hidden;
|
|||
int sys_faccessat_nt(int, const char *, int, uint32_t) hidden;
|
||||
int sys_fadvise_nt(int, u64, u64, int) hidden;
|
||||
int sys_fchdir_nt(int) hidden;
|
||||
int sys_fcntl_nt(int, int, unsigned) hidden;
|
||||
int sys_fcntl_nt(int, int, uintptr_t) hidden;
|
||||
int sys_fdatasync_nt(int) hidden;
|
||||
int sys_flock_nt(int, int) hidden;
|
||||
int sys_fork_nt(void) hidden;
|
||||
|
|
164
libc/calls/metaflock.c
Normal file
164
libc/calls/metaflock.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/flock.h"
|
||||
|
||||
union metaflock {
|
||||
struct flock cosmo;
|
||||
struct flock_linux {
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
} linux;
|
||||
struct flock_xnu {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
} xnu;
|
||||
struct flock_freebsd {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
int32_t l_sysid;
|
||||
} freebsd;
|
||||
struct flock_openbsd {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
} openbsd;
|
||||
struct flock_netbsd {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
} netbsd;
|
||||
};
|
||||
|
||||
void flock2cosmo(uintptr_t memory) {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
int32_t l_sysid;
|
||||
union metaflock *u;
|
||||
u = (union metaflock *)memory;
|
||||
if (IsLinux()) {
|
||||
l_start = u->linux.l_start;
|
||||
l_len = u->linux.l_len;
|
||||
l_pid = u->linux.l_pid;
|
||||
l_type = u->linux.l_type;
|
||||
l_whence = u->linux.l_whence;
|
||||
l_sysid = 0;
|
||||
} else if (IsXnu()) {
|
||||
l_start = u->xnu.l_start;
|
||||
l_len = u->xnu.l_len;
|
||||
l_pid = u->xnu.l_pid;
|
||||
l_type = u->xnu.l_type;
|
||||
l_whence = u->xnu.l_whence;
|
||||
l_sysid = 0;
|
||||
} else if (IsFreebsd()) {
|
||||
l_start = u->freebsd.l_start;
|
||||
l_len = u->freebsd.l_len;
|
||||
l_pid = u->freebsd.l_pid;
|
||||
l_type = u->freebsd.l_type;
|
||||
l_whence = u->freebsd.l_whence;
|
||||
l_sysid = u->freebsd.l_sysid;
|
||||
} else if (IsOpenbsd()) {
|
||||
l_start = u->openbsd.l_start;
|
||||
l_len = u->openbsd.l_len;
|
||||
l_pid = u->openbsd.l_pid;
|
||||
l_type = u->openbsd.l_type;
|
||||
l_whence = u->openbsd.l_whence;
|
||||
l_sysid = 0;
|
||||
} else if (IsNetbsd()) {
|
||||
l_start = u->netbsd.l_start;
|
||||
l_len = u->netbsd.l_len;
|
||||
l_pid = u->netbsd.l_pid;
|
||||
l_type = u->netbsd.l_type;
|
||||
l_whence = u->netbsd.l_whence;
|
||||
l_sysid = 0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
u->cosmo.l_start = l_start;
|
||||
u->cosmo.l_len = l_len;
|
||||
u->cosmo.l_pid = l_pid;
|
||||
u->cosmo.l_type = l_type;
|
||||
u->cosmo.l_whence = l_whence;
|
||||
u->cosmo.l_sysid = l_sysid;
|
||||
}
|
||||
|
||||
void cosmo2flock(uintptr_t memory) {
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int32_t l_pid;
|
||||
int16_t l_type;
|
||||
int16_t l_whence;
|
||||
int32_t l_sysid;
|
||||
union metaflock *u;
|
||||
u = (union metaflock *)memory;
|
||||
l_start = u->cosmo.l_start;
|
||||
l_len = u->cosmo.l_len;
|
||||
l_pid = u->cosmo.l_pid;
|
||||
l_type = u->cosmo.l_type;
|
||||
l_whence = u->cosmo.l_whence;
|
||||
l_sysid = u->cosmo.l_sysid;
|
||||
if (IsLinux()) {
|
||||
u->linux.l_start = l_start;
|
||||
u->linux.l_len = l_len;
|
||||
u->linux.l_pid = l_pid;
|
||||
u->linux.l_type = l_type;
|
||||
u->linux.l_whence = l_whence;
|
||||
} else if (IsXnu()) {
|
||||
u->xnu.l_start = l_start;
|
||||
u->xnu.l_len = l_len;
|
||||
u->xnu.l_pid = l_pid;
|
||||
u->xnu.l_type = l_type;
|
||||
u->xnu.l_whence = l_whence;
|
||||
} else if (IsFreebsd()) {
|
||||
u->freebsd.l_start = l_start;
|
||||
u->freebsd.l_len = l_len;
|
||||
u->freebsd.l_pid = l_pid;
|
||||
u->freebsd.l_type = l_type;
|
||||
u->freebsd.l_whence = l_whence;
|
||||
u->freebsd.l_sysid = l_sysid;
|
||||
} else if (IsOpenbsd()) {
|
||||
u->openbsd.l_start = l_start;
|
||||
u->openbsd.l_len = l_len;
|
||||
u->openbsd.l_pid = l_pid;
|
||||
u->openbsd.l_type = l_type;
|
||||
u->openbsd.l_whence = l_whence;
|
||||
} else if (IsNetbsd()) {
|
||||
u->netbsd.l_start = l_start;
|
||||
u->netbsd.l_len = l_len;
|
||||
u->netbsd.l_pid = l_pid;
|
||||
u->netbsd.l_type = l_type;
|
||||
u->netbsd.l_whence = l_whence;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ int sys_openat(int dirfd, const char *file, int flags, unsigned mode) {
|
|||
errno = err;
|
||||
fd = __sys_openat(dirfd, file, flags & ~O_CLOEXEC, mode);
|
||||
if (fd != -1 && (flags & O_CLOEXEC)) {
|
||||
sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
__sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/iov.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -45,6 +46,7 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
|
|||
|
||||
if (fd < 0) return einval();
|
||||
if (iovlen < 0) return einval();
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_read)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/iov.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -49,6 +50,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
|
|||
|
||||
if (fd < 0) return einval();
|
||||
if (iovlen < 0) return einval();
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_write)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
@ -31,18 +32,21 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
||||
if (fd < 0) return einval();
|
||||
if (iovlen < 0) return einval();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_read)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_readv(fd, iov, iovlen);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_readv_metal(g_fds.p + fd, iov, iovlen);
|
||||
if (fd >= 0 && iovlen >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_read)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_readv(fd, iov, iovlen);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_readv_metal(g_fds.p + fd, iov, iovlen);
|
||||
} else {
|
||||
return sys_readv_nt(g_fds.p + fd, iov, iovlen);
|
||||
}
|
||||
} else {
|
||||
return sys_readv_nt(g_fds.p + fd, iov, iovlen);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
int64_t l_start;
|
||||
int64_t l_len;
|
||||
int l_pid;
|
||||
struct flock { /* cosmopolitan abi */
|
||||
int16_t l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */
|
||||
int16_t l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
|
||||
int64_t l_start; /* starting offset */
|
||||
int64_t l_len; /* 0 means until end of file */
|
||||
int32_t l_pid; /* lock owner */
|
||||
int32_t l_sysid; /* remote system id or zero for local */
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sysinfo.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/memorystatusex.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns amount of system ram, cores, etc.
|
||||
|
@ -34,6 +36,11 @@
|
|||
*/
|
||||
int sysinfo(struct sysinfo *info) {
|
||||
int rc;
|
||||
if (IsAsan()) {
|
||||
if (info && !__asan_is_valid(info, sizeof(*info))) {
|
||||
return efault();
|
||||
}
|
||||
}
|
||||
memset(info, 0, sizeof(*info));
|
||||
if (!IsWindows()) {
|
||||
rc = sys_sysinfo(info);
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
|
@ -30,6 +32,11 @@
|
|||
* @see stat()
|
||||
*/
|
||||
int utimes(const char *path, const struct timeval tv[2]) {
|
||||
if (IsAsan()) {
|
||||
if (tv && !__asan_is_valid(tv, sizeof(*tv) * 2)) {
|
||||
return efault();
|
||||
}
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
/*
|
||||
* we don't modernize utimes() into utimensat() because the
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/wait4.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Waits for status to change on process.
|
||||
|
@ -35,6 +37,16 @@
|
|||
*/
|
||||
int wait4(int pid, int *opt_out_wstatus, int options,
|
||||
struct rusage *opt_out_rusage) {
|
||||
if (IsAsan()) {
|
||||
if (opt_out_wstatus &&
|
||||
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) {
|
||||
return efault();
|
||||
}
|
||||
if (opt_out_rusage &&
|
||||
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))) {
|
||||
return efault();
|
||||
}
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_wait4(pid, opt_out_wstatus, options, opt_out_rusage);
|
||||
} else {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
@ -34,18 +35,21 @@
|
|||
* @return number of bytes actually handed off, or -1 w/ errno
|
||||
*/
|
||||
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
||||
if (fd < 0) return einval();
|
||||
if (iovlen < 0) return einval();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_write)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_writev(fd, iov, iovlen);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
|
||||
if (fd >= 0 && iovlen >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_write)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_writev(fd, iov, iovlen);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
|
||||
} else {
|
||||
return sys_writev_nt(g_fds.p + fd, iov, iovlen);
|
||||
}
|
||||
} else {
|
||||
return sys_writev_nt(g_fds.p + fd, iov, iovlen);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue