Skip to content

Commit

Permalink
Make redbean StoreAsset() work better
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
jart committed May 14, 2021
1 parent 919b6fe commit 690be54
Show file tree
Hide file tree
Showing 228 changed files with 3,661 additions and 3,023 deletions.
Binary file modified build/bootstrap/compile.com
Binary file not shown.
1 change: 0 additions & 1 deletion examples/curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ai.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sock.h"
Expand Down
6 changes: 3 additions & 3 deletions libc/calls/calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
109 changes: 81 additions & 28 deletions libc/calls/fcntl-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
31 changes: 31 additions & 0 deletions libc/calls/fcntl-sysv.c
Original file line number Diff line number Diff line change
@@ -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;
}
10 changes: 8 additions & 2 deletions libc/calls/fcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,22 @@
*
* 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
* @asyncsignalsafe
*/
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);
Expand Down
2 changes: 1 addition & 1 deletion libc/calls/fixupnewfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions libc/calls/flock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions libc/calls/fstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions libc/calls/fstatat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

/**
Expand All @@ -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()) {
Expand Down
2 changes: 1 addition & 1 deletion libc/calls/getcwd-xnu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion libc/calls/getppid.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* Returns parent process id.
* @asyncsignalsafe
*/
int32_t getppid(void) {
int getppid(void) {
if (!IsWindows()) {
if (!IsNetbsd()) {
return sys_getppid();
Expand Down
7 changes: 5 additions & 2 deletions libc/calls/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 ─╬─│┼
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 690be54

Please sign in to comment.