mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Perform some code cleanup
This commit is contained in:
parent
174d288e66
commit
fe3216e961
14 changed files with 803 additions and 312 deletions
|
@ -41,7 +41,6 @@
|
|||
* @param size in range [1..0x7ffff000] is reasonable
|
||||
* @return [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with
|
||||
* exception of size==0, in which case return zero means no error
|
||||
* @see write(), pread(), readv()
|
||||
* @asyncsignalsafe
|
||||
* @restartable
|
||||
* @vforksafe
|
||||
|
@ -49,7 +48,7 @@
|
|||
ssize_t read(int fd, void *buf, size_t size) {
|
||||
ssize_t rc;
|
||||
if (fd >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
if ((!buf && size) || (IsAsan() && !__asan_is_valid(buf, size))) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = _weaken(__zipos_read)(
|
||||
|
@ -65,7 +64,7 @@ ssize_t read(int fd, void *buf, size_t size) {
|
|||
rc = sys_readv_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
}
|
||||
} else {
|
||||
rc = einval();
|
||||
rc = ebadf();
|
||||
}
|
||||
DATATRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)),
|
||||
buf, rc > 40 ? "..." : "", size, rc);
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
* @restartable
|
||||
*/
|
||||
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
||||
int i;
|
||||
ssize_t rc;
|
||||
|
||||
if (fd >= 0 && iovlen >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
||||
rc = efault();
|
||||
|
@ -67,9 +67,12 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
|||
} else {
|
||||
rc = sys_readv_nt(g_fds.p + fd, iov, iovlen);
|
||||
}
|
||||
} else if (fd < 0) {
|
||||
rc = ebadf();
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
|
||||
#if defined(SYSDEBUG) && _DATATRACE
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
if (rc == -1 && errno == EFAULT) {
|
||||
|
@ -81,5 +84,6 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/rlimit.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -43,6 +43,8 @@
|
|||
* - `RLIMIT_FSIZE` causes `SIGXFSZ` to sent to the process when the
|
||||
* soft limit on file size is exceeded and the process is destroyed
|
||||
* when the hard limit is exceeded. It works everywhere but Windows
|
||||
* and it also causes `EFBIG` to be returned by i/o functions after
|
||||
* the `SIGXFSZ` signal is delivered or ignored
|
||||
*
|
||||
* - `RLIMIT_NPROC` limits the number of simultaneous processes and it
|
||||
* should work on all platforms except Windows. Please be advised it
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nt/enum/threadaccess.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/thread.h"
|
||||
|
@ -48,6 +48,7 @@ static textwindows int sys_tkill_nt(int tid, int sig) {
|
|||
* @param tid is thread id
|
||||
* @param sig does nothing on xnu
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int tkill(int tid, int sig) {
|
||||
int rc;
|
||||
|
|
|
@ -34,12 +34,27 @@
|
|||
* This function changes the current file position. For documentation
|
||||
* on file position behaviors and gotchas, see the lseek() function.
|
||||
*
|
||||
* @param fd is something open()'d earlier
|
||||
* @param fd is open file descriptor
|
||||
* @param buf is copied from, cf. copy_file_range(), sendfile(), etc.
|
||||
* @param size in range [1..0x7ffff000] is reasonable
|
||||
* @return [1..size] bytes on success, or -1 w/ errno; noting zero is
|
||||
* impossible unless size was passed as zero to do an error check
|
||||
* @see read(), pwrite(), writev(), SIGPIPE
|
||||
* @raise EBADF if `fd` is negative or not an open file descriptor
|
||||
* @raise EBADF if `fd` wasn't opened with `O_WRONLY` or `O_RDWR`
|
||||
* @raise EPIPE if `fd` is a pipe whose other reader end was closed,
|
||||
* after the `SIGPIPE` signal was delivered, blocked, or ignored
|
||||
* @raise EFBIG if `RLIMIT_FSIZE` soft limit was exceeded, after the
|
||||
* `SIGXFSZ` signal was either delivered, blocked, or ignored
|
||||
* @raise EFAULT if `size` is nonzero and `buf` points to bad memory
|
||||
* @raise EPERM if pledge() is in play without the stdio promise
|
||||
* @raise ENOSPC if device containing `fd` is full
|
||||
* @raise EIO if low-level i/o error happened
|
||||
* @raise EINTR if signal was delivered instead
|
||||
* @raise EAGAIN if `O_NONBLOCK` is in play and write needs to block
|
||||
* @raise ENOBUFS if kernel lacked internal resources; which FreeBSD
|
||||
* and XNU say could happen with sockets, and OpenBSD documents it
|
||||
* as a general possibility; whereas other system don't specify it
|
||||
* @raise ENXIO is specified only by POSIX and XNU when a request is
|
||||
* made of a nonexistent device or outside device capabilities
|
||||
* @asyncsignalsafe
|
||||
* @restartable
|
||||
* @vforksafe
|
||||
|
@ -47,7 +62,7 @@
|
|||
ssize_t write(int fd, const void *buf, size_t size) {
|
||||
ssize_t rc;
|
||||
if (fd >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
if ((!buf && size) || (IsAsan() && !__asan_is_valid(buf, size))) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = _weaken(__zipos_write)(
|
||||
|
@ -63,7 +78,7 @@ ssize_t write(int fd, const void *buf, size_t size) {
|
|||
rc = sys_writev_nt(fd, &(struct iovec){buf, size}, 1);
|
||||
}
|
||||
} else {
|
||||
rc = einval();
|
||||
rc = ebadf();
|
||||
}
|
||||
DATATRACE("write(%d, %#.*hhs%s, %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)),
|
||||
buf, rc > 40 ? "..." : "", size, rc);
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
* @restartable
|
||||
*/
|
||||
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
||||
int i;
|
||||
ssize_t rc;
|
||||
|
||||
if (fd >= 0 && iovlen >= 0) {
|
||||
|
@ -72,6 +71,8 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
|||
} else {
|
||||
rc = sys_writev_nt(fd, iov, iovlen);
|
||||
}
|
||||
} else if (fd < 0) {
|
||||
rc = ebadf();
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
|
|
|
@ -488,13 +488,11 @@ static int CloneLinux(int (*func)(void *arg, int tid), char *stk, size_t stksz,
|
|||
// COSMOPOLITAN
|
||||
|
||||
/**
|
||||
* Creates thread without malloc being linked, e.g.
|
||||
* Creates thread without malloc being linked.
|
||||
*
|
||||
* int worker(void *arg) {
|
||||
* return 0;
|
||||
* }
|
||||
* If you use clone() you're on you're own, e.g.
|
||||
*
|
||||
* // NOTE: See _mktls() for _Thread_local support.
|
||||
* int worker(void *arg) { return 0; }
|
||||
* struct CosmoTib tib = {.tib_self = &tib, .tib_tid = -1};
|
||||
* char *stk = _mapstack();
|
||||
* tid = clone(worker, stk, GetStackSize() - 16,
|
||||
|
|
|
@ -100,4 +100,7 @@ void _wait0(const atomic_int *ctid) {
|
|||
_wait0_poll(&ts);
|
||||
}
|
||||
}
|
||||
if (IsOpenbsd()) {
|
||||
sched_yield(); // TODO(jart): whhhy?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ bool IsMulticastIp(uint32_t);
|
|||
bool IsAnonymousIp(uint32_t);
|
||||
int CategorizeIp(uint32_t);
|
||||
const char *GetIpCategoryName(int);
|
||||
bool IsCloudflareIp(uint32_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
42
net/http/iscloudflare.c
Normal file
42
net/http/iscloudflare.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- 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 2022 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 "net/http/ip.h"
|
||||
|
||||
/**
|
||||
* Returns true if `x` is Cloudflare IPv4 address.
|
||||
*
|
||||
* @see https://www.cloudflare.com/ips/ (April 8, 2021)
|
||||
*/
|
||||
bool IsCloudflareIp(uint32_t x) {
|
||||
return (x & 0xfffffc00) == 0x6715f400 || // 103.21.244.0/22
|
||||
(x & 0xfffffc00) == 0x6716c800 || // 103.22.200.0/22
|
||||
(x & 0xfffffc00) == 0x671f0400 || // 103.31.4.0/22
|
||||
(x & 0xfff80000) == 0x68100000 || // 104.16.0.0/13
|
||||
(x & 0xfffc0000) == 0x68180000 || // 104.24.0.0/14
|
||||
(x & 0xffffc000) == 0x6ca2c000 || // 108.162.192.0/18
|
||||
(x & 0xfffffc00) == 0x83004800 || // 131.0.72.0/22
|
||||
(x & 0xffffc000) == 0x8d654000 || // 141.101.64.0/18
|
||||
(x & 0xfffe0000) == 0xa29e0000 || // 162.158.0.0/15
|
||||
(x & 0xfff80000) == 0xac400000 || // 172.64.0.0/13
|
||||
(x & 0xfffff000) == 0xadf53000 || // 173.245.48.0/20
|
||||
(x & 0xfffff000) == 0xbc726000 || // 188.114.96.0/20
|
||||
(x & 0xfffff000) == 0xbe5df000 || // 190.93.240.0/20
|
||||
(x & 0xfffffc00) == 0xc5eaf000 || // 197.234.240.0/22
|
||||
(x & 0xffff8000) == 0xc6298000; // 198.41.128.0/17
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -20,13 +20,81 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/subprocess.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
char testlib_enable_tmp_setup_teardown;
|
||||
|
||||
TEST(write, notOpen_ebadf) {
|
||||
ASSERT_SYS(EBADF, -1, write(-1, 0, 0));
|
||||
ASSERT_SYS(EBADF, -1, write(+3, 0, 0));
|
||||
}
|
||||
|
||||
TEST(write, readOnlyFd_ebadf) {
|
||||
ASSERT_SYS(0, 0, touch("foo", 0644));
|
||||
ASSERT_SYS(0, 3, open("foo", O_RDONLY));
|
||||
ASSERT_SYS(EBADF, -1, write(3, "x", 1));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
||||
TEST(write, badMemory_efault) {
|
||||
ASSERT_SYS(EFAULT, -1, write(1, 0, 1));
|
||||
if (!IsAsan()) return;
|
||||
ASSERT_SYS(EFAULT, -1, write(1, (void *)1, 1));
|
||||
}
|
||||
|
||||
TEST(write, brokenPipe_sigpipeIgnored_returnsEpipe) {
|
||||
int fds[2];
|
||||
SPAWN(fork);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
ASSERT_SYS(0, 0, pipe(fds));
|
||||
ASSERT_SYS(0, 1, write(4, "x", 1));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(EPIPE, -1, write(4, "x", 1));
|
||||
ASSERT_SYS(0, 0, close(4));
|
||||
EXITS(0);
|
||||
}
|
||||
|
||||
TEST(write, brokenPipe_sigpipeBlocked_returnsEpipe) {
|
||||
int fds[2];
|
||||
sigset_t mask;
|
||||
SPAWN(fork);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGPIPE);
|
||||
sigprocmask(SIG_BLOCK, &mask, 0);
|
||||
ASSERT_SYS(0, 0, pipe(fds));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(EPIPE, -1, write(4, "x", 1));
|
||||
ASSERT_SYS(0, 0, close(4));
|
||||
EXITS(0);
|
||||
}
|
||||
|
||||
TEST(write, rlimitFsizeExceeded_raisesEfbig) {
|
||||
if (IsWindows()) return; // not supported
|
||||
struct rlimit rl = {1, 10};
|
||||
SPAWN(fork);
|
||||
signal(SIGXFSZ, SIG_IGN);
|
||||
ASSERT_SYS(0, 0, setrlimit(RLIMIT_FSIZE, &rl));
|
||||
ASSERT_SYS(0, 3, creat("foo", 0644));
|
||||
ASSERT_SYS(0, 1, write(3, "x", 1));
|
||||
ASSERT_SYS(EFBIG, -1, write(3, "x", 1));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
EXITS(0);
|
||||
}
|
||||
|
||||
static long Write(long fd, const void *data, unsigned long size) {
|
||||
long ax, di, si, dx;
|
||||
asm volatile("syscall"
|
||||
|
|
|
@ -20,12 +20,15 @@
|
|||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/iov.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
@ -35,6 +38,32 @@ void SetUpOnce(void) {
|
|||
ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath fattr", 0));
|
||||
}
|
||||
|
||||
TEST(writev, negativeFd_ebadf) {
|
||||
ASSERT_SYS(EBADF, -1, writev(-1, 0, 0));
|
||||
}
|
||||
|
||||
TEST(writev, negativeCount_einval) {
|
||||
ASSERT_SYS(EINVAL, -1, writev(1, 0, -1));
|
||||
}
|
||||
|
||||
TEST(writev, negative_einvalOrEfault) {
|
||||
struct iovec v[] = {{"", -1}};
|
||||
ASSERT_EQ(-1, writev(1, v, 1));
|
||||
ASSERT_TRUE(errno == EINVAL || errno == EFAULT);
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
TEST(writev, exceedsIovMax_einval) {
|
||||
if (IsWindows()) return; // it's complicated
|
||||
int i, n = IOV_MAX + 1;
|
||||
struct iovec *v = _gc(malloc(sizeof(struct iovec) * n));
|
||||
for (i = 0; i < n; ++i) {
|
||||
v[i].iov_base = "x";
|
||||
v[i].iov_len = 1;
|
||||
}
|
||||
ASSERT_SYS(EINVAL, -1, writev(1, v, n));
|
||||
}
|
||||
|
||||
TEST(writev, test) {
|
||||
int fd;
|
||||
char ba[1] = "a";
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "libc/atomic.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/thread/spawn.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
|
Loading…
Reference in a new issue