Compare commits

...

11 commits

Author SHA1 Message Date
wingdeans 43573173c6
Merge a1f5160fab into 5488f0b2ca 2024-05-03 11:28:50 -04:00
Gautham 5488f0b2ca
Remove zlib namespacing (#1142)
We have an optimized version of zlib from the Chromium project.
We need it for a lot of our libc services. It would be nice to export
this to user applications if we can, since projects like llamafile are
already depending on it under the private namespace, to avoid
needing to link zlib twice.
2024-05-03 08:07:25 -07:00
Gavin Hayes deff138e7e
recvfrom: don't convert address if addrsize is 0 (#1153) 2024-05-03 08:03:57 -07:00
Gavin Hayes b6e40a3a58
Add /dev/(u)random on NT (#1163) 2024-05-03 07:59:51 -07:00
Cadence Ember 8f6bc9dabc
Let signals interrupt fgets unless SA_RESTART set (#1152) 2024-05-03 07:49:41 -07:00
Justine Tunney 181cd4cbe8
Add sysctlbyname() for MacOS 2024-05-02 23:21:43 -07:00
Justine Tunney 5c6877b02b
Introduce support for trapping math
The feenableexcept() and fedisableexcept() APIs are now provided which
let you detect when NaNs appear the moment it happens from anywhere in
your program. Tests have also been added for the mission critical math
functions expf() and erff(), whose perfect operation has been assured.
See examples/trapping.c to see how to use this powerful functionality.
2024-04-30 13:38:43 -07:00
Justine Tunney 403bc25412
Make MXCSR editable by signal handlers on Windows
It's now possible to recover from floating point exception traps.
2024-04-30 13:38:43 -07:00
Matt Colyer 3bcd40be12
Fix regression in apeinstall.sh (#1161)
This should have been a part of a6baba1.
2024-04-29 20:40:38 -07:00
Paul Kulchenko fcfdd26b72
Fix wrong parameter type in redbean documentation (#1162) 2024-04-29 20:09:25 -04:00
wingdeans a1f5160fab isutf8: implement RFC 3629
reject surrogate pairs (U+D800 to U+DFFF)
reject greater than U+10FFFF
2023-12-28 16:21:48 -05:00
65 changed files with 1098 additions and 85 deletions

View file

@ -31,6 +31,8 @@
#include <string.h>
#include <sys/mman.h>
#include <sys/random.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <time.h>
#include <unistd.h>
@ -39,7 +41,7 @@
/* maximum path size that cosmo can take */
#define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024)
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
#define SYSLIB_VERSION 9 /* sync with libc/runtime/syslib.internal.h */
#define SYSLIB_VERSION 10 /* sync with libc/runtime/syslib.internal.h */
struct Syslib {
int magic;
@ -106,6 +108,10 @@ struct Syslib {
OPTIONAL (cosmo lib should check __syslib->version) */
/* v9 (2024-01-31) */
int (*pthread_cpu_number_np)(size_t *);
/* v10 (2024-05-02) */
long (*sysctl)(int *, u_int, void *, size_t *, void *, size_t);
long (*sysctlbyname)(const char *, void *, size_t *, void *, size_t);
long (*sysctlnametomib)(const char *, int *, size_t *);
};
#define ELFCLASS32 1
@ -148,8 +154,8 @@ struct Syslib {
#define _COMM_PAGE_APRR_WRITE_ENABLE (_COMM_PAGE_START_ADDRESS + 0x110)
#define _COMM_PAGE_APRR_WRITE_DISABLE (_COMM_PAGE_START_ADDRESS + 0x118)
#define MIN(X, Y) ((Y) > (X) ? (X) : (Y))
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
#define Min(X, Y) ((Y) > (X) ? (X) : (Y))
#define Max(X, Y) ((Y) < (X) ? (X) : (Y))
#define READ32(S) \
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
@ -552,6 +558,20 @@ static long sys_pselect(int nfds, fd_set *readfds, fd_set *writefds,
return sysret(pselect(nfds, readfds, writefds, errorfds, timeout, sigmask));
}
static long sys_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen) {
return sysret(sysctl(name, namelen, oldp, oldlenp, newp, newlen));
}
static long sys_sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
void *newp, size_t newlen) {
return sysret(sysctlbyname(name, oldp, oldlenp, newp, newlen));
}
static long sys_sysctlnametomib(const char *name, int *mibp, size_t *sizep) {
return sysret(sysctlnametomib(name, mibp, sizep));
}
__attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
long *sp, struct ElfEhdr *e,
struct ElfPhdr *p,
@ -596,7 +616,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
continue;
c = p[j].p_vaddr & -pagesz;
d = (p[j].p_vaddr + p[j].p_memsz + (pagesz - 1)) & -pagesz;
if (MAX(a, c) < MIN(b, d)) {
if (Max(a, c) < Min(b, d)) {
Pexit(exe, 0, "ELF segments overlap each others virtual memory");
}
}
@ -670,7 +690,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
a = p[i].p_vaddr + p[i].p_filesz; /* end of file content */
b = (a + (pagesz - 1)) & -pagesz; /* first pure bss page */
c = p[i].p_vaddr + p[i].p_memsz; /* end of segment data */
wipe = MIN(b - a, c - a);
wipe = Min(b - a, c - a);
if (wipe && (~prot1 & PROT_WRITE)) {
prot1 = PROT_READ | PROT_WRITE;
}
@ -970,6 +990,9 @@ int main(int argc, char **argv, char **envp) {
M->lib.dlclose = dlclose;
M->lib.dlerror = dlerror;
M->lib.pthread_cpu_number_np = pthread_cpu_number_np;
M->lib.sysctl = sys_sysctl;
M->lib.sysctlbyname = sys_sysctlbyname;
M->lib.sysctlnametomib = sys_sysctlnametomib;
/* getenv("_") is close enough to at_execfn */
execfn = 0;

View file

@ -10,8 +10,8 @@ if [ ! -f ape/loader.c ]; then
cd "$COSMO" || exit
fi
if [ -x build/bootstrap/make.com ]; then
MAKE=build/bootstrap/make.com
if [ -x build/bootstrap/make ]; then
MAKE=build/bootstrap/make
else
MAKE=make
fi

142
examples/trapping.c Normal file
View file

@ -0,0 +1,142 @@
#include <fenv.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <ucontext.h>
#include <unistd.h>
#include "libc/calls/struct/aarch64.internal.h"
/*
Do you put lots of assert(!isnan(x)) in your code??
Your microprocessor has a feature to automate this.
Uncaught SIGFPE (FPE_FLTINV)
__math_invalidf at libc/tinymath/math_errf.c:88
logf at libc/tinymath/logf.c:100
main at examples/trapping.c:29
cosmo at libc/runtime/cosmo.S:105
_start at libc/crt/crt.S:116
This file shows how to use floating point exception
trapping with Cosmopolitan Libc.
*/
#define TRAPS (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)
void spring_trap(int sig, siginfo_t *si, void *arg) {
// print signal safely
const char *msg;
int sic = si->si_code;
if (sic == FPE_INTDIV)
msg = "FPE_INTDIV: "; // integer divide by zero
else if (sic == FPE_INTOVF)
msg = "FPE_INTOVF: "; // integer overflow
else if (sic == FPE_FLTDIV)
msg = "FPE_FLTDIV: "; // floating point divide by zero
else if (sic == FPE_FLTOVF)
msg = "FPE_FLTOVF: "; // floating point overflow
else if (sic == FPE_FLTUND)
msg = "FPE_FLTUND: "; // floating point underflow
else if (sic == FPE_FLTRES)
msg = "FPE_FLTRES: "; // floating point inexact
else if (sic == FPE_FLTINV)
msg = "FPE_FLTINV: "; // invalid floating point operation
else if (sic == FPE_FLTSUB)
msg = "FPE_FLTSUB: "; // subscript out of range
else
msg = "SIGFPE: ";
write(1, msg, strlen(msg));
// recover from trap so that execution may resume
// without this the same signal will just keep getting raised
ucontext_t *ctx = arg;
#ifdef __x86_64__
if (ctx->uc_mcontext.fpregs) {
ctx->uc_mcontext.fpregs->mxcsr |= TRAPS << 7; // disable traps
ctx->uc_mcontext.fpregs->mxcsr &= ~TRAPS; // clear cages
return;
}
#elif defined(__aarch64__)
struct _aarch64_ctx *ac;
for (ac = (struct _aarch64_ctx *)ctx->uc_mcontext.__reserved; ac->magic;
ac = (struct _aarch64_ctx *)((char *)ac + ac->size)) {
if (ac->magic == FPSIMD_MAGIC) {
struct fpsimd_context *sm = (struct fpsimd_context *)ac;
sm->fpcr &= ~(TRAPS << 8); // disable traps
sm->fpsr &= ~TRAPS; // clear cages
return;
}
}
#endif
// exit if we can't recover execution
msg = "cannot recover from signal\n";
write(1, msg, strlen(msg));
_exit(1);
}
void setup_trap(void) {
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = spring_trap;
sigaction(SIGFPE, &sa, 0);
}
void activate_trap(void) {
feclearexcept(TRAPS);
if (feenableexcept(TRAPS)) {
static bool once;
if (!once) {
fprintf(stderr, "warning: trapping math isn't supported on this cpu\n");
once = true;
}
}
}
float ident(float x) {
return x;
}
float (*veil)(float) = ident;
int main(int argc, char *argv[]) {
float x;
setup_trap();
// test illegal math
activate_trap();
x = 0 / veil(0);
printf("0/0 = %g\n", x);
// test divide by zero
activate_trap();
x = 1 / veil(0);
printf("1/0 = %g\n", x);
// test divide by zero again
activate_trap();
x = -1 / veil(0);
printf("-1/0 = %g\n", x);
// test domain error
activate_trap();
x = logf(veil(-1));
printf("log(-1) = %g\n", x);
// test imaginary number
activate_trap();
x = sqrtf(veil(-1));
printf("sqrt(-1) = %g\n", x);
// test overflow
activate_trap();
x = expf(veil(88.8));
printf("expf(88.8) = %g\n", x);
// test underflow
activate_trap();
x = expf(veil(-104));
printf("expf(-104) = %g\n", x);
}

View file

@ -237,7 +237,9 @@ int sys_munlock(const void *, size_t) libcesque;
int sys_munlockall(void) libcesque;
int sys_personality(uint64_t) libcesque;
int sys_ptrace(int, ...) libcesque;
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int sysctl(int *, unsigned, void *, size_t *, void *, size_t) libcesque;
int sysctlbyname(const char *, void *, size_t *, void *, size_t) libcesque;
int sysctlnametomib(const char *, int *, size_t *) libcesque;
int tmpfd(void) libcesque;
int touch(const char *, unsigned) libcesque;
int unveil(const char *, const char *) libcesque;

View file

@ -53,7 +53,7 @@ static dontinline int __clk_tck_init(void) {
cmd[0] = 1; // CTL_KERN
cmd[1] = 12; // KERN_CLOCKRATE
len = sizeof(clock);
if (sys_sysctl(cmd, 2, &clock, &len, NULL, 0) != -1) {
if (sysctl(cmd, 2, &clock, &len, NULL, 0) != -1) {
x = clock.hz;
} else {
x = -1;

View file

@ -67,7 +67,7 @@ int sys_clock_gettime_xnu(int clock, struct timespec *ts) {
struct timeval x;
size_t n = sizeof(x);
int mib[] = {CTL_KERN, KERN_BOOTTIME};
if (sys_sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1)
if (sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1)
return -1;
if (ts)
*ts = timeval_totimespec(timeval_sub(timeval_real(), x));

View file

@ -332,7 +332,8 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
if (__isfdkind(fd, kFdFile) || //
__isfdkind(fd, kFdSocket) || //
__isfdkind(fd, kFdConsole) || //
__isfdkind(fd, kFdDevNull)) {
__isfdkind(fd, kFdDevNull) || //
__isfdkind(fd, kFdDevRandom)) {
if (cmd == F_GETFL) {
rc = g_fds.p[fd].flags & (O_ACCMODE | _O_APPEND | _O_DIRECT |
_O_NONBLOCK | _O_RANDOM | _O_SEQUENTIAL);

View file

@ -104,6 +104,7 @@ textwindows int sys_fstat_nt(int fd, struct stat *st) {
return ebadf();
case kFdConsole:
case kFdDevNull:
case kFdDevRandom:
return sys_fstat_nt_special(g_fds.p[fd].kind, st);
case kFdSocket:
return sys_fstat_nt_socket(g_fds.p[fd].kind, st);

View file

@ -59,6 +59,8 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
return sys_fstat_nt_special(kFdConsole, st);
} else if (!strcmp(path + 5, "null")) {
return sys_fstat_nt_special(kFdDevNull, st);
} else if (!strcmp(path + 5, "random") || !strcmp(path + 5, "urandom")) {
return sys_fstat_nt_special(kFdDevRandom, st);
} else if (!strcmp(path + 5, "stdin")) {
return sys_fstat_nt(STDIN_FILENO, st);
} else if (!strcmp(path + 5, "stdout")) {

View file

@ -51,7 +51,7 @@ static int __get_cpu_count_bsd(void) {
} else {
cmd[1] = HW_NCPU;
}
if (!sys_sysctl(cmd, 2, &c, &n, 0, 0)) {
if (!sysctl(cmd, 2, &c, &n, 0, 0)) {
return c;
} else {
return -1;

View file

@ -24,7 +24,7 @@
int gethostname_bsd(char *name, size_t len, int kind) {
int cmd[2] = {CTL_KERN, kind};
if (sys_sysctl(cmd, 2, name, &len, 0, 0) != -1) {
if (sysctl(cmd, 2, name, &len, 0, 0) != -1) {
return 0;
} else {
if (errno == ENOMEM) {

View file

@ -64,7 +64,7 @@ int getloadavg(double *a, int n) {
struct loadavg loadinfo;
int mib[2] = {CTL_VM, VM_LOADAVG};
size = sizeof(loadinfo);
if ((rc = sys_sysctl(mib, 2, &loadinfo, &size, 0, 0)) != -1) {
if ((rc = sysctl(mib, 2, &loadinfo, &size, 0, 0)) != -1) {
for (i = 0; i < n; i++) {
a[i] = (double)loadinfo.ldavg[i] / loadinfo.fscale;
}

View file

@ -195,7 +195,7 @@ static inline void InitProgramExecutableNameImpl(void) {
cmd[2] = KERN_PROC_PATHNAME_NETBSD;
}
cmd[3] = -1; // current process
if (sys_sysctl(cmd, ARRAYLEN(cmd), b, &n, 0, 0) != -1) {
if (sysctl(cmd, ARRAYLEN(cmd), b, &n, 0, 0) != -1) {
if (!OldApeLoader(b)) {
goto UseBuf;
}

View file

@ -70,7 +70,7 @@ static void GetRandomArnd(char *p, size_t n) {
cmd[0] = 1; // CTL_KERN
cmd[1] = IsFreebsd() ? 37 : 81; // KERN_ARND
unassert((m = n) <= 256);
if (sys_sysctl(cmd, 2, p, &n, 0, 0) == -1)
if (sysctl(cmd, 2, p, &n, 0, 0) == -1)
notpossible;
if (m != n)
notpossible;

View file

@ -24,7 +24,6 @@
#include "libc/calls/termios.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/serialize.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
@ -42,6 +41,7 @@
#include "libc/nt/winsock.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/serialize.h"
#include "libc/sock/internal.h"
#include "libc/sock/struct/ifconf.h"
#include "libc/sock/struct/ifreq.h"
@ -66,7 +66,7 @@ static struct HostAdapterInfoNode {
struct sockaddr netmask;
struct sockaddr broadcast;
short flags;
} *__hostInfo;
} * __hostInfo;
static int ioctl_default(int fd, unsigned long request, void *arg) {
int rc;
@ -107,8 +107,9 @@ static int ioctl_fionread(int fd, uint32_t *arg) {
*arg = MAX(0, bytes);
return 0;
} else if (g_fds.p[fd].kind == kFdDevNull) {
*arg = 1;
return 0;
return enotty();
} else if (g_fds.p[fd].kind == kFdDevRandom) {
return einval();
} else if (GetFileType(handle) == kNtFileTypePipe) {
uint32_t avail;
if (PeekNamedPipe(handle, 0, 0, 0, &avail, 0)) {

View file

@ -55,6 +55,7 @@ bool32 ischardev(int fd) {
}
} else {
return __isfdkind(fd, kFdConsole) || __isfdkind(fd, kFdDevNull) ||
__isfdkind(fd, kFdDevRandom) ||
(__isfdkind(fd, kFdFile) &&
GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar);
}

View file

@ -62,7 +62,7 @@ static textwindows int64_t Seek(struct Fd *f, int64_t offset, int whence) {
}
textwindows int64_t sys_lseek_nt(int fd, int64_t offset, int whence) {
if (__isfdkind(fd, kFdDevNull)) {
if (__isfdkind(fd, kFdDevNull) || __isfdkind(fd, kFdDevRandom)) {
return offset;
} else if (__isfdkind(fd, kFdFile)) {
struct Fd *f = g_fds.p + fd;

View file

@ -159,6 +159,15 @@ static textwindows int sys_open_nt_special(int fd, int flags, int mode,
return fd;
}
static textwindows int sys_open_nt_no_handle(int fd, int flags, int mode,
int kind) {
g_fds.p[fd].kind = kind;
g_fds.p[fd].mode = mode;
g_fds.p[fd].flags = flags;
g_fds.p[fd].handle = -1;
return fd;
}
static textwindows int sys_open_nt_dup(int fd, int flags, int mode, int oldfd) {
int64_t handle;
if (!__isfdopen(oldfd)) {
@ -211,6 +220,8 @@ textwindows int sys_open_nt(int dirfd, const char *file, uint32_t flags,
rc = sys_open_nt_special(fd, flags, mode, kFdConsole, u"CONIN$");
} else if (!strcmp(file + 5, "null")) {
rc = sys_open_nt_special(fd, flags, mode, kFdDevNull, u"NUL");
} else if (!strcmp(file + 5, "urandom") || !strcmp(file + 5, "random")) {
rc = sys_open_nt_no_handle(fd, flags, mode, kFdDevRandom);
} else if (!strcmp(file + 5, "stdin")) {
rc = sys_open_nt_dup(fd, flags, mode, STDIN_FILENO);
} else if (!strcmp(file + 5, "stdout")) {

View file

@ -72,7 +72,8 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) {
rc = sys_pread(fd, buf, size, offset, offset);
} else if (__isfdkind(fd, kFdSocket)) {
rc = espipe();
} else if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdDevNull)) {
} else if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdDevNull) ||
__isfdkind(fd, kFdDevRandom)) {
rc = sys_read_nt(fd, (struct iovec[]){{buf, size}}, 1, offset);
} else {
rc = ebadf();

View file

@ -40,6 +40,8 @@ static const char *__fdkind2str(int x) {
return "kFdZip";
case kFdEpoll:
return "kFdEpoll";
case kFdDevRandom:
return "kFdRandom";
default:
return "kFdWut";
}

View file

@ -65,7 +65,8 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) {
rc = sys_pwrite(fd, buf, size, offset, offset);
} else if (__isfdkind(fd, kFdSocket)) {
rc = espipe();
} else if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdDevNull)) {
} else if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdDevNull) ||
__isfdkind(fd, kFdDevRandom)) {
rc = sys_write_nt(fd, (struct iovec[]){{(void *)buf, size}}, 1, offset);
} else {
return ebadf();

View file

@ -786,6 +786,10 @@ textwindows ssize_t ReadBuffer(int fd, void *data, size_t size, int64_t offset,
return 0;
}
if (f->kind == kFdDevRandom) {
return ProcessPrng(data, size) ? size : __winerr();
}
if (f->kind == kFdConsole) {
return ReadFromConsole(f, data, size, waitmask);
}

View file

@ -29,6 +29,7 @@ textwindows ssize_t sys_readv_nt(int fd, const struct iovec *iov, int iovlen) {
case kFdFile:
case kFdConsole:
case kFdDevNull:
case kFdDevRandom:
return sys_read_nt(fd, iov, iovlen, -1);
case kFdSocket:
return _weaken(sys_recv_nt)(fd, iov, iovlen, 0);

View file

@ -61,7 +61,7 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
bool pwriting = offset != -1;
bool seekable =
(f->kind == kFdFile && GetFileType(handle) == kNtFileTypeDisk) ||
f->kind == kFdDevNull;
f->kind == kFdDevNull || f->kind == kFdDevRandom;
if (pwriting && !seekable) {
return espipe();
}

View file

@ -2,15 +2,16 @@
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FD_INTERNAL_H_
COSMOPOLITAN_C_START_
#define kFdEmpty 0
#define kFdFile 1
#define kFdSocket 2
#define kFdConsole 4
#define kFdSerial 5
#define kFdZip 6
#define kFdEpoll 7
#define kFdReserved 8
#define kFdDevNull 9
#define kFdEmpty 0
#define kFdFile 1
#define kFdSocket 2
#define kFdConsole 4
#define kFdSerial 5
#define kFdZip 6
#define kFdEpoll 7
#define kFdReserved 8
#define kFdDevNull 9
#define kFdDevRandom 10
struct Fd {
char kind;

33
libc/calls/sysctl.c Normal file
View file

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/runtime/syslib.internal.h"
int sys_sysctl(int *, unsigned, void *, size_t *, void *, size_t) libcesque;
int sysctl(int *name, unsigned namelen, void *oldp, size_t *oldlenp, void *newp,
size_t newlen) {
if (__syslib && __syslib->__version >= 10) {
return _sysret(
__syslib->__sysctl(name, namelen, oldp, oldlenp, newp, newlen));
} else {
return sys_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
}
}

31
libc/calls/sysctlbyname.c Normal file
View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/errfuns.h"
int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
size_t newlen) {
if (__syslib && __syslib->__version >= 10) {
return _sysret(__syslib->__sysctlbyname(name, oldp, oldlenp, newp, newlen));
} else {
return enosys();
}
}

View file

@ -0,0 +1,30 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/errfuns.h"
int sysctlnametomib(const char *name, int *mibp, size_t *sizep) {
if (__syslib && __syslib->__version >= 10) {
return _sysret(__syslib->__sysctlnametomib(name, mibp, sizep));
} else {
return enosys();
}
}

View file

@ -46,7 +46,7 @@ static int64_t GetUptime(void) {
struct timeval x;
size_t n = sizeof(x);
int mib[] = {CTL_KERN, KERN_BOOTTIME};
if (sys_sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1)
if (sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1)
return 0;
return timespec_real().tv_sec - x.tv_sec;
}
@ -55,7 +55,7 @@ static int64_t GetPhysmem(void) {
uint64_t x = 0;
size_t n = sizeof(x);
int mib[] = {CTL_HW, HW_PHYSMEM};
if (sys_sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1)
if (sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1)
return 0;
return x;
}
@ -65,7 +65,7 @@ static void GetLoads(uint64_t loads[3]) {
struct loadavg loadinfo;
int mib[2] = {CTL_VM, VM_LOADAVG};
size = sizeof(loadinfo);
if (sys_sysctl(mib, 2, &loadinfo, &size, 0, 0) != -1) {
if (sysctl(mib, 2, &loadinfo, &size, 0, 0) != -1) {
for (int i = 0; i < 3; i++) {
loads[i] = (double)loadinfo.ldavg[i] / loadinfo.fscale * 65536;
}

View file

@ -43,14 +43,55 @@ struct FpuStackEntry {
};
struct thatispacked FpuState {
/* 8087 FPU Control Word
IM: Invalid Operation
DM: Denormal Operand
ZM: Zero Divide
OM: Overflow
UM: Underflow
PM: Precision
PC: Precision Control
{float,,double,long double}
RC: Rounding Control
{even, -, +, 0}
drr
0b0000001001111111 */
uint16_t cwd;
/* 8087 FPU Status Word */
uint16_t swd;
uint16_t ftw;
uint16_t fop;
uint64_t rip;
uint64_t rdp;
/* SSE CONTROL AND STATUS REGISTER
IE: Invalid Operation Flag
DE: Denormal Flag
ZE: Divide-by-Zero Flag
OE: Overflow Flag
UE: Underflow Flag
PE: Precision Flag
DAZ: Denormals Are Zeros
IM: Invalid Operation Mask
DM: Denormal Operation Mask
ZM: Divide-by-Zero Mask
OM: Overflow Mask
UM: Underflow Mask
PM: Precision Mask
RC: Rounding Control
{even, -, +, 0}
FTZ: Flush To Zero
reserved
0b00000000000000000001111110000000 */
uint32_t mxcsr;
uint32_t mxcr_mask;
struct FpuStackEntry st[8];
struct XmmRegister xmm[16];
uint32_t __padding[24];

View file

@ -62,7 +62,7 @@ static void GetBsdStr(int c0, int c1, char *s) {
size_t n = SYS_NMLN;
int cmd[2] = {c0, c1};
bzero(s, n), --n;
sys_sysctl(cmd, 2, s, &n, NULL, 0);
sysctl(cmd, 2, s, &n, NULL, 0);
errno = e;
// sysctl kern.version is too verbose for uname
if ((p = strchr(s, '\n'))) {

View file

@ -52,6 +52,11 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
struct Fd *f = g_fds.p + fd;
bool isconsole = f->kind == kFdConsole;
// not implemented, XNU returns eperm();
if (f->kind == kFdDevRandom) {
return eperm();
}
// determine win32 handle for writing
int64_t handle = f->handle;
if (isconsole && _weaken(GetConsoleOutputHandle)) {

View file

@ -28,6 +28,7 @@ textwindows ssize_t sys_writev_nt(int fd, const struct iovec *iov, int iovlen) {
case kFdFile:
case kFdConsole:
case kFdDevNull:
case kFdDevRandom:
return sys_write_nt(fd, iov, iovlen, -1);
case kFdSocket:
return _weaken(sys_send_nt)(fd, iov, iovlen, 0);

View file

@ -5,6 +5,7 @@ COSMOPOLITAN_C_START_
errno_t cosmo_once(_Atomic(uint32_t) *, void (*)(void));
int systemvpe(const char *, char *const[], char *const[]) libcesque;
char *GetProgramExecutableName(void);
void unleaf(void);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_COSMO_H_ */

View file

@ -0,0 +1,92 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/runtime/fenv.h"
/**
* Disables floating point exception trapping, e.g.
*
* feenableexcept(FE_INVALID | FE_DIVBYZERO |
* FE_OVERFLOW | FE_UNDERFLOW);
*
* When trapping is enabled, something should handle SIGFPE. Calling
* ShowCrashReports() at startup will install a generic handler with
* backtraces and the symbol of the `si->si_code` which UNIX defines
*
* - `FPE_INTOVF`: integer overflow
* - `FPE_INTDIV`: integer divide by zero
* - `FPE_FLTDIV`: floating point divide by zero
* - `FPE_FLTOVF`: floating point overflow
* - `FPE_FLTUND`: floating point underflow
* - `FPE_FLTRES`: floating point inexact
* - `FPE_FLTINV`: invalid floating point operation
* - `FPE_FLTSUB`: subscript out of range
*
* It's important to not use the `-ffast-math` or `-Ofast` flags when
* compiling code that needs to be debugged. Using `-fsignaling-nans`
* will also help, since GCC doesn't enable that by default.
*
* @param excepts may bitwise-or the following:
* - `FE_INVALID`
* - `FE_DIVBYZERO`
* - `FE_OVERFLOW`
* - `FE_UNDERFLOW`
* - `FE_INEXACT`
* - `FE_ALL_EXCEPT` (all of the above)
* @see fetestexcept() if you don't want to deal with signals
* @see feenableexcept() to turn it on in the first place
*/
int fedisableexcept(int excepts) {
// limit to what we know
excepts &= FE_ALL_EXCEPT;
#ifdef __x86_64__
#ifndef NOX87
// configure 8087 fpu control word
// setting the bits enables suppression
unsigned short x87cw;
asm("fstcw\t%0" : "=m"(x87cw));
x87cw |= excepts;
asm("fldcw\t%0" : /* no inputs */ : "m"(x87cw));
#endif
// configure modern sse control word
// setting the bits enables suppression
unsigned mxcsr;
asm("stmxcsr\t%0" : "=m"(mxcsr));
mxcsr |= excepts << 7;
asm("ldmxcsr\t%0" : /* no inputs */ : "m"(mxcsr));
return 0;
#elif defined(__aarch64__)
unsigned fpcr;
unsigned fpcr2;
fpcr = __builtin_aarch64_get_fpcr();
fpcr2 = fpcr & ~(excepts << 8);
if (fpcr != fpcr2)
__builtin_aarch64_set_fpcr(fpcr2);
return (fpcr >> 8) & FE_ALL_EXCEPT;
#else
return -1;
#endif
}

View file

@ -0,0 +1,98 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/runtime/fenv.h"
/**
* Enables floating point exception trapping, e.g.
*
* feenableexcept(FE_INVALID | FE_DIVBYZERO |
* FE_OVERFLOW | FE_UNDERFLOW);
*
* When trapping is enabled, something should handle SIGFPE. Calling
* ShowCrashReports() at startup will install a generic handler with
* backtraces and the symbol of the `si->si_code` which UNIX defines
*
* - `FPE_INTOVF`: integer overflow
* - `FPE_INTDIV`: integer divide by zero
* - `FPE_FLTDIV`: floating point divide by zero
* - `FPE_FLTOVF`: floating point overflow
* - `FPE_FLTUND`: floating point underflow
* - `FPE_FLTRES`: floating point inexact
* - `FPE_FLTINV`: invalid floating point operation
* - `FPE_FLTSUB`: subscript out of range
*
* It's important to not use the `-ffast-math` or `-Ofast` flags when
* compiling code that needs to be debugged. Using `-fsignaling-nans`
* will also help, since GCC doesn't enable that by default.
*
* @param excepts may bitwise-or the following:
* - `FE_INVALID`
* - `FE_DIVBYZERO`
* - `FE_OVERFLOW`
* - `FE_UNDERFLOW`
* - `FE_INEXACT`
* - `FE_ALL_EXCEPT` (all of the above)
* @see fetestexcept() if you don't want to deal with signals
* @see fedisableexcept() to turn it back off again
*/
int feenableexcept(int excepts) {
// limit to what we know
excepts &= FE_ALL_EXCEPT;
#ifdef __x86_64__
#ifndef NOX87
// configure 8087 fpu control word
// celaring the bits disables suppression
unsigned short x87cw;
asm("fstcw\t%0" : "=m"(x87cw));
x87cw &= ~excepts;
asm("fldcw\t%0" : /* no inputs */ : "m"(x87cw));
#endif
// configure modern sse control word
// clearing the bits disables suppression
unsigned mxcsr;
asm("stmxcsr\t%0" : "=m"(mxcsr));
mxcsr &= ~(excepts << 7);
asm("ldmxcsr\t%0" : /* no inputs */ : "m"(mxcsr));
return 0;
#elif defined(__aarch64__)
unsigned fpcr;
unsigned fpcr2;
unsigned updated_fpcr;
fpcr = __builtin_aarch64_get_fpcr();
fpcr2 = fpcr | (excepts << 8);
if (fpcr != fpcr2) {
__builtin_aarch64_set_fpcr(fpcr2);
// floating point exception trapping is optional in aarch64
updated_fpcr = __builtin_aarch64_get_fpsr();
if (fpcr2 & ~updated_fpcr)
return -1;
}
return (fpcr >> 8) & FE_ALL_EXCEPT;
#else
return -1;
#endif
}

View file

@ -48,6 +48,7 @@ textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
ctx->uc_mcontext.fs = cr->SegFs;
ctx->uc_mcontext.fpregs = &ctx->__fpustate;
__repmovsb(&ctx->__fpustate, &cr->FltSave, sizeof(ctx->__fpustate));
ctx->__fpustate.mxcsr = cr->MxCsr;
}
textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
@ -74,6 +75,7 @@ textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
cr->SegCs = ctx->uc_mcontext.cs;
cr->SegGs = ctx->uc_mcontext.gs;
cr->SegFs = ctx->uc_mcontext.fs;
cr->MxCsr = ctx->__fpustate.mxcsr;
__repmovsb(&cr->FltSave, &ctx->__fpustate, sizeof(ctx->__fpustate));
}

32
libc/intrin/unleaf.c Normal file
View file

@ -0,0 +1,32 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/cosmo.h"
/**
* Does nothing.
*
* Calling this function will force the compiler to generate a stack
* frame. This ensures backtraces will work better in a few critical
* routines.
*/
void unleaf(void) {
// TODO: We should make ShowCrashReports() so __math_invalidf()
// doesn't have to call this in order for the actual math
// function to show up in the backtrace.
}

View file

@ -254,10 +254,28 @@ static relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
kprintf("\n");
}
static inline void SpinLock(atomic_uint *lock) {
int x;
for (;;) {
x = atomic_exchange_explicit(lock, 1, memory_order_acquire);
if (!x)
break;
}
}
static inline void SpinUnlock(atomic_uint *lock) {
atomic_store_explicit(lock, 0, memory_order_release);
}
relegated void __oncrash(int sig, struct siginfo *si, void *arg) {
static atomic_uint lock;
BLOCK_CANCELATION;
SpinLock(&lock);
int err = errno;
__restore_tty();
ShowCrashReport(err, sig, si, arg);
SpinUnlock(&lock);
ALLOW_CANCELATION;
}
#endif /* __x86_64__ */

View file

@ -18,6 +18,7 @@
*/
#include "ape/sections.internal.h"
#include "libc/assert.h"
#include "libc/atomic.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/aarch64.internal.h"
@ -32,6 +33,7 @@
#include "libc/calls/ucontext.h"
#include "libc/cxxabi.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/describebacktrace.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
@ -377,10 +379,25 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
klog(b->p, MIN(b->i, b->n));
}
static inline void SpinLock(atomic_uint *lock) {
int x;
for (;;) {
x = atomic_exchange_explicit(lock, 1, memory_order_acquire);
if (!x)
break;
}
}
static inline void SpinUnlock(atomic_uint *lock) {
atomic_store_explicit(lock, 0, memory_order_release);
}
relegated void __oncrash(int sig, struct siginfo *si, void *arg) {
ucontext_t *ctx = arg;
static atomic_uint lock;
BLOCK_CANCELATION;
__oncrash_impl(sig, si, ctx);
SpinLock(&lock);
__oncrash_impl(sig, si, arg);
SpinUnlock(&lock);
ALLOW_CANCELATION;
}

View file

@ -75,6 +75,19 @@ cosmo: push %rbp
#ifdef __FAST_MATH__
push %rax
stmxcsr (%rsp)
//
// Enable hardware optimizations in violation of the IEEE standard.
//
// - 0x0040 enables "DAZ: Denormals Are Zeros" in MXCSR. This causes the
// processor to turn denormal inputs into zero, before computing them.
// See Intel Manual Vol. 1 §10.2.3.4
//
// - 0x8000 enables "FTZ: Flush To Zero" in MXCSR. This means a floating
// point operation that results in underflow will be set to zero, with
// the same sign, rather than producing a denormalized output. It will
// happen only if underflow trapping hasnt been enabled. See the Intel
// Manual Vol. 1 §10.2.3.3.
//
orl $0x8040,(%rsp)
ldmxcsr (%rsp)
pop %rax

View file

@ -81,6 +81,8 @@ int fesetenv(const fenv_t *);
int fesetexceptflag(const fexcept_t *, int);
int fesetround(int);
int fetestexcept(int);
int feenableexcept(int);
int fedisableexcept(int);
int feupdateenv(const fenv_t *);
int __flt_rounds(void);
int __fesetround(int);

View file

@ -74,9 +74,9 @@ char *GetInterpreterExecutableName(char *p, size_t n) {
cmd[2] = 12; // KERN_PROC_PATHNAME
} else { //
cmd[2] = 5; // KERN_PROC_PATHNAME
} //
cmd[3] = -1; // current process
if (sys_sysctl(cmd, ARRAYLEN(cmd), p, &n, 0, 0) != -1) {
} //
cmd[3] = -1; // current process
if (sysctl(cmd, ARRAYLEN(cmd), p, &n, 0, 0) != -1) {
errno = e;
return p;
}

View file

@ -23,7 +23,7 @@ long __get_sysctl(int x, int y) {
int value;
int mib[2] = {x, y};
size_t len = sizeof(value);
if (sys_sysctl(mib, 2, &value, &len, 0, 0) != -1) {
if (sysctl(mib, 2, &value, &len, 0, 0) != -1) {
return value;
} else {
return -1;

View file

@ -12,7 +12,7 @@ COSMOPOLITAN_C_START_
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
#define SYSLIB_VERSION 9 /* sync with ape/ape-m1.c */
#define SYSLIB_VERSION 10 /* sync with ape/ape-m1.c */
/* if this number increases, then everyone on macos arm will need to
reinstall ape loader in order to run newer ape binaries so please
@ -82,6 +82,9 @@ struct Syslib {
char *(*__dlerror)(void);
/* v9 (2024-01-31) */
int (*__pthread_cpu_number_np)(size_t *);
long (*__sysctl)(int *, unsigned, void *, size_t *, void *, size_t);
long (*__sysctlbyname)(const char *, void *, size_t *, void *, size_t);
long (*__sysctlnametomib)(const char *, int *, size_t *);
};
extern struct Syslib *__syslib;

View file

@ -70,6 +70,9 @@ ssize_t recvfrom(int fd, void *buf, size_t size, int flags,
if (__isfdkind(fd, kFdSocket)) {
rc = sys_recvfrom_nt(fd, (struct iovec[]){{buf, size}}, 1, flags, &addr,
&addrsize);
if (rc != -1 && addrsize == sizeof(addr)) {
addrsize = 0;
}
} else if (__isfdkind(fd, kFdFile) && !opt_out_srcaddr) { /* socketpair */
if (!flags) {
rc = sys_read_nt(fd, (struct iovec[]){{buf, size}}, 1, -1);
@ -84,10 +87,14 @@ ssize_t recvfrom(int fd, void *buf, size_t size, int flags,
}
if (rc != -1) {
if (IsBsd()) {
__convert_bsd_to_sockaddr(&addr);
if (addrsize) {
if (IsBsd()) {
__convert_bsd_to_sockaddr(&addr);
}
__write_sockaddr(&addr, opt_out_srcaddr, opt_inout_srcaddrsize);
} else {
*opt_inout_srcaddrsize = 0;
}
__write_sockaddr(&addr, opt_out_srcaddr, opt_inout_srcaddrsize);
}
END_CANCELATION_POINT;

View file

@ -57,11 +57,7 @@ char *fgets_unlocked(char *s, int size, FILE *f) {
break;
} else {
if ((c = fgetc_unlocked(f)) == -1) {
if (ferror_unlocked(f) == EINTR) {
continue;
} else {
break;
}
break;
}
*p++ = c & 255;
if (c == '\n')

View file

@ -26,8 +26,8 @@ static const char kUtf8Dispatch[] = {
1, 1, 1, 1, 1, 1, 1, 1, // 0320
1, 1, 1, 1, 1, 1, 1, 1, // 0330
2, 3, 3, 3, 3, 3, 3, 3, // 0340 utf8-3
3, 3, 3, 3, 3, 3, 3, 3, // 0350
4, 5, 5, 5, 5, 0, 0, 0, // 0360 utf8-4
3, 3, 3, 3, 3, 4, 3, 3, // 0350
5, 6, 6, 6, 7, 0, 0, 0, // 0360 utf8-4
0, 0, 0, 0, 0, 0, 0, 0, // 0370
};
@ -95,6 +95,7 @@ bool32 isutf8(const void *data, size_t size) {
}
// fallthrough
case 3:
case_utf8_3:
if (p + 2 <= e && //
(p[0] & 0300) == 0200 && //
(p[1] & 0300) == 0200) { //
@ -104,11 +105,17 @@ bool32 isutf8(const void *data, size_t size) {
return false; // missing cont
}
case 4:
if (p < e && (*p & 040)) {
return false; // utf-16 surrogate
}
goto case_utf8_3;
case 5:
if (p < e && (*p & 0377) < 0220) {
return false; // overlong
}
// fallthrough
case 5:
case 6:
case_utf8_4:
if (p + 3 <= e && //
(((uint32_t)(p[+2] & 0377) << 030 | //
(uint32_t)(p[+1] & 0377) << 020 | //
@ -120,6 +127,11 @@ bool32 isutf8(const void *data, size_t size) {
} else {
return false; // missing cont
}
case 7:
if (p < e && (*p & 0x3F) > 0xF) {
return false; // over limit
}
goto case_utf8_4;
default:
__builtin_unreachable();
}

View file

@ -2,6 +2,12 @@
#define COSMOPOLITAN_LIBC_THREAD_THREADS_H_
COSMOPOLITAN_C_START_
#if !defined(__cplusplus) && \
(!(defined(__GNUC__) && __GNUC__ >= 13) || \
!(defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L))
#define thread_local _Thread_local
#endif
#define TSS_DTOR_ITERATIONS 4
enum {

View file

@ -26,6 +26,7 @@
*/
#include "libc/errno.h"
#include "libc/cosmo.h"
#include "libc/tinymath/arm.internal.h"
#if WANT_ERRNO
@ -45,6 +46,7 @@ with_errnof (float y, int e)
dontinline static float
xflowf (uint32_t sign, float y)
{
unleaf();
y = eval_as_float (opt_barrier_float (sign ? -y : y) * y);
return with_errnof (y, ERANGE);
}
@ -74,6 +76,7 @@ __math_oflowf (uint32_t sign)
float
__math_divzerof (uint32_t sign)
{
unleaf();
float y = opt_barrier_float (sign ? -1.0f : 1.0f) / 0.0f;
return with_errnof (y, ERANGE);
}
@ -81,6 +84,7 @@ __math_divzerof (uint32_t sign)
dontinstrument float
__math_invalidf (float x)
{
unleaf();
float y = (x - x) / (x - x);
return isnan (x) ? y : with_errnof (y, EDOM);
}

View file

@ -20,15 +20,19 @@
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/nt/files.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/o.h"
#include "libc/testlib/testlib.h"
int pipefd[2];
int stdoutBack;
int allowMask;
void SetUpOnce(void) {
testlib_enable_tmp_setup_teardown();
// qemu-aarch64 defines o_largefile wrong
allowMask = ~(O_LARGEFILE | 0x00008000);
}
void CaptureStdout(void) {
@ -46,8 +50,7 @@ void RestoreStdout(void) {
TEST(specialfile, devNull) {
ASSERT_SYS(0, 3, creat("/dev/null", 0644));
// qemu-aarch64 defines o_largefile wrong
ASSERT_EQ(O_WRONLY, fcntl(3, F_GETFL) & ~(O_LARGEFILE | 0x00008000));
ASSERT_EQ(O_WRONLY, fcntl(3, F_GETFL) & allowMask);
ASSERT_SYS(0, 2, write(3, "hi", 2));
ASSERT_SYS(0, 2, pwrite(3, "hi", 2, 0));
ASSERT_SYS(0, 2, pwrite(3, "hi", 2, 2));
@ -64,12 +67,51 @@ TEST(specialfile, devNull) {
TEST(specialfile, devNullRead) {
char buf[8] = {0};
ASSERT_SYS(0, 3, open("/dev/null", O_RDONLY));
// qemu-aarch64 defines o_largefile wrong
ASSERT_EQ(O_RDONLY, fcntl(3, F_GETFL) & ~(O_LARGEFILE | 0x00008000));
ASSERT_EQ(O_RDONLY, fcntl(3, F_GETFL) & allowMask);
ASSERT_SYS(0, 0, read(3, buf, 8));
ASSERT_SYS(0, 0, close(3));
}
TEST(specialfile, devRandomRead) {
char buf[8] = {0};
ASSERT_SYS(0, 3, open("/dev/random", O_RDONLY));
ASSERT_EQ(O_RDONLY, fcntl(3, F_GETFL) & allowMask);
ASSERT_SYS(0, 8, read(3, buf, 8));
ASSERT_NE(0, memcmp(buf, " ", 8));
ASSERT_SYS(0, 0, close(3));
}
TEST(specialfile, devUrandomRead) {
char buf[8] = {0};
ASSERT_SYS(0, 3, open("/dev/urandom", O_RDONLY));
ASSERT_EQ(O_RDONLY, fcntl(3, F_GETFL) & allowMask);
ASSERT_SYS(0, 8, read(3, buf, 8));
ASSERT_NE(0, memcmp(buf, " ", 8));
ASSERT_SYS(0, 0, close(3));
}
TEST(specialfile, devRandomWrite_fails_on_nt) {
if (!IsWindows()) {
return;
}
char buf[8] = {0};
ASSERT_SYS(0, 3, creat("/dev/random", 0644));
ASSERT_EQ(O_WRONLY, fcntl(3, F_GETFL) & allowMask);
ASSERT_SYS(EPERM, -1, write(3, buf, 8));
ASSERT_SYS(0, 0, close(3));
}
TEST(specialfile, devUrandomWrite_fails_on_nt) {
if (!IsWindows()) {
return;
}
char buf[8] = {0};
ASSERT_SYS(0, 3, creat("/dev/urandom", 0644));
ASSERT_EQ(O_WRONLY, fcntl(3, F_GETFL) & allowMask);
ASSERT_SYS(EPERM, -1, write(3, buf, 8));
ASSERT_SYS(0, 0, close(3));
}
TEST(specialfile, devStdout) {
char buf[8] = {8};
CaptureStdout();

View file

@ -33,9 +33,9 @@
__static_yoink("zipos");
__static_yoink("libc/testlib/hyperion.txt");
__static_yoink("_Cz_inflate");
__static_yoink("_Cz_inflateInit2");
__static_yoink("_Cz_inflateEnd");
__static_yoink("inflate");
__static_yoink("inflateInit2");
__static_yoink("inflateEnd");
void *Worker(void *arg) {
int i, fd;

View file

@ -93,3 +93,44 @@ TEST(recvfrom, test) {
EXPECT_SYS(0, 0, close(client1));
WAIT(exit, 0);
}
// server listens for connections, accepts a connection, and sends data
// client connects to server recieves with recvfrom and verifies addrsize
// is 0 as the sender info isn't available on connection sockets.
TEST(recvfrom, tcp) {
uint32_t addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in server = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(0x7f000001),
};
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&server, sizeof(server)));
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&server, &addrsize));
ASSERT_SYS(0, 0, listen(3, 5));
////////////////////////////////////////////////////////////////////////////////
SPAWN(fork);
struct sockaddr_in data, addr;
uint32_t addrsize = sizeof(struct sockaddr_in);
EXPECT_SYS(0, 0, close(3));
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&server, sizeof(server)));
ASSERT_SYS(
0, sizeof(data),
recvfrom(3, &data, sizeof(data), 0, (struct sockaddr *)&addr, &addrsize));
ASSERT_EQ(0, addrsize);
EXPECT_SYS(0, 0, close(3));
////////////////////////////////////////////////////////////////////////////////
PARENT();
int client;
struct sockaddr client_sockaddr;
uint32_t sockaddr_size = sizeof(client_sockaddr);
ASSERT_NE(-1, (client = accept(3, &client_sockaddr, &sockaddr_size)));
ASSERT_SYS(0, sizeof(client_sockaddr),
sendto(client, &client_sockaddr, sizeof(client_sockaddr), 0,
(struct sockaddr *)&server, sizeof(server)));
EXPECT_SYS(0, 0, close(client));
WAIT(exit, 0);
EXPECT_SYS(0, 0, close(3));
}

View file

@ -0,0 +1,138 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 Cadence Ember
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/isystem/errno.h"
#include "libc/isystem/sched.h"
#include "libc/isystem/signal.h"
#include "libc/isystem/stddef.h"
#include "libc/isystem/unistd.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#define MY_TEST_STRING_1 "He"
#define MY_TEST_STRING_2 "llo world!"
char buf[20] = {0};
int pipes[2];
int pid;
int got_sigusr1 = 0;
// -=- these get called for each test ------------------------------------------
void sigusr1_handler(int) {
got_sigusr1 = 1;
}
void write_pipe(int send_signal_before_end) {
// Set up pipe for writing
close(pipes[0]);
FILE *stream = fdopen(pipes[1], "w");
// Start writing the first part of the stream
fputs(MY_TEST_STRING_1, stream);
// Send SIGUSR1 to parent (if we're currently testing that)
if (send_signal_before_end) {
kill(getppid(), SIGUSR1);
}
// Send rest of stream
fputs(MY_TEST_STRING_2, stream);
// Close stream - this will cause the parent's fgets to end
fclose(stream);
}
void read_pipe() {
// Set up pipe for reading
close(pipes[1]);
FILE *stream = fdopen(pipes[0], "r");
// Read with fgets
fgets(buf, 20, stream);
// Tidy up
fclose(stream);
}
// -=- these set up the tests --------------------------------------------------
void SetUpOnce(void) {
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(1, &set);
if (sched_setaffinity(0, sizeof set, &set) == -1) {
perror("sched_setaffinity");
fprintf(stderr, "single core affinity is needed for test reliability\n");
_exit(1);
}
}
void setup_signal_and_pipe(uint64_t sa_flags) {
// Set up SIGUSR1 handler
struct sigaction sa = {.sa_handler = sigusr1_handler, .sa_flags = sa_flags};
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
perror("sigaction");
_exit(1);
}
got_sigusr1 = 0;
// Set up pipe between parent and child
if (pipe(pipes) == -1) {
perror("pipe");
_exit(1);
}
}
// -=- these are the tests -----------------------------------------------------
TEST(fgets_eintr, testThatFgetsReadsFromPipeNormally) {
setup_signal_and_pipe(0); // 0 = no SA_RESTART
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
write_pipe(0); // 0 = no signal
_exit(0);
}
read_pipe();
EXPECT_STREQ(MY_TEST_STRING_1 MY_TEST_STRING_2, buf);
}
TEST(fgets_eintr, testThatTheSignalInterruptsFgets) {
setup_signal_and_pipe(0); // 0 = no SA_RESTART
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
write_pipe(1); // 1 = signal
_exit(0);
}
read_pipe();
EXPECT_STRNE(MY_TEST_STRING_1 MY_TEST_STRING_2, buf);
EXPECT_EQ(EINTR, errno);
EXPECT_EQ(1, got_sigusr1);
}
TEST(fgets_eintr, testThatFgetsRestartsWhenSaRestartIsSet) {
setup_signal_and_pipe(SA_RESTART); // SA_RESTART
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
write_pipe(1); // 1 = signal
_exit(0);
}
read_pipe();
EXPECT_STREQ(MY_TEST_STRING_1 MY_TEST_STRING_2, buf);
EXPECT_NE(EINTR, errno);
EXPECT_EQ(1, got_sigusr1);
}

View file

@ -39,6 +39,9 @@ TEST(isutf8, good) {
"剑号巨阙 珠称夜光 果珍李柰 菜重芥姜 海咸河淡 鳞潜羽翔"
"龙师火帝 鸟官人皇 始制文字 乃服衣裳 推位让国 有虞陶唐",
-1));
EXPECT_TRUE(isutf8("\xf4\x8f\xbf\xbf", -1));
EXPECT_TRUE(isutf8("\xed\x9f\xbf", -1));
EXPECT_TRUE(isutf8("\xee\x80\x80", -1));
}
TEST(isutf8, bad) {
@ -46,6 +49,9 @@ TEST(isutf8, bad) {
ASSERT_FALSE(isutf8("\200\300", -1)); // latin1 c1 control code
ASSERT_FALSE(isutf8("\300\300", -1)); // missing continuation
ASSERT_FALSE(isutf8("\377\200\200\200\200", -1)); // thompson-pike varint
ASSERT_FALSE(isutf8("\xf4\x90\x80\x80", -1)); // over limit
ASSERT_FALSE(isutf8("\xed\xa0\x80", -1));
ASSERT_FALSE(isutf8("\xed\xbf\xbf", -1)); // surrogate pairs
}
TEST(isutf8, oob) {

View file

@ -16,7 +16,8 @@ TEST_MATH_DIRECTDEPS = \
LIBC_RUNTIME \
LIBC_SYSV \
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_OPENMP
TEST_MATH_DEPS := \
$(call uniq,$(foreach x,$(TEST_MATH_DIRECTDEPS),$($(x))))
@ -33,7 +34,7 @@ o/$(MODE)/test/math/%.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
$(TEST_MATH_OBJS): private CFLAGS += -fno-builtin
$(TEST_MATH_OBJS): private CFLAGS += -fno-builtin -fopenmp
.PHONY: o/$(MODE)/test/math
o/$(MODE)/test/math: \

55
test/math/erff_test.c Normal file
View file

@ -0,0 +1,55 @@
// Copyright 2024 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 <math.h>
#include <stdlib.h>
#define MAX_ERROR_ULP 1
#define GOTTA_TEST_THEM_ALL 0
unsigned rand32(void) {
/* Knuth, D.E., "The Art of Computer Programming," Vol 2,
Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998,
p. 106 (line 26) & p. 108 */
static unsigned long long lcg = 1;
lcg *= 6364136223846793005;
lcg += 1442695040888963407;
return lcg >> 32;
}
int main() {
#if GOTTA_TEST_THEM_ALL
#pragma omp parallel for
for (long i = 0; i < 4294967296; ++i) {
#else
for (long r = 0; r < 100000; ++r) {
unsigned i = rand32();
#endif
union {
float f;
unsigned i;
} x, a, b;
x.i = i;
a.f = erf(x.f);
b.f = erff(x.f);
long ai = a.i;
long bi = b.i;
long e = bi - ai;
if (e < 0)
e = -e;
if (e > MAX_ERROR_ULP)
exit(99);
}
}

87
test/math/expf_test.c Normal file
View file

@ -0,0 +1,87 @@
// Copyright 2024 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 <errno.h>
#include <math.h>
#include <stdlib.h>
#define MAX_ERROR_ULP 1
#define GOTTA_TEST_THEM_ALL 0
float ident(float x) {
return x;
}
float (*veil)(float) = ident;
unsigned rand32(void) {
/* Knuth, D.E., "The Art of Computer Programming," Vol 2,
Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998,
p. 106 (line 26) & p. 108 */
static unsigned long long lcg = 1;
lcg *= 6364136223846793005;
lcg += 1442695040888963407;
return lcg >> 32;
}
int main() {
// specials
if (expf(veil(0.f)) != 1.f)
return 1;
if (!isnan(expf(veil(NAN))))
return 2;
if (expf(veil(-INFINITY)) != 0.f)
return 3;
if (expf(veil(INFINITY)) != INFINITY)
return 4;
if (errno)
return 5;
// overflow
if (expf(veil(88.8)) != HUGE_VALF)
return 6;
if (errno != ERANGE)
return 7;
errno = 0;
// underflow
if (expf(veil(-104)) != 0.)
return 8;
if (errno != ERANGE)
return 9;
#if GOTTA_TEST_THEM_ALL
#pragma omp parallel for
for (long i = 0; i < 4294967296; ++i) {
#else
for (long r = 0; r < 100000; ++r) {
unsigned i = rand32();
#endif
union {
float f;
unsigned i;
} x, a, b;
x.i = i;
a.f = exp(x.f);
b.f = expf(x.f);
long ai = a.i;
long bi = b.i;
long e = bi - ai;
if (e < 0)
e = -e;
if (e > MAX_ERROR_ULP)
exit(99);
}
}

1
third_party/awk/b.c vendored
View file

@ -1463,6 +1463,7 @@ rescan:
}
break;
}
__builtin_unreachable();
}
int cgoto(fa *f, int s, int c)

View file

@ -45,9 +45,9 @@ __static_yoink("musl_libc_notice");
// something as substantive as this library, then we shall assume the
// application is meaty enough to benefit from the performance of the
// chromium zlib library (costs ~40kb binary) versus just having puff
__static_yoink("_Cz_inflateInit2");
__static_yoink("_Cz_inflate");
__static_yoink("_Cz_inflateEnd");
__static_yoink("inflateInit2");
__static_yoink("inflate");
__static_yoink("inflateEnd");
#endif
static char *

View file

@ -31,7 +31,7 @@
#ifndef USE_ZLIB
ZCONST ulg near *get_crc_table OF((void));
#endif
#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY))
#if (1 || defined(USE_ZLIB) || defined(CRC_TABLE_ONLY))
# ifdef IZ_CRC_BE_OPTIMIZ
# undef IZ_CRC_BE_OPTIMIZ
# endif

View file

@ -72,7 +72,7 @@
#include "libc/nt/winsock.h"
#endif
unsigned _Cz_crc32(unsigned crc, const unsigned char *buf, unsigned len);
unsigned crc32(unsigned crc, const unsigned char *buf, unsigned len);
/*
* XXX start of zipfile.h
@ -867,7 +867,7 @@ local void read_Unicode_Path_entry(pZipListEntry)
}
strcpy(iname, pZipListEntry->iname);
chksum = _Cz_crc32(chksum, (uch *)(iname), strlen(iname));
chksum = crc32(chksum, (uch *)(iname), strlen(iname));
free(iname);
@ -972,7 +972,7 @@ local void read_Unicode_Path_local_entry(pZipListEntry)
}
strcpy(iname, pZipListEntry->iname);
chksum = _Cz_crc32(chksum, (uch *)(iname), strlen(iname));
chksum = crc32(chksum, (uch *)(iname), strlen(iname));
free(iname);
@ -1558,7 +1558,7 @@ local int add_Unicode_Path_local_extra_field(pZEntry)
# define inameLocal (pZEntry->iname)
#endif
chksum = _Cz_crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
chksum = crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
#ifdef WIN32_OEM
free(inameLocal);
@ -1685,7 +1685,7 @@ local int add_Unicode_Path_cen_extra_field(pZEntry)
# define inameLocal (pZEntry->iname)
#endif
chksum = _Cz_crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
chksum = crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
#ifdef WIN32_OEM
free(inameLocal);

View file

@ -13,6 +13,7 @@
#define z_const const
#if 0
#define Z_COSMO_PREFIX_SET
#define Bytef _Cz_Bytef
@ -162,6 +163,9 @@
#define zlibCompileFlags _Cz_zlibCompileFlags
#define zlibVersion _Cz_zlibVersion
#pragma message "zconf is included, so zlibVersion should be renamed"
#endif
typedef unsigned char Byte;
typedef unsigned int uInt; /* 16 bits or more */

View file

@ -215,7 +215,7 @@
(runs (format "o/$m/%s%s V=5 TESTARGS=-b" name runsuffix))
(buns (format "o/$m/test/%s_test%s V=5 TESTARGS=-b" name runsuffix)))
(cond ((not (member ext '("c" "cc" "cpp" "s" "S" "rl" "f" "cu")))
(format "m=%s; make -j32 MODE=$m o/$m/%s"
(format "m=%s; make -j96 MODE=$m o/$m/%s"
mode
(directory-file-name
(or (file-name-directory
@ -226,7 +226,7 @@
(cosmo-join
" && "
`("m=%s; f=o/$m/%s"
,(concat "make -j32 $f MODE=$m")
,(concat "make -j96 $f MODE=$m")
"scp $f $f.dbg win10:; ssh win10 ./%s"))
mode name (file-name-nondirectory name)))
((eq kind 'run-xnu)
@ -234,19 +234,19 @@
(cosmo-join
" && "
`("m=%s; f=o/$m/%s"
,(concat "make -j32 $f MODE=$m")
,(concat "make -j96 $f MODE=$m")
"scp $f $f.dbg xnu:"
"ssh xnu ./%s"))
mode name (file-name-nondirectory name)))
((and (equal suffix "")
(cosmo-contains "_test." (buffer-file-name)))
(format "m=%s; make -j32 MODE=$m %s"
(format "m=%s; make -j96 MODE=$m %s"
mode runs))
((and (equal suffix "")
(file-exists-p (format "%s" buddy)))
(format (cosmo-join
" && "
'("m=%s; n=%s; make -j32 o/$m/$n%s.o MODE=$m"
'("m=%s; n=%s; make -j96 o/$m/$n%s.o MODE=$m"
;; "bloat o/$m/%s.o | head"
;; "nm -C --size o/$m/%s.o | sort -r"
"echo"
@ -258,11 +258,11 @@
(cosmo-join
" && "
`("m=%s; f=o/$m/%s"
,(concat "make -j32 $f MODE=$m")
,(concat "make -j96 $f MODE=$m")
"build/run ./$f"))
mode name))
((eq kind 'test)
(format `"m=%s; f=o/$m/%s.ok && make -j32 $f MODE=$m" mode name))
(format `"m=%s; f=o/$m/%s.ok && make -j96 $f MODE=$m" mode name))
((and (file-regular-p this)
(file-executable-p this))
(format "build/run ./%s" file))
@ -271,7 +271,7 @@
(cosmo-join
" && "
`("m=%s; f=o/$m/%s%s.o"
,(concat "make -j32 $f MODE=$m")
,(concat "make -j96 $f MODE=$m")
;; "nm -C --size $f | sort -r"
"echo"
"size -A $f | grep '^[.T]' | grep -v 'debug\\|command.line\\|stack' | sort -rnk2"
@ -481,7 +481,7 @@
(error "don't know how to show assembly for non c/c++ source file"))
(let* ((default-directory root)
(compile-command
(format "make %s -j32 MODE=%s %s %s"
(format "make %s -j96 MODE=%s %s %s"
(or extra-make-flags "") mode asm-gcc asm-clang)))
(save-buffer)
(set-visited-file-modtime (current-time))
@ -641,11 +641,11 @@
(compile (format "sh -c %s" file)))
((eq major-mode 'lua-mode)
(let* ((mode (cosmo--make-mode arg)))
(compile (format "make -j32 MODE=%s o/%s/tool/net/redbean && build/run o/%s/tool/net/redbean -i %s" mode mode mode file))))
(compile (format "make -j96 MODE=%s o/%s/tool/net/redbean && build/run o/%s/tool/net/redbean -i %s" mode mode mode file))))
((and (eq major-mode 'python-mode)
(cosmo-startswith "third_party/python/Lib/test/" file))
(let ((mode (cosmo--make-mode arg)))
(compile (format "make -j32 MODE=%s PYHARNESSARGS=-vv PYTESTARGS=-v o/%s/%s.py.runs"
(compile (format "make -j96 MODE=%s PYHARNESSARGS=-vv PYTESTARGS=-v o/%s/%s.py.runs"
mode mode (file-name-sans-extension file)))))
((eq major-mode 'python-mode)
(compile (format "python %s" file)))

View file

@ -1612,7 +1612,7 @@ FUNCTIONS
called from `.init.lua`. This function is not available in
unsecure mode.
ProgramSslRequired(mandatory:str)
ProgramSslRequired(mandatory:bool)
Enables the blocking of HTTP so that all inbound clients and
must use the TLS transport layer. This has the same effect as
the `-J` flag. Fetch() is still allowed to make outbound HTTP