diff --git a/ape/loader.c b/ape/loader.c index 40e6f8d04..ffbdb3838 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -438,16 +438,6 @@ static long Write(int fd, const void *data, unsigned long size, int os) { return CallSystem(fd, (long)data, size, 0, 0, 0, 0, numba, os); } -static int Execve(const char *prog, char **argv, char **envp, int os) { - int numba; - if (IsLinux() && IsAarch64()) { - numba = 221; - } else { - numba = 59; - } - return CallSystem((long)prog, (long)argv, (long)envp, 0, 0, 0, 0, numba, os); -} - static int Access(const char *path, int mode, int os) { if (IsLinux() && IsAarch64()) { return SystemCall(-100, (long)path, mode, 0, 0, 0, 0, 48); diff --git a/build/bootstrap/ar.com b/build/bootstrap/ar.com index d57a4284f..f5bfc395b 100755 Binary files a/build/bootstrap/ar.com and b/build/bootstrap/ar.com differ diff --git a/build/bootstrap/chmod.com b/build/bootstrap/chmod.com index c3440427a..1a843b830 100755 Binary files a/build/bootstrap/chmod.com and b/build/bootstrap/chmod.com differ diff --git a/build/bootstrap/cocmd.com b/build/bootstrap/cocmd.com index d3846b120..d61b3d12b 100755 Binary files a/build/bootstrap/cocmd.com and b/build/bootstrap/cocmd.com differ diff --git a/build/bootstrap/compile.com b/build/bootstrap/compile.com index 438b1af83..42c95ff8c 100755 Binary files a/build/bootstrap/compile.com and b/build/bootstrap/compile.com differ diff --git a/build/bootstrap/cp.com b/build/bootstrap/cp.com index 76ec9989b..dc2c6f8d9 100755 Binary files a/build/bootstrap/cp.com and b/build/bootstrap/cp.com differ diff --git a/build/bootstrap/echo.com b/build/bootstrap/echo.com index db7ea23aa..822575ee5 100755 Binary files a/build/bootstrap/echo.com and b/build/bootstrap/echo.com differ diff --git a/build/bootstrap/fixupobj.com b/build/bootstrap/fixupobj.com index afa014021..fdf9f2719 100755 Binary files a/build/bootstrap/fixupobj.com and b/build/bootstrap/fixupobj.com differ diff --git a/build/bootstrap/gzip.com b/build/bootstrap/gzip.com index 84fae4ba5..667d7369b 100755 Binary files a/build/bootstrap/gzip.com and b/build/bootstrap/gzip.com differ diff --git a/build/bootstrap/make.com b/build/bootstrap/make.com index bae36587e..c9c8beb6c 100755 Binary files a/build/bootstrap/make.com and b/build/bootstrap/make.com differ diff --git a/build/bootstrap/mkdeps.com b/build/bootstrap/mkdeps.com index a8e969f1a..7fc162ae7 100755 Binary files a/build/bootstrap/mkdeps.com and b/build/bootstrap/mkdeps.com differ diff --git a/build/bootstrap/mkdir.com b/build/bootstrap/mkdir.com index e71d0e503..f972be18c 100755 Binary files a/build/bootstrap/mkdir.com and b/build/bootstrap/mkdir.com differ diff --git a/build/bootstrap/package.com b/build/bootstrap/package.com index c404b3b2e..b2cb8f00a 100755 Binary files a/build/bootstrap/package.com and b/build/bootstrap/package.com differ diff --git a/build/bootstrap/pwd.com b/build/bootstrap/pwd.com index 603df4de9..e0dd91a20 100755 Binary files a/build/bootstrap/pwd.com and b/build/bootstrap/pwd.com differ diff --git a/build/bootstrap/rm.com b/build/bootstrap/rm.com index c1a311f3f..7d4b51a4a 100755 Binary files a/build/bootstrap/rm.com and b/build/bootstrap/rm.com differ diff --git a/build/bootstrap/touch.com b/build/bootstrap/touch.com index aaa95f8df..724bc2ae7 100755 Binary files a/build/bootstrap/touch.com and b/build/bootstrap/touch.com differ diff --git a/build/bootstrap/unbundle.com b/build/bootstrap/unbundle.com index 25cd06475..0cb05dc6e 100755 Binary files a/build/bootstrap/unbundle.com and b/build/bootstrap/unbundle.com differ diff --git a/build/bootstrap/zipobj.com b/build/bootstrap/zipobj.com index 12611fdae..26128d2a7 100755 Binary files a/build/bootstrap/zipobj.com and b/build/bootstrap/zipobj.com differ diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index 7762dd908..8bcb44b9c 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -134,12 +134,6 @@ o/$(MODE)/libc/calls/mkntenvblock.o: private \ CPPFLAGS += \ -DSTACK_FRAME_UNLIMITED -# we must segregate codegen because: -# file contains multiple independently linkable apis - COPTS += \ - -ffunction-sections \ - -fdata-sections - # we always want -Os because: # va_arg codegen is very bloated in default mode o//libc/calls/open.o \ diff --git a/libc/calls/clock_gettime-mono.c b/libc/calls/clock_gettime-mono.c index 072bae513..308a4f503 100644 --- a/libc/calls/clock_gettime-mono.c +++ b/libc/calls/clock_gettime-mono.c @@ -17,14 +17,14 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/struct/timespec.h" +#include "libc/cosmo.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/nexgen32e/x86feature.h" #include "libc/sysv/consts/clock.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" static struct { - pthread_once_t once; + _Atomic(uint32_t) once; struct timespec base_wall; uint64_t base_tick; } g_mono; @@ -39,7 +39,7 @@ int sys_clock_gettime_mono(struct timespec *time) { uint64_t cycles; struct timespec res; if (X86_HAVE(INVTSC)) { - pthread_once(&g_mono.once, sys_clock_gettime_mono_init); + cosmo_once(&g_mono.once, sys_clock_gettime_mono_init); cycles = rdtsc() - g_mono.base_tick; nanos = cycles / 3; *time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos)); diff --git a/libc/calls/copy_file_range.c b/libc/calls/copy_file_range.c index cf20058e2..4962a6bc8 100644 --- a/libc/calls/copy_file_range.c +++ b/libc/calls/copy_file_range.c @@ -23,6 +23,7 @@ #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asan.internal.h" @@ -30,10 +31,9 @@ #include "libc/intrin/strace.internal.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" static struct CopyFileRange { - pthread_once_t once; + _Atomic(uint32_t) once; bool ok; } g_copy_file_range; @@ -104,7 +104,7 @@ ssize_t copy_file_range(int infd, int64_t *opt_in_out_inoffset, int outfd, int64_t *opt_in_out_outoffset, size_t uptobytes, uint32_t flags) { ssize_t rc; - pthread_once(&g_copy_file_range.once, copy_file_range_init); + cosmo_once(&g_copy_file_range.once, copy_file_range_init); BEGIN_CANCELLATION_POINT; if (!g_copy_file_range.ok) { diff --git a/libc/calls/dup.c b/libc/calls/dup.c index c56f4c9b2..7ef655a48 100644 --- a/libc/calls/dup.c +++ b/libc/calls/dup.c @@ -30,6 +30,17 @@ * The `O_CLOEXEC` flag shall be cleared from the resulting file * descriptor; see dup3() to preserve it. * + * One use case for duplicating file descriptors is to be able to + * reassign an open()'d file or pipe() to the stdio of an executed + * subprocess. On Windows, in order for this to work, the subprocess + * needs to be a Cosmopolitan program that has socket() linked. + * + * Only small programs should duplicate sockets. That's because this + * implementation uses DuplicateHandle() on Windows, which Microsoft + * says might cause its resources to leak internally. Thus it likely + * isn't a good idea to design a server that does it a lot and lives + * a long time, without contributing a patch to this implementation. + * * @param fd remains open afterwards * @return some arbitrary new number for fd * @raise EPERM if pledge() is in play without stdio diff --git a/libc/calls/dup2.c b/libc/calls/dup2.c index 71cad1934..36817bcde 100644 --- a/libc/calls/dup2.c +++ b/libc/calls/dup2.c @@ -27,13 +27,24 @@ /** * Duplicates file descriptor, granting it specific number. * - * The `O_CLOEXEC` flag shall be cleared from the resulting file - * descriptor; see dup3() to preserve it. - * * Unlike dup3(), the dup2() function permits oldfd and newfd to be the * same, in which case the only thing this function does is test if * oldfd is open. * + * The `O_CLOEXEC` flag shall be cleared from the resulting file + * descriptor; see dup3() to preserve it. + * + * One use case for duplicating file descriptors is to be able to + * reassign an open()'d file or pipe() to the stdio of an executed + * subprocess. On Windows, in order for this to work, the subprocess + * needs to be a Cosmopolitan program that has socket() linked. + * + * Only small programs should duplicate sockets. That's because this + * implementation uses DuplicateHandle() on Windows, which Microsoft + * says might cause its resources to leak internally. Thus it likely + * isn't a good idea to design a server that does it a lot and lives + * a long time, without contributing a patch to this implementation. + * * @param oldfd isn't closed afterwards * @param newfd if already assigned, is silently closed beforehand; * unless it's equal to oldfd, in which case dup2() is a no-op diff --git a/libc/calls/dup3-sysv.c b/libc/calls/dup3-sysv.c index 4cb873e83..1830c3d36 100644 --- a/libc/calls/dup3-sysv.c +++ b/libc/calls/dup3-sysv.c @@ -19,18 +19,18 @@ #include "libc/assert.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/strace.internal.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" #define F_DUP2FD 10 #define F_DUP2FD_CLOEXEC 18 static struct Dup3 { - pthread_once_t once; + _Atomic(uint32_t) once; bool demodernize; } g_dup3; @@ -58,7 +58,7 @@ int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) { return __sys_fcntl(oldfd, how, newfd); } - pthread_once(&g_dup3.once, sys_dup3_test); + cosmo_once(&g_dup3.once, sys_dup3_test); if (!g_dup3.demodernize) { return __sys_dup3(oldfd, newfd, flags); diff --git a/libc/calls/dup3.c b/libc/calls/dup3.c index a4d9413e0..05d29de37 100644 --- a/libc/calls/dup3.c +++ b/libc/calls/dup3.c @@ -28,9 +28,19 @@ /** * Duplicates file descriptor/handle. * - * On Windows, we can't guarantee the desired file descriptor is used. - * We can however remap the standard handles (non-atomically) if their - * symbolic names are used. + * The `O_CLOEXEC` flag shall be cleared from the resulting file + * descriptor; see dup3() to preserve it. + * + * One use case for duplicating file descriptors is to be able to + * reassign an open()'d file or pipe() to the stdio of an executed + * subprocess. On Windows, in order for this to work, the subprocess + * needs to be a Cosmopolitan program that has socket() linked. + * + * Only small programs should duplicate sockets. That's because this + * implementation uses DuplicateHandle() on Windows, which Microsoft + * says might cause its resources to leak internally. Thus it likely + * isn't a good idea to design a server that does it a lot and lives + * a long time, without contributing a patch to this implementation. * * @param oldfd isn't closed afterwards * @param newfd if already assigned, is silently closed beforehand; diff --git a/libc/calls/execlp.c b/libc/calls/execlp.c index 962f20f46..66f5f6e59 100644 --- a/libc/calls/execlp.c +++ b/libc/calls/execlp.c @@ -42,11 +42,6 @@ int execlp(const char *prog, const char *arg, ... /*, NULL*/) { va_list va, vb; char pathbuf[PATH_MAX]; - // resolve path of executable - if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) { - return -1; - } - // turn varargs into array va_copy(vb, va); va_start(va, arg); @@ -60,6 +55,15 @@ int execlp(const char *prog, const char *arg, ... /*, NULL*/) { } va_end(vb); + if (strchr(prog, '/')) { + return execv(prog, argv); + } + + // resolve path of executable + if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) { + return -1; + } + // change argv[0] to resolved path if it's ambiguous // otherwise the program won't have much luck finding itself if (argv[0] && *prog != '/' && *exe == '/' && !strcmp(prog, argv[0])) { diff --git a/libc/calls/execve-nt.greg.c b/libc/calls/execve-nt.greg.c index 1277c4891..90632b925 100644 --- a/libc/calls/execve-nt.greg.c +++ b/libc/calls/execve-nt.greg.c @@ -21,7 +21,9 @@ #include "libc/calls/internal.h" #include "libc/calls/ntspawn.h" #include "libc/calls/syscall-nt.internal.h" +#include "libc/fmt/itoa.h" #include "libc/intrin/strace.internal.h" +#include "libc/intrin/weaken.h" #include "libc/mem/alloca.h" #include "libc/nt/accounting.h" #include "libc/nt/console.h" @@ -35,6 +37,7 @@ #include "libc/nt/thunk/msabi.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" #include "libc/str/str.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/consts/map.h" @@ -84,22 +87,36 @@ textwindows int sys_execve_nt(const char *program, char *const argv[], ////////////////////////////////////////////////////////////////////////////// // execve operation is unrecoverable from this point - // close cloexec handles - for (i = 3; i < g_fds.n; ++i) { - if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) { + // close non-stdio and cloexec handles + for (i = 0; i < g_fds.n; ++i) { + if (g_fds.p[i].kind == kFdEmpty) { + g_fds.p[i].handle = -1; + } else if (i > 2 || (g_fds.p[i].flags & O_CLOEXEC)) { __imp_CloseHandle(g_fds.p[i].handle); + g_fds.p[i].handle = -1; } } + int bits; + char buf[32], *v = 0; + if (_weaken(socket)) { + for (bits = i = 0; i < 3; ++i) { + if (g_fds.p[i].kind == kFdSocket) { + bits |= 1 << i; + } + } + FormatInt32(stpcpy(buf, "__STDIO_SOCKETS="), bits); + v = buf; + } bzero(&startinfo, sizeof(startinfo)); startinfo.cb = sizeof(struct NtStartupInfo); startinfo.dwFlags = kNtStartfUsestdhandles; - startinfo.hStdInput = __getfdhandleactual(0); - startinfo.hStdOutput = __getfdhandleactual(1); - startinfo.hStdError = __getfdhandleactual(2); + startinfo.hStdInput = g_fds.p[0].handle; + startinfo.hStdOutput = g_fds.p[1].handle; + startinfo.hStdError = g_fds.p[2].handle; // spawn the process - rc = ntspawn(program, argv, envp, 0, 0, 0, true, 0, 0, &startinfo, &procinfo); + rc = ntspawn(program, argv, envp, v, 0, 0, true, 0, 0, &startinfo, &procinfo); if (rc == -1) { STRACE("panic: unrecoverable ntspawn(%#s) error: %m", program); __imp_ExitProcess(6543); diff --git a/libc/calls/execve.c b/libc/calls/execve.c index a4beeeb85..c3b99d83e 100644 --- a/libc/calls/execve.c +++ b/libc/calls/execve.c @@ -40,6 +40,11 @@ * to be valid UTF-8 in order to round-trip the WIN32 API, without being * corrupted. * + * On Windows, only file descriptors 0, 1 and 2 can be passed to a child + * process in such a way that allows them to be automatically discovered + * when the child process initializes. Cosmpolitan currently treats your + * other file descriptors as implicitly O_CLOEXEC. + * * @param program will not be PATH searched, see commandv() * @param argv[0] is the name of the program to run * @param argv[1,n-2] optionally specify program arguments diff --git a/libc/calls/execvpe.c b/libc/calls/execvpe.c index 891388f2e..80382d405 100644 --- a/libc/calls/execvpe.c +++ b/libc/calls/execvpe.c @@ -27,7 +27,9 @@ /** * Executes program, with path environment search. * - * The current process is replaced with the executed one. + * This function is a wrapper of the execve() system call that does path + * resolution. The `PATH` environment variable is taken from your global + * `environ` rather than the `envp` argument. * * @param prog is the program to launch * @param argv is [file,argv₁..argvₙ₋₁,NULL] @@ -47,6 +49,10 @@ int execvpe(const char *prog, char *const argv[], char *const *envp) { return efault(); } + if (strchr(prog, '/')) { + return execve(prog, argv, envp); + } + // resolve path of executable if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) { return -1; diff --git a/libc/calls/fcntl-nt.c b/libc/calls/fcntl-nt.c index 2004e73bc..0fbed453e 100644 --- a/libc/calls/fcntl-nt.c +++ b/libc/calls/fcntl-nt.c @@ -321,8 +321,9 @@ static textwindows int sys_fcntl_nt_setfl(int fd, unsigned *flags, unsigned arg, // // - O_NONBLOCK make read() raise EAGAIN // - O_NDELAY same thing as O_NONBLOCK + // - O_ACCMODE but has a minimal effect // - allowed = O_NONBLOCK; + allowed = O_ACCMODE | O_NONBLOCK; if (changed & ~allowed) { // the following access mode flags are supported, but it's currently // not possible to change them on windows. diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c index 29ed68a25..c3ed33add 100644 --- a/libc/calls/fstat-nt.c +++ b/libc/calls/fstat-nt.c @@ -102,7 +102,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { st->st_ctim = FileTimeToTimeSpec(wst.ftCreationFileTime); st->st_birthtim = st->st_ctim; st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow; - st->st_blksize = PAGESIZE; + st->st_blksize = 4096; st->st_dev = wst.dwVolumeSerialNumber; st->st_rdev = 0; st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow; @@ -118,7 +118,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { &fci, sizeof(fci))) { actualsize = fci.CompressedFileSize; } - st->st_blocks = ROUNDUP(actualsize, PAGESIZE) / 512; + st->st_blocks = ROUNDUP(actualsize, 4096) / 512; } } else { STRACE("%s failed %m", "GetFileInformationByHandle"); diff --git a/libc/calls/getprogramexecutablename.greg.c b/libc/calls/getprogramexecutablename.greg.c index 764365f7e..71a0663a5 100644 --- a/libc/calls/getprogramexecutablename.greg.c +++ b/libc/calls/getprogramexecutablename.greg.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/metalfile.internal.h" #include "libc/calls/syscall-sysv.internal.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/macros.internal.h" @@ -34,7 +35,10 @@ #define KERN_PROC_PATHNAME_FREEBSD 12 #define KERN_PROC_PATHNAME_NETBSD 5 -char program_executable_name[PATH_MAX]; +static struct ProgramExecutableName { + _Atomic(uint32_t) once; + char buf[PATH_MAX]; +} program_executable_name; static inline int IsAlpha(int c) { return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); @@ -50,7 +54,9 @@ static inline char *StrCat(char buf[PATH_MAX], const char *a, const char *b) { } static inline void GetProgramExecutableNameImpl(char *p, char *e) { + int c; char *q; + char **ep; ssize_t rc; size_t i, n; union { @@ -84,9 +90,9 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) { // if argv[0] exists then turn it into an absolute path. we also try // adding a .com suffix since the ape auto-appends it when resolving - if (__argc && (((q = __argv[0]) && !sys_faccessat(AT_FDCWD, q, F_OK, 0)) || - ((q = StrCat(u.path, __argv[0], ".com")) && - !sys_faccessat(AT_FDCWD, q, F_OK, 0)))) { + if (((q = __argv[0]) && !sys_faccessat(AT_FDCWD, q, F_OK, 0)) || + ((q = StrCat(u.path, __argv[0], ".com")) && + !sys_faccessat(AT_FDCWD, q, F_OK, 0))) { if (*q != '/') { if (q[0] == '.' && q[1] == '/') { q += 2; @@ -103,6 +109,19 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) { return; } + // if getenv("_") exists then use that + for (ep = __envp; (q = *ep); ++ep) { + if (*q++ == '_' && *q++ == '=') { + while ((c = *q++)) { + if (p + 1 < e) { + *p++ = c; + } + } + *p = 0; + return; + } + } + // if argv[0] doesn't exist, then fallback to interpreter name if ((rc = sys_readlinkat(AT_FDCWD, "/proc/self/exe", p, e - p - 1)) > 0 || (rc = sys_readlinkat(AT_FDCWD, "/proc/curproc/file", p, e - p - 1)) > 0) { @@ -125,28 +144,29 @@ static inline void GetProgramExecutableNameImpl(char *p, char *e) { } // otherwise give up and just copy argv[0] into it - if (!*p && __argv[0] && strlen(__argv[0]) < e - p) { - strcpy(p, __argv[0]); + if (!*p && (q = __argv[0])) { + while ((c = *q++)) { + if (p + 1 < e) { + *p++ = c; + } + } + *p = 0; } } +static void InitProgramExecutableName(void) { + int e; + e = errno; + GetProgramExecutableNameImpl( + program_executable_name.buf, + program_executable_name.buf + sizeof(program_executable_name.buf)); + errno = e; +} + /** * Returns absolute path of program. */ char *GetProgramExecutableName(void) { - int e; - static bool once; - if (!once) { - e = errno; - GetProgramExecutableNameImpl( - program_executable_name, - program_executable_name + sizeof(program_executable_name)); - errno = e; - once = true; - } - return program_executable_name; + cosmo_once(&program_executable_name.once, InitProgramExecutableName); + return program_executable_name.buf; } - -/* const void *const GetProgramExecutableNameCtor[] initarray = { */ -/* GetProgramExecutableName, */ -/* }; */ diff --git a/libc/calls/ktmppath.c b/libc/calls/ktmppath.c index 862a335ce..42c5a8964 100644 --- a/libc/calls/ktmppath.c +++ b/libc/calls/ktmppath.c @@ -48,7 +48,7 @@ __attribute__((__constructor__)) static void kTmpPathInit(void) { char16_t path16[PATH_MAX]; if ((s = getenv("TMPDIR")) && (n = strlen(s)) < PATH_MAX / 2) { - memcpy(kTmpPath, s, n); + if (n) memcpy(kTmpPath, s, n); if (n && kTmpPath[n - 1] != '/') { kTmpPath[n + 0] = '/'; kTmpPath[n + 1] = 0; diff --git a/libc/runtime/mkstemp.c b/libc/calls/mkstemp.c similarity index 75% rename from libc/runtime/mkstemp.c rename to libc/calls/mkstemp.c index 0148e685d..c46c4c89b 100644 --- a/libc/runtime/mkstemp.c +++ b/libc/calls/mkstemp.c @@ -17,6 +17,8 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/errno.h" #include "libc/intrin/bits.h" #include "libc/stdio/rand.h" #include "libc/stdio/temp.h" @@ -25,30 +27,54 @@ #include "libc/sysv/errfuns.h" /** - * Creates temporary file name and descriptor, e.g. + * Creates temporary file name and file descriptor. + * + * The best way to construct your path template is: * * char path[PATH_MAX+1]; * strlcat(path, kTmpDir, sizeof(path)); * strlcat(path, "sauce.XXXXXX", sizeof(path)); + * + * This usage pattern makes mkstemp() equivalent to tmpfd(): + * + * int fd; + * fd = mkstemp(path); + * unlink(path); + * + * This usage pattern makes mkstemp() equivalent to mktemp(): + * * close(mkstemp(path)); * puts(path); * * @param template is mutated to replace last six X's with rng * @return open file descriptor r + w exclusive or -1 w/ errno * @raise EINVAL if `template` didn't end with `XXXXXX` + * @see tmpfd() if you don't need a path */ int mkstemp(char *template) { - int i, n; uint64_t w; + int i, n, e, fd; if ((n = strlen(template)) < 6 || READ16LE(template + n - 2) != READ16LE("XX") || READ32LE(template + n - 6) != READ32LE("XXXX")) { return einval(); } - w = _rand64(); - for (i = 0; i < 6; ++i) { - template[n - 6 + i] = "0123456789abcdefghijklmnopqrstuvwxyz"[w % 36]; - w /= 36; + for (;;) { + w = _rand64(); + for (i = 0; i < 6; ++i) { + template[n - 6 + i] = "0123456789abcdefghijklmnopqrstuvwxyz"[w % 36]; + w /= 36; + } + e = errno; + if ((fd = open(template, + O_RDWR | O_CREAT | O_EXCL | (IsWindows() ? 0x00410000 : 0), + 0600)) != -1) { + return fd; + } else if (errno == EEXIST) { + errno = e; + } else { + template[0] = 0; + return fd; + } } - return open(template, O_RDWR | O_CREAT | O_EXCL, 0600); } diff --git a/libc/stdio/mktemp.c b/libc/calls/mktemp.c similarity index 82% rename from libc/stdio/mktemp.c rename to libc/calls/mktemp.c index 2c5fe5d4a..cfad33ada 100644 --- a/libc/stdio/mktemp.c +++ b/libc/calls/mktemp.c @@ -16,11 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/errno.h" -#include "libc/intrin/bits.h" -#include "libc/stdio/rand.h" +#include "libc/calls/calls.h" #include "libc/stdio/temp.h" -#include "libc/str/str.h" /** * Generates temporary filename. @@ -34,18 +31,11 @@ * @see mkstemp() */ char *mktemp(char *template) { - int i, n; - uint64_t w; - if ((n = strlen(template)) < 6 || - READ16LE(template + n - 2) != READ16LE("XX") || - READ32LE(template + n - 6) != READ32LE("XXXX")) { - errno = EINVAL; + int fd; + if ((fd = mkstemp(template)) != -1) { + close(fd); + return template; + } else { return 0; } - w = _rand64(); - for (i = 0; i < 6; ++i) { - template[n - 6 + i] = "0123456789abcdefghijklmnopqrstuvwxyz"[w % 36]; - w /= 36; - } - return template; } diff --git a/libc/calls/openat.c b/libc/calls/openat.c index 803eb409a..142d561e0 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -132,6 +132,7 @@ * @raise ENOTSUP if `file` is on zip file system and process is vfork()'d * @raise ENOSPC if file system is full when `file` would be `O_CREAT`ed * @raise EINTR if we needed to block and a signal was delivered instead + * @raise EEXIST if `O_CREAT|O_EXCL` are used and `file` already existed * @raise ECANCELED if thread was cancelled in masked mode * @raise ENOENT if `file` doesn't exist when `O_CREAT` isn't in `flags` * @raise ENOENT if `file` points to a string that's empty diff --git a/libc/calls/read.c b/libc/calls/read.c index 2b17753b7..7f758bc57 100644 --- a/libc/calls/read.c +++ b/libc/calls/read.c @@ -86,7 +86,7 @@ ssize_t read(int fd, void *buf, size_t size) { rc = ebadf(); } END_CANCELLATION_POINT; - DATATRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), - buf, rc > 40 ? "..." : "", size, rc); + DATATRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, + (int)MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, rc); return rc; } diff --git a/libc/calls/readv-metal.c b/libc/calls/readv-metal.c index 8d813deff..46a6817e0 100644 --- a/libc/calls/readv-metal.c +++ b/libc/calls/readv-metal.c @@ -50,7 +50,7 @@ ssize_t sys_readv_metal(struct Fd *fd, const struct iovec *iov, int iovlen) { file = (struct MetalFile *)fd->handle; for (toto = i = 0; i < iovlen && file->pos < file->size; ++i) { got = MIN(iov[i].iov_len, file->size - file->pos); - memcpy(iov[i].iov_base, file->base, got); + if (got) memcpy(iov[i].iov_base, file->base, got); toto += got; } return toto; diff --git a/libc/calls/realpath.c b/libc/calls/realpath.c index e038e7211..912d07f48 100644 --- a/libc/calls/realpath.c +++ b/libc/calls/realpath.c @@ -145,7 +145,7 @@ restart: l++; } if (q+l >= PATH_MAX) goto toolong; - memcpy(output+q, stack+p, l); + if (l) memcpy(output+q, stack+p, l); output[q+l] = 0; p += l; @@ -223,7 +223,7 @@ skip_readlink: if (q-p && !IsSlash(stack[l-1])) stack[l++] = '/'; if (l + (q-p) + 1 >= PATH_MAX) goto toolong; memmove(output + l, output + p, q - p + 1); - memcpy(output, stack, l); + if (l) memcpy(output, stack, l); q = l + q-p; } diff --git a/libc/calls/splice.c b/libc/calls/splice.c index 244d44230..2c161153a 100644 --- a/libc/calls/splice.c +++ b/libc/calls/splice.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/syscall-sysv.internal.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" @@ -28,10 +29,9 @@ #include "libc/mem/alloca.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" static struct Splice { - pthread_once_t once; + _Atomic(uint32_t) once; bool ok; } g_splice; @@ -79,7 +79,7 @@ ssize_t splice(int infd, int64_t *opt_in_out_inoffset, int outfd, int64_t *opt_in_out_outoffset, size_t uptobytes, uint32_t flags) { ssize_t rc; - pthread_once(&g_splice.once, splice_init); + cosmo_once(&g_splice.once, splice_init); if (!g_splice.ok) { rc = enosys(); } else if (IsAsan() && ((opt_in_out_inoffset && diff --git a/libc/calls/symlinkat-nt.c b/libc/calls/symlinkat-nt.c index 0dca1a9c8..dfd063392 100644 --- a/libc/calls/symlinkat-nt.c +++ b/libc/calls/symlinkat-nt.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/syscall_support-nt.internal.h" +#include "libc/cosmo.h" #include "libc/errno.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/fileflagandattributes.h" @@ -31,12 +32,13 @@ #include "libc/nt/struct/tokenprivileges.h" #include "libc/nt/thunk/msabi.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; -static _Bool g_winlink_allowed; -static pthread_once_t g_winlink_once; +static struct { + _Atomic(uint32_t) once; + _Bool allowed; +} g_winlink; static textwindows void InitializeWinlink(void) { int64_t tok; @@ -48,7 +50,7 @@ static textwindows void InitializeWinlink(void) { tp.Privileges[0].Luid = id; tp.Privileges[0].Attributes = kNtSePrivilegeEnabled; if (!AdjustTokenPrivileges(tok, 0, &tp, sizeof(tp), 0, 0)) return; - g_winlink_allowed = GetLastError() != kNtErrorNotAllAssigned; + g_winlink.allowed = GetLastError() != kNtErrorNotAllAssigned; } textwindows int sys_symlinkat_nt(const char *target, int newdirfd, @@ -82,8 +84,8 @@ textwindows int sys_symlinkat_nt(const char *target, int newdirfd, // windows only lets administrators do this // even then we're required to ask for permission - pthread_once(&g_winlink_once, InitializeWinlink); - if (!g_winlink_allowed) { + cosmo_once(&g_winlink.once, InitializeWinlink); + if (!g_winlink.allowed) { return eperm(); } diff --git a/libc/calls/sync_file_range.c b/libc/calls/sync_file_range.c index 5c020e472..8b27915bd 100644 --- a/libc/calls/sync_file_range.c +++ b/libc/calls/sync_file_range.c @@ -29,7 +29,7 @@ * @note Linux documentation says this call is "dangerous"; for highest * assurance of data recovery after crash, consider fsync() on both * file and directory - * @see fsync(), fdatasync(), PAGESIZE + * @see fsync(), fdatasync() */ int sync_file_range(int fd, int64_t offset, int64_t bytes, unsigned flags) { int rc, olderr; diff --git a/libc/calls/tmpfd.c b/libc/calls/tmpfd.c index 286b183a4..a2df85044 100644 --- a/libc/calls/tmpfd.c +++ b/libc/calls/tmpfd.c @@ -16,11 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/rand.h" #include "libc/stdio/temp.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" @@ -64,6 +64,7 @@ * @return file descriptor on success, or -1 w/ errno * @raise ECANCELED if thread was cancelled in masked mode * @raise EINTR if signal was delivered + * @see mkstemp() if you need a path * @see tmpfile() for stdio version * @cancellationpoint * @asyncsignalsafe @@ -71,45 +72,23 @@ * @vforksafe */ int tmpfd(void) { - FILE *f; - unsigned x; - int fd, i, j, e; - char path[PATH_MAX], *p; - e = errno; - if (IsLinux() && (fd = open(kTmpPath, O_RDWR | _O_TMPFILE, 0600)) != -1) { - return fd; - } - errno = e; - p = path; - p = stpcpy(p, kTmpPath); - p = stpcpy(p, "tmp."); - if (program_invocation_short_name && - strlen(program_invocation_short_name) < 128) { - p = stpcpy(p, program_invocation_short_name); - *p++ = '.'; - } - for (i = 0; i < 10; ++i) { - x = _rand64(); - for (j = 0; j < 6; ++j) { - p[j] = "0123456789abcdefghijklmnopqrstuvwxyz"[x % 36]; - x /= 36; - } - p[j] = 0; + int e, fd; + const char *prog; + char path[PATH_MAX + 1]; + if (IsLinux()) { e = errno; - if ((fd = open(path, - O_RDWR | O_CREAT | O_EXCL | (IsWindows() ? _O_TMPFILE : 0), - 0600)) != -1) { - if (!IsWindows()) { - if (unlink(path)) { - notpossible; - } - } + if ((fd = open(kTmpPath, O_RDWR | _O_TMPFILE, 0600)) != -1) { return fd; - } else if (errno == EEXIST) { - errno = e; } else { - break; + errno = e; } } - return -1; + path[0] = 0; + strlcat(path, kTmpPath, sizeof(path)); + if (!(prog = program_invocation_short_name)) prog = "tmp"; + strlcat(path, prog, sizeof(path)); + strlcat(path, ".XXXXXX", sizeof(path)); + if ((fd = mkstemp(path)) == -1) return -1; + if (!IsWindows()) unassert(!unlink(path)); + return fd; } diff --git a/libc/calls/ttyname.c b/libc/calls/ttyname.c index 94e064feb..5df6e696e 100644 --- a/libc/calls/ttyname.c +++ b/libc/calls/ttyname.c @@ -17,15 +17,26 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/sysparam.h" +#include "libc/errno.h" #include "libc/log/log.h" - -static char ttyname_buf[PATH_MAX]; +#include "libc/paths.h" /** * Returns name of terminal. + * + * This function isn't required to be thread safe, consider ttyname_r(). + * + * @return terminal path on success, or null w/ errno + * @see ttyname_r() */ char *ttyname(int fd) { - int rc = ttyname_r(fd, ttyname_buf, sizeof(ttyname_buf)); - if (rc != 0) return NULL; - return &ttyname_buf[0]; + errno_t err; + static char buf[sizeof(_PATH_DEV) + MAXNAMLEN]; + if (!(err = ttyname_r(fd, buf, sizeof(buf)))) { + return buf; + } else { + errno = err; + return 0; + } } diff --git a/libc/calls/ttyname_r.c b/libc/calls/ttyname_r.c index 7235735cc..4823cb81f 100644 --- a/libc/calls/ttyname_r.c +++ b/libc/calls/ttyname_r.c @@ -25,6 +25,7 @@ #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/fmt/itoa.h" +#include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/log/log.h" #include "libc/nt/console.h" @@ -34,66 +35,79 @@ #define FIODGNAME 0x80106678 // freebsd -static textwindows dontinline int sys_ttyname_nt(int fd, char *buf, - size_t size) { +static textwindows errno_t sys_ttyname_nt(int fd, char *buf, size_t size) { uint32_t mode; + const char *s; if (GetConsoleMode(g_fds.p[fd].handle, &mode)) { - if (mode & kNtEnableVirtualTerminalInput) { - strncpy(buf, "CONIN$", size); + if (strlcpy(buf, + (mode & kNtEnableVirtualTerminalInput) ? "CONIN$" : "CONOUT$", + size) < size) { return 0; } else { - strncpy(buf, "CONOUT$", size); - return 0; + return ERANGE; } } else { - return enotty(); + return ENOTTY; } } -static int ttyname_freebsd(int fd, char *buf, size_t size) { +// clobbers errno +static errno_t ttyname_freebsd(int fd, char *buf, size_t size) { struct fiodgname_arg { int len; void *buf; } fg; fg.buf = buf; fg.len = size; - if (sys_ioctl(fd, FIODGNAME, &fg) != -1) return 0; - return enotty(); + if (sys_ioctl(fd, FIODGNAME, &fg) != -1) { + return 0; + } else { + return ENOTTY; + } } -static int ttyname_linux(int fd, char *buf, size_t size) { - struct stat st1, st2; - if (!isatty(fd)) return errno; - char name[PATH_MAX]; - FormatInt32(stpcpy(name, "/proc/self/fd/"), fd); +// clobbers errno +static errno_t ttyname_linux(int fd, char *buf, size_t size) { ssize_t got; + struct stat st1, st2; + char name[14 + 12 + 1]; + if (!isatty(fd)) return errno; + FormatInt32(stpcpy(name, "/proc/self/fd/"), fd); got = readlink(name, buf, size); if (got == -1) return errno; - if ((size_t)got >= size) return erange(); + if (got >= size) return ERANGE; buf[got] = 0; if (stat(buf, &st1) || fstat(fd, &st2)) return errno; - if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) return enodev(); + if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) return ENODEV; return 0; } /** - * Returns name of terminal, reentrantly. + * Returns name of terminal. + * + * @return 0 on success, or error number on error + * @raise ERANGE if `size` was too small + * @returnserrno + * @threadsafe */ -int ttyname_r(int fd, char *buf, size_t size) { - int rc; +errno_t ttyname_r(int fd, char *buf, size_t size) { + errno_t e, res; + e = errno; if (IsLinux()) { - rc = ttyname_linux(fd, buf, size); + res = ttyname_linux(fd, buf, size); } else if (IsFreebsd()) { - rc = ttyname_freebsd(fd, buf, size); + res = ttyname_freebsd(fd, buf, size); } else if (IsWindows()) { - if (__isfdkind(fd, kFdFile)) { - rc = sys_ttyname_nt(fd, buf, size); + if (__isfdopen(fd)) { + res = sys_ttyname_nt(fd, buf, size); } else { - rc = ebadf(); + res = EBADF; } } else { - rc = enosys(); + res = ENOSYS; } - STRACE("ttyname_r(%d, %s) → %d% m", fd, buf, rc); - return rc; + errno = e; + STRACE("ttyname_r(%d, %#.*hhs) → %s", fd, (int)size, buf, + !res ? "0" : _strerrno(res)); + return res; } diff --git a/libc/cosmo.h b/libc/cosmo.h new file mode 100644 index 000000000..f349d01c4 --- /dev/null +++ b/libc/cosmo.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_COSMO_H_ +#define COSMOPOLITAN_LIBC_COSMO_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +errno_t cosmo_once(_Atomic(uint32_t) *, void (*)(void)); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_COSMO_H_ */ diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index d75c0a053..c3073edfa 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -78,7 +78,7 @@ /* Programs should call GetStackSize() */ #define APE_STACKSIZE 262144 /* default 256kb stack */ #define FRAMESIZE 0x10000 -#define PAGESIZE 0x1000 /* i386+ */ +#define _PAGESIZE 0x1000 /* i386+ */ #else #define APE_STACKSIZE 4194304 /* default 4mb stack */ #endif diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index 110fdf141..ee91d38ed 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -421,7 +421,7 @@ static struct AsanFault __asan_fault(const signed char *s, signed char dflt) { struct AsanFault r; if (s[0] < 0) { r.kind = s[0]; - } else if (((uintptr_t)(s + 1) & (PAGESIZE - 1)) && s[1] < 0) { + } else if (((uintptr_t)(s + 1) & 4095) && s[1] < 0) { r.kind = s[1]; } else { r.kind = dflt; @@ -652,6 +652,8 @@ static wint_t __asan_symbolize_access_poison(signed char kind) { return L'μ'; case kAsanGlobalOverrun: return L'Ω'; + case kAsanMmapSizeOverrun: + return L'Z'; default: return L'?'; } @@ -963,14 +965,6 @@ __attribute__((__destructor__)) static void __asan_morgue_flush(void) { } } -static size_t __asan_user_size(size_t n) { - if (n) { - return n; - } else { - return 1; - } -} - static size_t __asan_heap_size(size_t n) { if (n < 0x7fffffff0000) { n = ROUNDUP(n, _Alignof(struct AsanExtra)); @@ -1043,7 +1037,6 @@ static void *__asan_allocate(size_t a, size_t n, struct AsanTrace *bt, char *p; size_t c; struct AsanExtra *e; - n = __asan_user_size(n); if ((p = _weaken(dlmemalign)(a, __asan_heap_size(n)))) { c = _weaken(dlmalloc_usable_size)(p); e = (struct AsanExtra *)(p + c - sizeof(*e)); @@ -1244,12 +1237,7 @@ void *__asan_calloc(size_t n, size_t m) { void *__asan_realloc(void *p, size_t n) { struct AsanTrace bt; if (p) { - if (n) { - return __asan_realloc_impl(p, n, __asan_realloc_grow); - } else { - __asan_free(p); - return 0; - } + return __asan_realloc_impl(p, n, __asan_realloc_grow); } else { __asan_trace(&bt, RBP); return __asan_allocate_heap(16, n, &bt); diff --git a/libc/intrin/asancodes.h b/libc/intrin/asancodes.h index d2320950c..f5de56027 100644 --- a/libc/intrin/asancodes.h +++ b/libc/intrin/asancodes.h @@ -1,28 +1,29 @@ #ifndef COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ #define COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ -#define kAsanScale 3 -#define kAsanMagic 0x7fff8000 -#define kAsanNullPage -1 /* ∅ 0xff */ -#define kAsanProtected -2 /* P 0xfe */ -#define kAsanHeapFree -3 /* F 0xfd */ -#define kAsanHeapRelocated -4 /* R 0xfc */ -#define kAsanAllocaOverrun -5 /* 𝑂 0xfb */ -#define kAsanHeapUnderrun -6 /* U 0xfa */ -#define kAsanHeapOverrun -7 /* O 0xf9 */ -#define kAsanStackUnscoped -8 /* s 0xf8 */ -#define kAsanStackOverflow -9 /* ! 0xf7 */ -#define kAsanGlobalOrder -10 /* I 0xf6 */ -#define kAsanStackFree -11 /* r 0xf5 */ -#define kAsanStackPartial -12 /* p 0xf4 */ -#define kAsanStackOverrun -13 /* o 0xf3 */ -#define kAsanStackMiddle -14 /* m 0xf2 */ -#define kAsanStackUnderrun -15 /* u 0xf1 */ -#define kAsanAllocaUnderrun -16 /* 𝑈 0xf0 */ -#define kAsanUnmapped -17 /* M 0xef */ -#define kAsanGlobalRedzone -18 /* G 0xee */ -#define kAsanGlobalGone -19 /* 𝐺 0xed */ -#define kAsanGlobalUnderrun -20 /* μ 0xec */ -#define kAsanGlobalOverrun -21 /* Ω 0xeb */ +#define kAsanScale 3 +#define kAsanMagic 0x7fff8000 +#define kAsanNullPage -1 /* ∅ 0xff */ +#define kAsanProtected -2 /* P 0xfe */ +#define kAsanHeapFree -3 /* F 0xfd */ +#define kAsanHeapRelocated -4 /* R 0xfc */ +#define kAsanAllocaOverrun -5 /* 𝑂 0xfb */ +#define kAsanHeapUnderrun -6 /* U 0xfa */ +#define kAsanHeapOverrun -7 /* O 0xf9 */ +#define kAsanStackUnscoped -8 /* s 0xf8 */ +#define kAsanStackOverflow -9 /* ! 0xf7 */ +#define kAsanGlobalOrder -10 /* I 0xf6 */ +#define kAsanStackFree -11 /* r 0xf5 */ +#define kAsanStackPartial -12 /* p 0xf4 */ +#define kAsanStackOverrun -13 /* o 0xf3 */ +#define kAsanStackMiddle -14 /* m 0xf2 */ +#define kAsanStackUnderrun -15 /* u 0xf1 */ +#define kAsanAllocaUnderrun -16 /* 𝑈 0xf0 */ +#define kAsanUnmapped -17 /* M 0xef */ +#define kAsanGlobalRedzone -18 /* G 0xee */ +#define kAsanGlobalGone -19 /* 𝐺 0xed */ +#define kAsanGlobalUnderrun -20 /* μ 0xec */ +#define kAsanGlobalOverrun -21 /* Ω 0xeb */ +#define kAsanMmapSizeOverrun -22 /* Z 0xea */ #endif /* COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ */ diff --git a/libc/intrin/bits.h b/libc/intrin/bits.h index ff29985aa..72d583904 100644 --- a/libc/intrin/bits.h +++ b/libc/intrin/bits.h @@ -8,9 +8,6 @@ int _bitreverse8(int) pureconst; int _bitreverse16(int) pureconst; uint32_t _bitreverse32(uint32_t) pureconst; uint64_t _bitreverse64(uint64_t) pureconst; -unsigned long _roundup2pow(unsigned long) pureconst; -unsigned long _roundup2log(unsigned long) pureconst; -unsigned long _rounddown2pow(unsigned long) pureconst; #define READ16LE(P) \ (__extension__({ \ diff --git a/libc/calls/vmsplice.c b/libc/intrin/cosmo_once.c similarity index 57% rename from libc/calls/vmsplice.c rename to libc/intrin/cosmo_once.c index 922ce5989..4ff1e87e2 100644 --- a/libc/calls/vmsplice.c +++ b/libc/intrin/cosmo_once.c @@ -1,7 +1,7 @@ /*-*- 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 2020 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 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 │ @@ -16,29 +16,47 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/calls/struct/iovec.h" -#include "libc/calls/struct/iovec.internal.h" +#include "libc/cosmo.h" #include "libc/errno.h" +#include "libc/intrin/atomic.h" +#include "libc/thread/thread.h" + +#define INIT 0 +#define CALLING 1 +#define FINISHED 2 /** - * Transfers memory to pipe. + * Ensures initialization function is called exactly once. * - * @param flags can have SPLICE_F_{MOVE,NONBLOCK,MORE,GIFT} - * @return number of bytes actually transferred, or -1 w/ errno + * This is the same as `pthread_once` except that it always uses a tiny + * spinlock implementation and won't make any system calls. It's needed + * since this function is an upstream dependency of both pthread_once() + * and nsync_once(). Most code should favor calling those functions. + * + * @return 0 on success, or errno on error */ -ssize_t vmsplice(int fd, const struct iovec *chunks, int64_t count, - uint32_t flags) { - int olderr; - ssize_t wrote; - olderr = errno; - if ((wrote = sys_vmsplice(fd, chunks, count, flags)) == -1) { - errno = olderr; - if (count) { - wrote = write(fd, chunks[0].iov_base, chunks[0].iov_len); - } else { - wrote = write(fd, NULL, 0); - } +errno_t cosmo_once(_Atomic(uint32_t) *once, void init(void)) { + uint32_t old; + switch ((old = atomic_load_explicit(once, memory_order_relaxed))) { + case INIT: + if (atomic_compare_exchange_strong_explicit(once, &old, CALLING, + memory_order_acquire, + memory_order_relaxed)) { + init(); + atomic_store_explicit(once, FINISHED, memory_order_release); + return 0; + } + // fallthrough + case CALLING: + for (;;) { + if (atomic_load_explicit(once, memory_order_acquire) != CALLING) { + break; + } + } + return 0; + case FINISHED: + return 0; + default: + return EINVAL; } - return wrote; } diff --git a/libc/intrin/describeframe.c b/libc/intrin/describeframe.c index 847e3b707..0d2021986 100644 --- a/libc/intrin/describeframe.c +++ b/libc/intrin/describeframe.c @@ -37,8 +37,6 @@ static const char *GetFrameName(int x) { return "automap"; } else if (IsFixedFrame(x)) { return "fixed"; - } else if (IsArenaFrame(x)) { - return "arena"; } else if (IsStaticStackFrame(x)) { return "stack"; } else if (IsGfdsFrame(x)) { diff --git a/libc/intrin/describeopenflags.c b/libc/intrin/describeopenflags.c index d6f304315..03a349425 100644 --- a/libc/intrin/describeopenflags.c +++ b/libc/intrin/describeopenflags.c @@ -25,7 +25,7 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/sol.h" -#define N (PAGESIZE / 2 / sizeof(struct DescribeFlags)) +#define N (4096 / 2 / sizeof(struct DescribeFlags)) /** * Describes clock_gettime() clock argument. diff --git a/libc/intrin/describesigaction.c b/libc/intrin/describesigaction.c index d5ca35f19..da6ee9d2d 100644 --- a/libc/intrin/describesigaction.c +++ b/libc/intrin/describesigaction.c @@ -46,6 +46,7 @@ static const char *DescribeSigFlags(char buf[64], int x) { {SA_RESETHAND, "RESETHAND"}, // {SA_NOMASK, "NOMASK"}, // {SA_ONESHOT, "ONESHOT"}, // + {0x04000000, "RESTORER"}, // }; return DescribeFlags(buf, 64, kSigFlags, ARRAYLEN(kSigFlags), "SA_", x); } diff --git a/libc/intrin/describesocketprotocol.c b/libc/intrin/describesocketprotocol.c index a2ae09142..74d7004ab 100644 --- a/libc/intrin/describesocketprotocol.c +++ b/libc/intrin/describesocketprotocol.c @@ -27,6 +27,7 @@ const char *(DescribeSocketProtocol)(char buf[12], int family) { if (family == IPPROTO_UDP) return "IPPROTO_UDP"; if (family == IPPROTO_RAW) return "IPPROTO_RAW"; if (family == IPPROTO_IPV6) return "IPPROTO_IPv6"; + if (family == IPPROTO_ICMPV6) return "IPPROTO_ICMPV6"; FormatInt32(buf, family); return buf; } diff --git a/libc/intrin/describesocklevel.c b/libc/intrin/describesocklevel.c index c009ae249..dd7a0900a 100644 --- a/libc/intrin/describesocklevel.c +++ b/libc/intrin/describesocklevel.c @@ -24,10 +24,14 @@ * Describes setsockopt() level arguments. */ const char *(DescribeSockLevel)(char buf[12], int x) { + if (x == SOL_SOCKET) return "SOL_SOCKET"; if (x == SOL_IP) return "SOL_IP"; + if (x == SOL_ICMP) return "SOL_ICMP"; if (x == SOL_TCP) return "SOL_TCP"; if (x == SOL_UDP) return "SOL_UDP"; - if (x == SOL_SOCKET) return "SOL_SOCKET"; + if (x == SOL_IPV6) return "SOL_IPV6"; + if (x == SOL_ICMPV6) return "SOL_ICMPV6"; + if (x == SOL_RAW) return "SOL_RAW"; FormatInt32(buf, x); return buf; } diff --git a/libc/intrin/describestat.c b/libc/intrin/describestat.c index c844f2247..80ad0db05 100644 --- a/libc/intrin/describestat.c +++ b/libc/intrin/describestat.c @@ -79,7 +79,7 @@ const char *(DescribeStat)(char buf[N], int rc, const struct stat *st) { append(", .st_%s=%'lu", "rdev", st->st_rdev); } - if (st->st_blksize != PAGESIZE) { + if (st->st_blksize != 4096) { append(", .st_%s=%'lu", "blksize", st->st_blksize); } diff --git a/libc/intrin/ftrace_enabled.c b/libc/intrin/ftrace_enabled.c index 05cc68cf2..1e448fbe6 100644 --- a/libc/intrin/ftrace_enabled.c +++ b/libc/intrin/ftrace_enabled.c @@ -25,7 +25,7 @@ * @param delta is added to enabled state * @return enabled state before `delta` was applied */ -int ftrace_enabled(int delta) { +dontinstrument int ftrace_enabled(int delta) { int res; struct CosmoTib *tib; if (__tls_enabled) { diff --git a/libc/intrin/g_fds.c b/libc/intrin/g_fds.c index db5f9ce8c..68d5ed9d2 100644 --- a/libc/intrin/g_fds.c +++ b/libc/intrin/g_fds.c @@ -18,13 +18,17 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" +#include "libc/intrin/_getenv.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/extend.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/intrin/pushpop.internal.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/nt/runtime.h" #include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" #include "libc/str/str.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" @@ -37,16 +41,26 @@ __static_yoink("_init_g_fds"); struct Fds g_fds; static struct Fd g_fds_static[OPEN_MAX]; -static textwindows dontinline void SetupWinStd(struct Fds *fds, int i, int x) { +static int Atoi(const char *str) { + int i; + for (i = 0; '0' <= *str && *str <= '9'; ++str) { + i *= 10; + i += *str - '0'; + } + return i; +} + +static textwindows dontinline void SetupWinStd(struct Fds *fds, int i, int x, + int sockset) { int64_t h; h = GetStdHandle(x); if (!h || h == -1) return; - fds->p[i].kind = pushpop(kFdFile); + fds->p[i].kind = ((1 << i) & sockset) ? pushpop(kFdSocket) : pushpop(kFdFile); fds->p[i].handle = h; atomic_store_explicit(&fds->f, i + 1, memory_order_relaxed); } -textstartup void __init_fds(void) { +textstartup void __init_fds(int argc, char **argv, char **envp) { struct Fds *fds; __fds_lock_obj._type = PTHREAD_MUTEX_RECURSIVE; fds = __veil("r", &g_fds); @@ -77,9 +91,29 @@ textstartup void __init_fds(void) { fds->p[1].handle = __veil("r", 0x3F8ull); fds->p[2].handle = __veil("r", 0x3F8ull); } else if (IsWindows()) { - SetupWinStd(fds, 0, kNtStdInputHandle); - SetupWinStd(fds, 1, kNtStdOutputHandle); - SetupWinStd(fds, 2, kNtStdErrorHandle); + int sockset = 0; + struct Env var; + var = _getenv(envp, "__STDIO_SOCKETS"); + if (var.s) { + int i = var.i + 1; + do { + envp[i - 1] = envp[i]; + } while (envp[i]); + sockset = Atoi(var.s); + } + if (sockset && !_weaken(socket)) { +#ifdef SYSDEBUG + kprintf("%s: parent process passed sockets as stdio, but this program" + " can't use them since it didn't link the socket() function\n", + argv[0]); + _Exit(1); +#else + sockset = 0; // let ReadFile() fail +#endif + } + SetupWinStd(fds, 0, kNtStdInputHandle, sockset); + SetupWinStd(fds, 1, kNtStdOutputHandle, sockset); + SetupWinStd(fds, 2, kNtStdErrorHandle, sockset); } fds->p[1].flags = O_WRONLY | O_APPEND; fds->p[2].flags = O_WRONLY | O_APPEND; diff --git a/libc/intrin/g_fds_init.S b/libc/intrin/g_fds_init.S index 279078f5b..225e940d9 100644 --- a/libc/intrin/g_fds_init.S +++ b/libc/intrin/g_fds_init.S @@ -21,6 +21,9 @@ .init.start 305,_init_g_fds push %rdi push %rsi + mov %r12d,%edi // argc + mov %r13,%rsi // argv + mov %r14,%rdx // environ call __init_fds pop %rsi pop %rdi diff --git a/libc/intrin/getauxval.c b/libc/intrin/getauxval.c index 986014305..87a3bdc25 100644 --- a/libc/intrin/getauxval.c +++ b/libc/intrin/getauxval.c @@ -35,7 +35,11 @@ unsigned long getauxval(unsigned long key) { x = _getauxval(key); if (key == AT_PAGESZ) { if (!x.isfound) { +#ifdef __aarch64__ x.value = 16384; +#else + x.value = 4096; +#endif } x.isfound = true; } diff --git a/libc/intrin/getenv.c b/libc/intrin/getenv.c index f61f073d4..9b1f6922a 100644 --- a/libc/intrin/getenv.c +++ b/libc/intrin/getenv.c @@ -26,6 +26,7 @@ * Environment variables can store empty string on Unix but not Windows. * * @return pointer to value of `environ` entry, or null if not found + * @threadunsafe */ char *getenv(const char *s) { char **p; diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index b1436aa23..d7e71356e 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -625,7 +625,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, ++p; } for (i = j = 0; !pdot || j < prec; ++j) { - if (UNLIKELY(!((intptr_t)s & (PAGESIZE - 1)))) { + if (UNLIKELY(!((intptr_t)s & 4095))) { if (!dang && kisdangerous(s)) break; } if (!type) { @@ -687,7 +687,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, s += sizeof(char16_t); if (IsHighSurrogate(t)) { if (!pdot || j + 1 < prec) { - if (UNLIKELY(!((intptr_t)s & (PAGESIZE - 1)))) { + if (UNLIKELY(!((intptr_t)s & 4095))) { if (!dang && kisdangerous(s)) break; } u = *(const char16_t *)s; diff --git a/libc/intrin/morton.c b/libc/intrin/morton.c deleted file mode 100644 index ab03b777b..000000000 --- a/libc/intrin/morton.c +++ /dev/null @@ -1,38 +0,0 @@ -/*-*- 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 2020 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/intrin/morton.h" - -/** - * Interleaves bits. - * @see https://en.wikipedia.org/wiki/Z-order_curve - * @see unmorton() - */ -unsigned long morton(unsigned long y, unsigned long x) { - x = (x | x << 020) & 0x0000FFFF0000FFFF; - x = (x | x << 010) & 0x00FF00FF00FF00FF; - x = (x | x << 004) & 0x0F0F0F0F0F0F0F0F; - x = (x | x << 002) & 0x3333333333333333; - x = (x | x << 001) & 0x5555555555555555; - y = (y | y << 020) & 0x0000FFFF0000FFFF; - y = (y | y << 010) & 0x00FF00FF00FF00FF; - y = (y | y << 004) & 0x0F0F0F0F0F0F0F0F; - y = (y | y << 002) & 0x3333333333333333; - y = (y | y << 001) & 0x5555555555555555; - return x | y << 1; -} diff --git a/libc/intrin/morton.h b/libc/intrin/morton.h deleted file mode 100644 index 215ece255..000000000 --- a/libc/intrin/morton.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_BITS_MORTON_H_ -#define COSMOPOLITAN_LIBC_BITS_MORTON_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -#ifdef COSMO - -#define morton __morton -#define unmorton __unmorton - -unsigned long morton(unsigned long, unsigned long) libcesque; -axdx_t unmorton(unsigned long) libcesque; - -#endif /* COSMO */ -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_BITS_MORTON_H_ */ diff --git a/libc/intrin/printmemoryintervals.c b/libc/intrin/printmemoryintervals.c index 485ea8bd2..281a82fb3 100644 --- a/libc/intrin/printmemoryintervals.c +++ b/libc/intrin/printmemoryintervals.c @@ -27,7 +27,6 @@ static bool IsNoteworthyHole(unsigned i, const struct MemoryIntervals *mm) { // gaps between shadow frames aren't interesting // the chasm from heap to stack ruins statistics return !( - (IsArenaFrame(mm->p[i].y) && !IsArenaFrame(mm->p[i + 1].x)) || (IsShadowFrame(mm->p[i].y) || IsShadowFrame(mm->p[i + 1].x)) || (!IsStaticStackFrame(mm->p[i].y) && IsStaticStackFrame(mm->p[i + 1].x))); } diff --git a/libc/intrin/putenv.c b/libc/intrin/putenv.c index 364536347..7536a1dc8 100644 --- a/libc/intrin/putenv.c +++ b/libc/intrin/putenv.c @@ -93,6 +93,7 @@ int PutEnvImpl(char *s, bool overwrite) { * @return 0 on success, or non-zero w/ errno on error * @raise ENOMEM if we require more vespene gas * @see setenv(), getenv() + * @threadunsafe */ int putenv(char *s) { int rc; diff --git a/libc/intrin/rounddown2pow.c b/libc/intrin/rounddown2pow.c deleted file mode 100644 index a9e8b8e45..000000000 --- a/libc/intrin/rounddown2pow.c +++ /dev/null @@ -1,30 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/intrin/bsr.h" - -/** - * Returns 𝑥 rounded down to previous two power. - * - * @define (𝑥>0→2^⌊log₂𝑥⌋, x=0→0, 𝑇→⊥) - * @see _roundup2pow() - */ -unsigned long _rounddown2pow(unsigned long x) { - return x ? 1ul << _bsrl(x) : 0; -} diff --git a/libc/intrin/roundup2log.c b/libc/intrin/roundup2log.c deleted file mode 100644 index e74204f3b..000000000 --- a/libc/intrin/roundup2log.c +++ /dev/null @@ -1,28 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/intrin/bsr.h" - -/** - * Returns 𝑥 rounded up to next two power and log'd. - * @see _roundup2pow() - */ -unsigned long _roundup2log(unsigned long x) { - return x > 1 ? (_bsrl(x - 1) + 1) : x ? 1 : 0; -} diff --git a/libc/intrin/roundup2pow.c b/libc/intrin/roundup2pow.c deleted file mode 100644 index 62584e874..000000000 --- a/libc/intrin/roundup2pow.c +++ /dev/null @@ -1,30 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/intrin/bsr.h" - -/** - * Returns 𝑥 rounded up to next two power. - * - * @define (𝑥>0→2^⌈log₂x⌉, x=0→0, 𝑇→⊥) - * @see _rounddown2pow() - */ -unsigned long _roundup2pow(unsigned long x) { - return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; -} diff --git a/libc/intrin/setenv.c b/libc/intrin/setenv.c index 7879d1bfb..bed6840c1 100644 --- a/libc/intrin/setenv.c +++ b/libc/intrin/setenv.c @@ -30,6 +30,7 @@ * @raise EINVAL if `name` is empty or contains `'='` * @raise ENOMEM if we require more vespene gas * @see putenv(), getenv() + * @threadunsafe */ int setenv(const char *name, const char *value, int overwrite) { int rc; diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.internal.h index e6e1ce20a..141b50308 100644 --- a/libc/intrin/strace.internal.h +++ b/libc/intrin/strace.internal.h @@ -19,7 +19,9 @@ COSMOPOLITAN_C_START_ #define STRACE(FMT, ...) \ do { \ if (UNLIKELY(__strace > 0) && strace_enabled(0) > 0) { \ + ftrace_enabled(-1); \ __stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__); \ + ftrace_enabled(+1); \ } \ } while (0) #else diff --git a/libc/intrin/strace_enabled.c b/libc/intrin/strace_enabled.c index c63c1b42d..e3783b36c 100644 --- a/libc/intrin/strace_enabled.c +++ b/libc/intrin/strace_enabled.c @@ -25,7 +25,7 @@ * @param delta is added to enabled state * @return enabled state before `delta` was applied */ -int strace_enabled(int delta) { +dontinstrument int strace_enabled(int delta) { int res; struct CosmoTib *tib; if (__tls_enabled) { diff --git a/libc/intrin/udivmodti4.c b/libc/intrin/udivmodti4.c index 8c240e100..8dfc565c4 100644 --- a/libc/intrin/udivmodti4.c +++ b/libc/intrin/udivmodti4.c @@ -85,7 +85,7 @@ forceinline du_int udiv128by64to64(du_int u1, du_int u0, du_int v, du_int *r) { * @param b is divisor * @param rem receives remainder if not NULL */ -COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) { +tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) { const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT; utwords dividend, divisor, quotient, remainder; si_int shift; @@ -135,3 +135,7 @@ COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) { if (rem) *rem = dividend.all; return quotient.all; } + +tu_int __udivti3(tu_int a, tu_int b) { + return __udivmodti4(a, b, NULL); +} diff --git a/libc/intrin/udivti3.c b/libc/intrin/udivti3.c deleted file mode 100644 index 8aa79bd30..000000000 --- a/libc/intrin/udivti3.c +++ /dev/null @@ -1,14 +0,0 @@ -#if 0 -/*─────────────────────────────────────────────────────────────────╗ -│ To the extent possible under law, Justine Tunney has waived │ -│ all copyright and related or neighboring rights to division, │ -│ as it is written in the following disclaimers: │ -│ • http://unlicense.org/ │ -│ • http://creativecommons.org/publicdomain/zero/1.0/ │ -╚─────────────────────────────────────────────────────────────────*/ -#endif -#include "third_party/compiler_rt/int_lib.h" - -COMPILER_RT_ABI tu_int __udivti3(tu_int a, tu_int b) { - return __udivmodti4(a, b, NULL); -} diff --git a/libc/intrin/unmorton.c b/libc/intrin/unmorton.c deleted file mode 100644 index 9c1e3ab84..000000000 --- a/libc/intrin/unmorton.c +++ /dev/null @@ -1,41 +0,0 @@ -/*-*- 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 2020 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/intrin/morton.h" - -static unsigned long GetOddBits(unsigned long x) { - x = (x | x >> 000) & 0x5555555555555555; - x = (x | x >> 001) & 0x3333333333333333; - x = (x | x >> 002) & 0x0F0F0F0F0F0F0F0F; - x = (x | x >> 004) & 0x00FF00FF00FF00FF; - x = (x | x >> 010) & 0x0000FFFF0000FFFF; - x = (x | x >> 020) & 0x00000000FFFFFFFF; - return x; -} - -/** - * Deinterleaves bits. - * - * @param 𝑖 is interleaved index - * @return deinterleaved coordinate {ax := 𝑦, dx := 𝑥} - * @see en.wikipedia.org/wiki/Z-order_curve - * @see morton() - */ -axdx_t unmorton(unsigned long i) { - return (axdx_t){GetOddBits(i >> 1), GetOddBits(i)}; -} diff --git a/libc/intrin/x86gradenames.c b/libc/intrin/x86gradenames.c deleted file mode 100644 index 98d012df5..000000000 --- a/libc/intrin/x86gradenames.c +++ /dev/null @@ -1,33 +0,0 @@ -/*-*- 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 2020 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/nexgen32e/x86info.h" -#include "tool/decode/lib/x86idnames.h" - -const struct IdName kX86GradeNames[] = { - {X86_GRADE_UNKNOWN, "Unknown"}, // - {X86_GRADE_APPLIANCE, "Appliance"}, // - {X86_GRADE_MOBILE, "Mobile"}, // - {X86_GRADE_TABLET, "Tablet"}, // - {X86_GRADE_DESKTOP, "Desktop"}, // - {X86_GRADE_CLIENT, "Client"}, // - {X86_GRADE_DENSITY, "Density"}, // - {X86_GRADE_SERVER, "Server"}, // - {X86_GRADE_SCIENCE, "Science"}, // - {0}, // -}; diff --git a/libc/intrin/x86marchnames.c b/libc/intrin/x86names.c similarity index 86% rename from libc/intrin/x86marchnames.c rename to libc/intrin/x86names.c index 42b29fb45..43aad86e0 100644 --- a/libc/intrin/x86marchnames.c +++ b/libc/intrin/x86names.c @@ -19,6 +19,19 @@ #include "libc/nexgen32e/x86info.h" #include "tool/decode/lib/x86idnames.h" +const struct IdName kX86GradeNames[] = { + {X86_GRADE_UNKNOWN, "Unknown"}, // + {X86_GRADE_APPLIANCE, "Appliance"}, // + {X86_GRADE_MOBILE, "Mobile"}, // + {X86_GRADE_TABLET, "Tablet"}, // + {X86_GRADE_DESKTOP, "Desktop"}, // + {X86_GRADE_CLIENT, "Client"}, // + {X86_GRADE_DENSITY, "Density"}, // + {X86_GRADE_SERVER, "Server"}, // + {X86_GRADE_SCIENCE, "Science"}, // + {0}, // +}; + const struct IdName kX86MarchNames[] = { {X86_MARCH_UNKNOWN, "Unknown"}, // {X86_MARCH_CORE2, "Core 2"}, // diff --git a/libc/isystem/cosmo.h b/libc/isystem/cosmo.h index b7c59d184..0eb3bcdc2 100644 --- a/libc/isystem/cosmo.h +++ b/libc/isystem/cosmo.h @@ -29,6 +29,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/elf/elf.h" #include "libc/fmt/itoa.h" diff --git a/libc/mem/arena.c b/libc/mem/arena.c deleted file mode 100644 index 7bb14cb8e..000000000 --- a/libc/mem/arena.c +++ /dev/null @@ -1,356 +0,0 @@ -/*-*- 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/mem/arena.h" -#include "libc/assert.h" -#include "libc/calls/calls.h" -#include "libc/dce.h" -#include "libc/intrin/bsf.h" -#include "libc/intrin/bsr.h" -#include "libc/intrin/likely.h" -#include "libc/intrin/weaken.h" -#include "libc/limits.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/mem/hook.internal.h" -#include "libc/runtime/memtrack.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/stdckdint.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/prot.h" -#include "libc/sysv/errfuns.h" - -#define BASE 0x50040000 -#define SIZE 0x2ff80000 -#define P(i) ((void *)(intptr_t)(i)) -#define EXCHANGE(HOOK, SLOT) \ - __arena_hook((intptr_t *)_weaken(HOOK), (intptr_t *)(&(SLOT))) - -static struct Arena { - bool once; - size_t size; - size_t depth; - size_t offset[16]; - void (*free)(void *); - void *(*malloc)(size_t); - void *(*calloc)(size_t, size_t); - void *(*memalign)(size_t, size_t); - void *(*realloc)(void *, size_t); - void *(*realloc_in_place)(void *, size_t); - size_t (*malloc_usable_size)(const void *); - size_t (*bulk_free)(void *[], size_t); - int (*malloc_trim)(size_t); -} __arena; - -static wontreturn void __arena_die(void) { - if (_weaken(__die)) _weaken(__die)(); - _exit(83); -} - -forceinline void __arena_check(void) { - unassert(__arena.depth); -} - -forceinline void __arena_check_pointer(void *p) { - unassert(BASE + __arena.offset[__arena.depth - 1] <= (uintptr_t)p && - (uintptr_t)p < BASE + __arena.offset[__arena.depth]); -} - -forceinline bool __arena_is_arena_pointer(void *p) { - return BASE <= (uintptr_t)p && (uintptr_t)p < BASE + SIZE; -} - -forceinline size_t __arena_get_size(void *p) { - return *(const size_t *)((const char *)p - sizeof(size_t)); -} - -static void __arena_free(void *p) { - __arena_check(); - if (p) { - __arena_check_pointer(p); - if (!(BASE <= (uintptr_t)p && (uintptr_t)p < BASE + SIZE)) { - __arena.free(p); - } - } -} - -static size_t __arena_bulk_free(void *p[], size_t n) { - size_t i; - for (i = 0; i < n; ++i) { - __arena_free(p[i]); - p[i] = 0; - } - return 0; -} - -static dontinline bool __arena_grow(size_t offset, size_t request) { - size_t greed; - greed = __arena.size + 1; - do { - greed += greed >> 1; - greed = ROUNDUP(greed, FRAMESIZE); - } while (greed < offset + request); - if (greed <= SIZE) { - if (mmap(P(BASE + __arena.size), greed - __arena.size, - PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, - -1, 0) != MAP_FAILED) { - __arena.size = greed; - return true; - } - } else { - enomem(); - } - if (_weaken(__oom_hook)) { - _weaken(__oom_hook)(request); - } - return false; -} - -static inline void *__arena_alloc(size_t a, size_t n) { - size_t o; - if (!n) n = 1; - o = ROUNDUP(__arena.offset[__arena.depth] + sizeof(size_t), a); - if (o + n >= n) { - if (n <= sizeof(size_t)) { - n = sizeof(size_t); - } else { - n = ROUNDUP(n, sizeof(size_t)); - } - if (o + n <= SIZE) { - if (UNLIKELY(o + n > __arena.size)) { - if (!__arena_grow(o, n)) return 0; - } - __arena.offset[__arena.depth] = o + n; - *(size_t *)(BASE + o - sizeof(size_t)) = n; - return (void *)(BASE + o); - } - } - enomem(); - return 0; -} - -static void *__arena_malloc(size_t n) { - __arena_check(); - return __arena_alloc(16, n); -} - -static void *__arena_calloc(size_t n, size_t z) { - __arena_check(); - if (ckd_mul(&n, n, z)) n = -1; - return __arena_alloc(16, n); -} - -static void *__arena_memalign(size_t a, size_t n) { - __arena_check(); - if (a <= sizeof(size_t)) { - return __arena_alloc(8, n); - } else { - return __arena_alloc(2ul << _bsrl(a - 1), n); - } -} - -static size_t __arena_malloc_usable_size(const void *p) { - __arena_check(); - __arena_check_pointer(p); - if (__arena_is_arena_pointer(p)) { - return __arena_get_size(p); - } else { - return __arena.malloc_usable_size(p); - } -} - -static void *__arena_realloc(void *p, size_t n) { - char *q; - size_t m, o, z; - __arena_check(); - if (p) { - __arena_check_pointer(p); - if (__arena_is_arena_pointer(p)) { - if (n) { - if ((m = __arena_get_size(p)) >= n) { - return p; - } else if (n <= SIZE) { - z = 2ul << _bsrl(n - 1); - if (__arena.offset[__arena.depth] - m == (o = (intptr_t)p - BASE)) { - if (UNLIKELY(o + z > __arena.size)) { - if (o + z <= SIZE) { - if (!__arena_grow(o, z)) { - return 0; - } - } else { - enomem(); - return 0; - } - } - __arena.offset[__arena.depth] = o + z; - *(size_t *)((char *)p - sizeof(size_t)) = z; - return p; - } else if ((q = __arena_alloc(1ul << _bsfl((intptr_t)p), z))) { - memmove(q, p, m); - return q; - } else { - return 0; - } - } else { - enomem(); - return 0; - } - } else { - return 0; - } - } else { - return __arena.realloc(p, n); - } - } else { - if (n <= 16) { - n = 16; - } else { - n = 2ul << _bsrl(n - 1); - } - return __arena_alloc(16, n); - } -} - -static void *__arena_realloc_in_place(void *p, size_t n) { - char *q; - size_t m, z; - __arena_check(); - if (p) { - __arena_check_pointer(p); - if (__arena_is_arena_pointer(p)) { - if (n) { - if ((m = __arena_get_size(p)) >= n) { - return p; - } else { - return 0; - } - } else { - return 0; - } - } else { - return __arena.realloc_in_place(p, n); - } - } else { - return 0; - } -} - -static int __arena_malloc_trim(size_t n) { - return 0; -} - -static void __arena_hook(intptr_t *h, intptr_t *f) { - intptr_t t; - if (h) { - t = *h; - *h = *f; - *f = t; - } -} - -static void __arena_install(void) { - EXCHANGE(hook_free, __arena.free); - EXCHANGE(hook_malloc, __arena.malloc); - EXCHANGE(hook_calloc, __arena.calloc); - EXCHANGE(hook_realloc, __arena.realloc); - EXCHANGE(hook_memalign, __arena.memalign); - EXCHANGE(hook_bulk_free, __arena.bulk_free); - EXCHANGE(hook_malloc_trim, __arena.malloc_trim); - EXCHANGE(hook_realloc_in_place, __arena.realloc_in_place); - EXCHANGE(hook_malloc_usable_size, __arena.malloc_usable_size); -} - -static void __arena_destroy(void) { - if (__arena.depth) __arena_install(); - if (__arena.size) munmap(P(BASE), __arena.size); - bzero(&__arena, sizeof(__arena)); -} - -static void __arena_init(void) { - __arena.free = __arena_free; - __arena.malloc = __arena_malloc; - __arena.calloc = __arena_calloc; - __arena.realloc = __arena_realloc; - __arena.memalign = __arena_memalign; - __arena.bulk_free = __arena_bulk_free; - __arena.malloc_trim = __arena_malloc_trim; - __arena.realloc_in_place = __arena_realloc_in_place; - __arena.malloc_usable_size = __arena_malloc_usable_size; - atexit(__arena_destroy); -} - -/** - * Pushes memory arena. - * - * This allocator gives a ~3x performance boost over dlmalloc, mostly - * because it isn't thread safe and it doesn't do defragmentation. - * - * Calling this function will push a new arena. It may be called - * multiple times from the main thread recursively. The first time it's - * called, it hooks all the regular memory allocation functions. Any - * allocations that were made previously outside the arena, will be - * passed on to the previous hooks. Then, the basic idea, is rather than - * bothering with free() you can just call __arena_pop() to bulk free. - * - * Arena allocations also have a slight size advantage, since 32-bit - * pointers are always used. The maximum amount of arena memory is - * 805,175,296 bytes. - * - * @see __arena_pop() - */ -void __arena_push(void) { - if (UNLIKELY(!__arena.once)) { - __arena_init(); - __arena.once = true; - } - if (!__arena.depth) { - __arena_install(); - } else { - unassert(__arena.depth < ARRAYLEN(__arena.offset) - 1); - } - __arena.offset[__arena.depth + 1] = __arena.offset[__arena.depth]; - ++__arena.depth; -} - -/** - * Pops memory arena. - * - * This pops the most recently created arena, freeing all the memory - * that was allocated between the push and pop arena calls. If this is - * the last arena on the stack, then the old malloc hooks are restored. - * - * @see __arena_push() - */ -void __arena_pop(void) { - size_t a, b, greed; - __arena_check(); - if (!--__arena.depth) __arena_install(); - a = __arena.offset[__arena.depth]; - b = __arena.offset[__arena.depth + 1]; - greed = a; - greed += FRAMESIZE; - greed <<= 1; - if (__arena.size > greed) { - munmap(P(BASE + greed), __arena.size - greed); - __arena.size = greed; - b = MIN(b, greed); - a = MIN(b, a); - } - bzero(P(BASE + a), b - a); -} diff --git a/libc/mem/arena.h b/libc/mem/arena.h deleted file mode 100644 index 404fecfe4..000000000 --- a/libc/mem/arena.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_MEM_ARENA_H_ -#define COSMOPOLITAN_LIBC_MEM_ARENA_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -void __arena_push(void); -void __arena_pop(void); - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_MEM_ARENA_H_ */ diff --git a/libc/mem/free.c b/libc/mem/free.c index c88786a4d..ed9864d6a 100644 --- a/libc/mem/free.c +++ b/libc/mem/free.c @@ -27,9 +27,7 @@ void (*hook_free)(void *) = dlfree; * * Releases the chunk of memory pointed to by p, that had been * previously allocated using malloc or a related routine such as - * realloc. It has no effect if p is null. If p was not malloced or - * already freed, free(p) will by default cause the current program to - * abort. + * realloc. It has no effect if p is null. * * @param p is allocation address, which may be NULL * @see dlfree() diff --git a/libc/mem/malloc.c b/libc/mem/malloc.c index 635473c01..a527e1361 100644 --- a/libc/mem/malloc.c +++ b/libc/mem/malloc.c @@ -30,11 +30,14 @@ void *(*hook_malloc)(size_t) = dlmalloc; * on ANSI C systems. * * If n is zero, malloc returns a minimum-sized chunk. (The minimum size - * is 32 bytes on 64bit systems.) Note that size_t is an unsigned type, - * so calls with arguments that would be negative if signed are - * interpreted as requests for huge amounts of space, which will often - * fail. The maximum supported value of n differs across systems, but is - * in all cases less than the maximum representable value of a size_t. + * is 32 bytes on 64bit systems.) It should be assumed that zero bytes + * are possible access, since that'll be enforced by `MODE=asan`. + * + * Note that size_t is an unsigned type, so calls with arguments that + * would be negative if signed are interpreted as requests for huge + * amounts of space, which will often fail. The maximum supported value + * of n differs across systems, but is in all cases less than the + * maximum representable value of a size_t. * * @param rdi is number of bytes needed, coerced to 1+ * @return new memory, or NULL w/ errno diff --git a/libc/mem/pvalloc.c b/libc/mem/pvalloc.c index bb82626d4..4ee636b4f 100644 --- a/libc/mem/pvalloc.c +++ b/libc/mem/pvalloc.c @@ -16,8 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.internal.h" +#include "libc/errno.h" #include "libc/mem/mem.h" +#include "libc/stdckdint.h" /** * Allocates granular aligned memory of granular size, i.e. @@ -31,5 +32,9 @@ * @threadsafe */ void *pvalloc(size_t n) { - return memalign(FRAMESIZE, ROUNDUP(n, FRAMESIZE)); + if (ckd_add(&n, n, FRAMESIZE - 1)) { + errno = ENOMEM; + return 0; + } + return memalign(FRAMESIZE, n & -FRAMESIZE); } diff --git a/libc/mem/realloc.c b/libc/mem/realloc.c index e00b1b4aa..9e9609c7b 100644 --- a/libc/mem/realloc.c +++ b/libc/mem/realloc.c @@ -29,8 +29,12 @@ void *(*hook_realloc)(void *, size_t) = dlrealloc; * does chunk p up to the minimum of (n, p's size) bytes, or null if no * space is available. * - * If p is NULL, realloc is equivalent to malloc. - * If p is not NULL and n is 0, realloc is equivalent to free. + * If p is NULL, then realloc() is equivalent to malloc(). + * + * If p is not NULL and n is 0, then realloc() shrinks the allocation to + * zero bytes. The allocation isn't freed and still continues to be a + * uniquely allocated piece of memory. However it should be assumed that + * zero bytes can be accessed, since that's enforced by `MODE=asan`. * * The returned pointer may or may not be the same as p. The algorithm * prefers extending p in most cases when possible, otherwise it employs @@ -54,8 +58,6 @@ void *(*hook_realloc)(void *, size_t) = dlrealloc; * @param p is address of current allocation or NULL * @param n is number of bytes needed * @return rax is result, or NULL w/ errno w/o free(p) - * @note realloc(p=0, n=0) → malloc(32) - * @note realloc(p≠0, n=0) → free(p) * @see dlrealloc() * @threadsafe */ diff --git a/libc/mem/strndup.c b/libc/mem/strndup.c index 382b57da1..39f4bc116 100644 --- a/libc/mem/strndup.c +++ b/libc/mem/strndup.c @@ -32,7 +32,7 @@ char *strndup(const char *s, size_t n) { char *s2; size_t len = strnlen(s, n); if ((s2 = malloc(len + 1))) { - memcpy(s2, s, len); + if (len) memcpy(s2, s, len); s2[len] = '\0'; return s2; } diff --git a/libc/nt/ipc.h b/libc/nt/ipc.h index 3fce3fd1e..356499c4e 100644 --- a/libc/nt/ipc.h +++ b/libc/nt/ipc.h @@ -85,6 +85,11 @@ bool32 TransactNamedPipe(int64_t hNamedPipe, void *lpInBuffer, uint32_t nOutBufferSize, uint32_t *lpBytesRead, struct NtOverlapped *lpOverlapped); +bool32 GetNamedPipeInfo(int64_t hNamedPipe, uint32_t *opt_out_lpFlags, + uint32_t *opt_out_lpOutBufferSize, + uint32_t *opt_out_lpInBufferSize, + uint32_t *opt_out_lpMaxInstances); + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_NT_IPC_H_ */ diff --git a/libc/nt/kernel32/GetNamedPipeInfo.S b/libc/nt/kernel32/GetNamedPipeInfo.S new file mode 100644 index 000000000..275043c27 --- /dev/null +++ b/libc/nt/kernel32/GetNamedPipeInfo.S @@ -0,0 +1,18 @@ +#include "libc/nt/codegen.h" +.imp kernel32,__imp_GetNamedPipeInfo,GetNamedPipeInfo + + .text.windows + .ftrace1 +GetNamedPipeInfo: + .ftrace2 +#ifdef __x86_64__ + push %rbp + mov %rsp,%rbp + mov __imp_GetNamedPipeInfo(%rip),%rax + jmp __sysv2nt6 +#elif defined(__aarch64__) + mov x0,#0 + ret +#endif + .endfn GetNamedPipeInfo,globl + .previous diff --git a/libc/nt/master.sh b/libc/nt/master.sh index a0e16c319..7face4b32 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -93,6 +93,7 @@ imp 'GetModuleFileName' GetModuleFileNameW kernel32 3 imp 'GetModuleHandle' GetModuleHandleA kernel32 1 imp 'GetModuleHandleEx' GetModuleHandleExW kernel32 3 imp 'GetModuleHandleW' GetModuleHandleW kernel32 1 +imp 'GetNamedPipeInfo' GetNamedPipeInfo kernel32 5 imp 'GetNumberOfConsoleInputEvents' GetNumberOfConsoleInputEvents kernel32 2 imp 'GetNumberOfConsoleMouseButtons' GetNumberOfConsoleMouseButtons kernel32 1 imp 'GetOverlappedResult' GetOverlappedResult kernel32 4 @@ -246,8 +247,8 @@ imp 'VirtualAlloc' VirtualAlloc kernel32 4 imp 'VirtualAllocEx' VirtualAllocEx kernel32 5 imp 'VirtualFree' VirtualFree kernel32 3 imp 'VirtualLock' VirtualLock kernel32 2 -imp 'VirtualUnlock' VirtualUnlock kernel32 2 imp 'VirtualQuery' VirtualQuery kernel32 3 +imp 'VirtualUnlock' VirtualUnlock kernel32 2 imp 'WaitForMultipleObjectsEx' WaitForMultipleObjectsEx kernel32 5 imp 'WaitForSingleObjectEx' WaitForSingleObjectEx kernel32 3 imp 'WideCharToMultiByte' WideCharToMultiByte kernel32 8 diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index 860e77d1e..2df2e2a30 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -644,7 +644,7 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg, if (!func) { rc = EINVAL; } else if (!IsTiny() && - ((flags & CLONE_VM) && (stksz < PAGESIZE || (stksz & 15)))) { + ((flags & CLONE_VM) && (stksz < 4096 || (stksz & 15)))) { rc = EINVAL; } else if (IsAsan() && (((flags & CLONE_SETTLS) && !__asan_is_valid(tls, 64)) || diff --git a/libc/runtime/cosmo2.c b/libc/runtime/cosmo2.c index 5df560666..816bf089c 100644 --- a/libc/runtime/cosmo2.c +++ b/libc/runtime/cosmo2.c @@ -148,7 +148,7 @@ textstartup void cosmo(long *sp, struct Syslib *m1) { #endif // initialize file system - __init_fds(); + __init_fds(argc, argv, envp); // set helpful globals __argc = argc; diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index ea7bf1a07..245ebdb6f 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -102,11 +102,11 @@ textstartup void __enable_tls(void) { // Here's the layout we're currently using: // - // .balign PAGESIZE + // .balign 4096 // _tdata_start: // .tdata // _tdata_size = . - _tdata_start - // .balign PAGESIZE + // .balign 4096 // _tbss_start: // _tdata_start + _tbss_offset: // .tbss diff --git a/libc/runtime/fork-nt.c b/libc/runtime/fork-nt.c index 42fe50e14..2904b3d09 100644 --- a/libc/runtime/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -52,6 +52,7 @@ #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" +#include "libc/sock/internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" @@ -68,7 +69,9 @@ bool32 __onntconsoleevent_nt(uint32_t); void kmalloc_unlock(void); static textwindows wontreturn void AbortFork(const char *func) { - STRACE("fork() %s() failed %d", func, GetLastError()); +#ifdef SYSDEBUG + kprintf("fork() %s() failed with win32 error %d\n", func, GetLastError()); +#endif ExitProcess(177); } @@ -104,7 +107,15 @@ static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n, } static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) { - return ForkIo2(h, buf, n, WriteFile, "WriteFile", false); + bool ok; + ok = ForkIo2(h, buf, n, WriteFile, "WriteFile", false); +#ifdef SYSDEBUG + if (!ok) { + kprintf("failed to write %zu bytes to forked child: %d\n", n, + GetLastError()); + } +#endif + return ok; } static textwindows dontinline void ReadOrDie(int64_t h, void *buf, size_t n) { @@ -320,8 +331,13 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { } for (i = 0; i < _mmi.i && ok; ++i) { if ((_mmi.p[i].flags & MAP_TYPE) != MAP_SHARED) { - ok = WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16), - _mmi.p[i].size); + uint32_t op; + char *p = (char *)((uint64_t)_mmi.p[i].x << 16); + // XXX: forking destroys thread guard pages currently + VirtualProtect( + p, _mmi.p[i].size, + __prot2nt(_mmi.p[i].prot | PROT_READ, _mmi.p[i].iscow), &op); + ok = WriteAll(writer, p, _mmi.p[i].size); } } if (ok) ok = WriteAll(writer, __data_start, __data_end - __data_start); diff --git a/libc/runtime/internal.h b/libc/runtime/internal.h index 966e2feca..73405c47b 100644 --- a/libc/runtime/internal.h +++ b/libc/runtime/internal.h @@ -51,7 +51,7 @@ int __inflate(void *, size_t, const void *, size_t); void *_Mmap(void *, size_t, int, int, int, int64_t) dontasan; int _Munmap(char *, size_t) dontasan; void __on_arithmetic_overflow(void); -void __init_fds(void); +void __init_fds(int, char **, char **); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h index f2fc9f30a..c22236757 100644 --- a/libc/runtime/memtrack.internal.h +++ b/libc/runtime/memtrack.internal.h @@ -141,10 +141,6 @@ forceinline pureconst bool IsShadowFrame(int x) { return 0x7fff <= x && x < 0x10008000; } -forceinline pureconst bool IsArenaFrame(int x) { - return 0x5004 <= x && x <= 0x7ffb; -} - forceinline pureconst bool IsStaticStackFrame(int x) { intptr_t stack = GetStaticStackAddr(0); return (int)(stack >> 16) <= x && @@ -192,19 +188,6 @@ forceinline pureconst bool OverlapsImageSpace(const void *p, size_t n) { } } -forceinline pureconst bool OverlapsArenaSpace(const void *p, size_t n) { - intptr_t BegA, EndA, BegB, EndB; - if (n) { - BegA = (intptr_t)p; - EndA = BegA + (n - 1); - BegB = 0x50000000; - EndB = 0x7ffdffff; - return MAX(BegA, BegB) < MIN(EndA, EndB); - } else { - return 0; - } -} - forceinline pureconst bool OverlapsShadowSpace(const void *p, size_t n) { intptr_t BegA, EndA, BegB, EndB; if (n) { diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c index 6164c63b7..5dc363366 100644 --- a/libc/runtime/mmap.c +++ b/libc/runtime/mmap.c @@ -245,9 +245,10 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { char *p = addr; struct DirectMap dm; + size_t requested_size; int a, b, i, f, m, n, x; bool needguard, clashes; - unsigned long guardsize; + unsigned long page_size; size_t virtualused, virtualneed; if (VERY_UNLIKELY(!size)) { @@ -274,11 +275,12 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, flags = MAP_SHARED; // cf. MAP_SHARED_VALIDATE } + requested_size = size; + page_size = getauxval(AT_PAGESZ); if (flags & MAP_ANONYMOUS) { fd = -1; off = 0; size = ROUNDUP(size, FRAMESIZE); - if (IsWindows()) prot |= PROT_WRITE; // kludge if ((flags & MAP_TYPE) == MAP_FILE) { STRACE("need MAP_PRIVATE or MAP_SHARED"); return VIP(einval()); @@ -289,8 +291,8 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, } else if (VERY_UNLIKELY(off < 0)) { STRACE("mmap negative offset"); return VIP(einval()); - } else if (VERY_UNLIKELY(!ALIGNED(off))) { - STRACE("mmap off isn't 64kb aligned"); + } else if (off & ((IsWindows() ? FRAMESIZE : page_size) - 1)) { + STRACE("mmap offset isn't properly aligned"); return VIP(einval()); } else if (VERY_UNLIKELY(INT64_MAX - size < off)) { STRACE("mmap too large"); @@ -326,8 +328,7 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, OnUnrecoverableMmapError("FIXED UNTRACK FAILED"); } } - } else if (p && !clashes && !OverlapsArenaSpace(p, size) && - !OverlapsShadowSpace(p, size)) { + } else if (p && !clashes && !OverlapsShadowSpace(p, size)) { x = FRAME(p); } else if (!Automap(n, a, &x)) { STRACE("automap has no room for %d frames with %d alignment", n, a); @@ -335,7 +336,6 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, } needguard = false; - guardsize = getauxval(AT_PAGESZ); p = (char *)ADDR_32_TO_48(x); if ((f & MAP_TYPE) == MAP_STACK) { if (~f & MAP_ANONYMOUS) { @@ -374,11 +374,15 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, if ((dm = sys_mmap(p + size - SIGSTKSZ, SIGSTKSZ, prot, f | MAP_GROWSDOWN_linux, fd, off)) .addr != MAP_FAILED) { - npassert(sys_mmap(p, guardsize, PROT_NONE, + npassert(sys_mmap(p, page_size, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) .addr == p); dm.addr = p; - return FinishMemory(p, size, prot, flags, fd, off, f, x, n, dm); + p = FinishMemory(p, size, prot, flags, fd, off, f, x, n, dm); + if (IsAsan() && p != MAP_FAILED) { + __asan_poison(p, page_size, kAsanStackOverflow); + } + return p; } else if (errno == ENOTSUP) { // WSL doesn't support MAP_GROWSDOWN needguard = true; @@ -399,14 +403,14 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, } if (p != MAP_FAILED) { + if (IsAsan()) { + __asan_poison(p + requested_size, size - requested_size, + kAsanMmapSizeOverrun); + } if (needguard) { - if (!IsWindows()) { - // make windows fork() code simpler - mprotect(p, guardsize, PROT_NONE); - } + unassert(!mprotect(p, page_size, PROT_NONE)); if (IsAsan()) { - __repstosb((void *)(((intptr_t)p >> 3) + 0x7fff8000), - kAsanStackOverflow, guardsize / 8); + __asan_poison(p, page_size, kAsanStackOverflow); } } } @@ -415,7 +419,7 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, } /** - * Beseeches system for page-table entries, e.g. + * Creates virtual memory, e.g. * * char *m; * m = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE, @@ -430,9 +434,7 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, * needs to be made mandatory because of Windows although you can * use __sys_mmap() to circumvent it on System Five in which case * runtime support services, e.g. asan memory safety, could break - * @param size must be >0 and needn't be a multiple of FRAMESIZE, but - * will be rounded up to FRAMESIZE automatically if MAP_ANONYMOUS - * is specified + * @param size must be >0 otherwise EINVAL is raised * @param prot can have PROT_READ/PROT_WRITE/PROT_EXEC/PROT_NONE/etc. * @param flags should have one of the following masked by `MAP_TYPE` * - `MAP_FILE` in which case `MAP_ANONYMOUS` shouldn't be used @@ -459,8 +461,8 @@ dontasan inline void *_Mmap(void *addr, size_t size, int prot, int flags, * @param fd is an open()'d file descriptor, whose contents shall be * made available w/ automatic reading at the chosen address * @param off specifies absolute byte index of fd's file for mapping, - * should be zero if MAP_ANONYMOUS is specified, and sadly needs - * to be 64kb aligned too + * should be zero if MAP_ANONYMOUS is specified, which SHOULD be + * aligned to FRAMESIZE * @return virtual base address of new mapping, or MAP_FAILED w/ errno */ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { diff --git a/libc/runtime/mprotect-nt.greg.c b/libc/runtime/mprotect-nt.greg.c index 18acb25b0..23071dc6c 100644 --- a/libc/runtime/mprotect-nt.greg.c +++ b/libc/runtime/mprotect-nt.greg.c @@ -27,6 +27,7 @@ textwindows int sys_mprotect_nt(void *addr, size_t size, int prot) { uint32_t op; char *a, *b, *x, *y, *p; __mmi_lock(); + size = (size + 4095) & -4096; p = addr; i = FindMemoryInterval(&_mmi, (intptr_t)p >> 16); if (i == _mmi.i || (!i && p + size <= (char *)ADDR_32_TO_48(_mmi.p[0].x))) { @@ -41,9 +42,14 @@ textwindows int sys_mprotect_nt(void *addr, size_t size, int prot) { // we unfortunately must do something similar to this for cow for (; i < _mmi.i; ++i) { x = (char *)ADDR_32_TO_48(_mmi.p[i].x); - y = x + _mmi.p[i].size; + y = (char *)ADDR_32_TO_48(_mmi.p[i].y) + 65536; if ((x <= p && p < y) || (x < p + size && p + size <= y) || (p < x && y < p + size)) { + if (p <= x && p + size >= y) { + _mmi.p[i].prot = prot; + } else { + _mmi.p[i].prot |= prot; + } a = MIN(MAX(p, x), y); b = MAX(MIN(p + size, y), x); if (!VirtualProtect(a, b - a, __prot2nt(prot, _mmi.p[i].iscow), &op)) { diff --git a/libc/runtime/mprotect.c b/libc/runtime/mprotect.c index 10081a82b..b3be7d50d 100644 --- a/libc/runtime/mprotect.c +++ b/libc/runtime/mprotect.c @@ -23,6 +23,8 @@ #include "libc/intrin/likely.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" @@ -41,7 +43,7 @@ int mprotect(void *addr, size_t size, int prot) { rc = einval(); // unix checks prot before checking size } else if (!size) { return 0; // make new technology consistent with unix - } else if (UNLIKELY((intptr_t)addr & 4095)) { + } else if (UNLIKELY((intptr_t)addr & (getauxval(AT_PAGESZ) - 1))) { rc = einval(); // unix checks prot before checking size } else if (!IsWindows()) { rc = sys_mprotect(addr, size, prot); diff --git a/libc/sock/accept.c b/libc/sock/accept.c index ae2be472b..e217813a3 100644 --- a/libc/sock/accept.c +++ b/libc/sock/accept.c @@ -23,13 +23,14 @@ * Creates client socket file descriptor for incoming connection. * * @param fd is the server socket file descriptor - * @param out_addr will receive the remote address - * @param inout_addrsize provides and receives addr's byte length + * @param opt_out_addr will receive the remote address + * @param opt_inout_addrsize provides and receives addr's byte length * @return client fd which needs close(), or -1 w/ errno * @cancellationpoint * @asyncsignalsafe * @restartable (unless SO_RCVTIMEO) */ -int accept(int fd, struct sockaddr *out_addr, uint32_t *inout_addrsize) { - return accept4(fd, out_addr, inout_addrsize, 0); +int accept(int fd, struct sockaddr *opt_out_addr, + uint32_t *opt_inout_addrsize) { + return accept4(fd, opt_out_addr, opt_inout_addrsize, 0); } diff --git a/libc/sock/accept4.c b/libc/sock/accept4.c index 2b16a42ef..4014691be 100644 --- a/libc/sock/accept4.c +++ b/libc/sock/accept4.c @@ -32,8 +32,8 @@ * Creates client socket file descriptor for incoming connection. * * @param fd is the server socket file descriptor - * @param out_addr will receive the remote address - * @param inout_addrsize provides and receives out_addr's byte length + * @param opt_out_addr will receive the remote address + * @param opt_inout_addrsize provides and receives out_addr's byte length * @param flags can have SOCK_{CLOEXEC,NONBLOCK}, which may apply to * both the newly created socket and the server one * @return client fd which needs close(), or -1 w/ errno @@ -41,7 +41,7 @@ * @asyncsignalsafe * @restartable (unless SO_RCVTIMEO) */ -int accept4(int fd, struct sockaddr *out_addr, uint32_t *inout_addrsize, +int accept4(int fd, struct sockaddr *opt_out_addr, uint32_t *opt_inout_addrsize, int flags) { int rc; struct sockaddr_storage ss = {0}; @@ -61,11 +61,13 @@ int accept4(int fd, struct sockaddr *out_addr, uint32_t *inout_addrsize, if (IsBsd()) { __convert_bsd_to_sockaddr(&ss); } - __write_sockaddr(&ss, out_addr, inout_addrsize); + __write_sockaddr(&ss, opt_out_addr, opt_inout_addrsize); } END_CANCELLATION_POINT; STRACE("accept4(%d, [%s]) -> %d% lm", fd, - DescribeSockaddr(out_addr, inout_addrsize ? *inout_addrsize : 0), rc); + DescribeSockaddr(opt_out_addr, + opt_inout_addrsize ? *opt_inout_addrsize : 0), + rc); return rc; } diff --git a/libc/sock/bind-nt.c b/libc/sock/bind-nt.c index dfc336bfa..21565c183 100644 --- a/libc/sock/bind-nt.c +++ b/libc/sock/bind-nt.c @@ -17,15 +17,14 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" +#include "libc/calls/struct/fd.internal.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" #include "libc/sock/syscall_fd.internal.h" -#include "libc/sock/yoink.inc" -#include "libc/sysv/errfuns.h" textwindows int sys_bind_nt(struct Fd *fd, const void *addr, uint32_t addrsize) { - npassert(fd->kind == kFdSocket); + unassert(fd->kind == kFdSocket); if (__sys_bind_nt(fd->handle, addr, addrsize) != -1) { return 0; } else { diff --git a/libc/sock/bind.c b/libc/sock/bind.c index c7a68f878..48518a09a 100644 --- a/libc/sock/bind.c +++ b/libc/sock/bind.c @@ -32,7 +32,11 @@ * * struct sockaddr_in in = {AF_INET, htons(12345), {htonl(0x7f000001)}}; * int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - * bind(fd, &in, sizeof(in)); + * bind(fd, (struct sockaddr *)&in, sizeof(in)); + * + * On Windows, Cosmopolitan's implementation of bind() takes care of + * always setting the WIN32-specific `SO_EXCLUSIVEADDRUSE` option on + * inet stream sockets in order to safeguard your servers from tests * * @param fd is the file descriptor returned by socket() * @param addr is usually the binary-encoded ip:port on which to listen diff --git a/libc/sock/sockdebug.c b/libc/sock/sockdebug.c index 970ff4fe6..bf74ee730 100644 --- a/libc/sock/sockdebug.c +++ b/libc/sock/sockdebug.c @@ -65,7 +65,7 @@ const char *(DescribeSockaddr)(char buf[128], const struct sockaddr *sa, unix = (const struct sockaddr_un *)sa; n = strnlen(unix->sun_path, sizeof(unix->sun_path)); n = MIN(n, 128 - 1); - memcpy(buf, unix->sun_path, n); + if (n) memcpy(buf, unix->sun_path, n); buf[n] = 0; } } diff --git a/libc/sock/socket-nt.c b/libc/sock/socket-nt.c index 977a37db8..add1f2bb7 100644 --- a/libc/sock/socket-nt.c +++ b/libc/sock/socket-nt.c @@ -16,14 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" #include "libc/mem/mem.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/iphlpapi.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" #include "libc/sock/yoink.inc" +#include "libc/str/str.h" +#include "libc/sysv/consts/af.h" #include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/so.h" @@ -42,13 +47,22 @@ __static_yoink("_dupsockfd"); textwindows int sys_socket_nt(int family, int type, int protocol) { int64_t h; struct SockFd *sockfd; - int fd, oflags, truetype; + int fd, oflags, truetype, yes = 1; fd = __reservefd(-1); if (fd == -1) return -1; truetype = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); if ((h = WSASocket(family, truetype, protocol, NULL, 0, kNtWsaFlagOverlapped)) != -1) { - oflags = 0; + + // sets SO_EXCLUSIVEADDRUSE on all sockets so they won't get pilfered + // you can read a blog post on this subject in the find_unused_port() + // pydoc of this file third_party/python/Lib/test/support/__init__.py + // this needs to happen right after socket is called or it won't work + if (family == AF_INET || family == AF_INET6) { + unassert(__sys_setsockopt_nt(h, SOL_SOCKET, -5, &yes, 4) != -1); + } + + oflags = O_RDWR; if (type & SOCK_CLOEXEC) oflags |= O_CLOEXEC; if (type & SOCK_NONBLOCK) oflags |= O_NONBLOCK; sockfd = calloc(1, sizeof(struct SockFd)); @@ -62,6 +76,7 @@ textwindows int sys_socket_nt(int family, int type, int protocol) { g_fds.p[fd].handle = h; g_fds.p[fd].extra = (uintptr_t)sockfd; __fds_unlock(); + return fd; } else { __releasefd(fd); diff --git a/libc/sock/socket.c b/libc/sock/socket.c index 983625c53..a4a157b52 100644 --- a/libc/sock/socket.c +++ b/libc/sock/socket.c @@ -22,26 +22,31 @@ #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sysv/consts/af.h" +#include "libc/sysv/errfuns.h" /** * Creates new system resource for network communication, e.g. * * int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); * - * @param family can be AF_UNIX, AF_INET, etc. + * @param family can be AF_UNIX, AF_INET, AF_INET6, etc. * @param type can be SOCK_STREAM (for TCP), SOCK_DGRAM (e.g. UDP), or * SOCK_RAW (IP) so long as IP_HDRINCL was passed to setsockopt(); * and additionally, may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC * @param protocol can be IPPROTO_TCP, IPPROTO_UDP, or IPPROTO_ICMP * @return socket file descriptor or -1 w/ errno - * @error ENETDOWN, EPFNOSUPPORT, etc. + * @raise EAFNOSUPPORT if `family` isn't supported by system or platform * @see libc/sysv/consts.sh * @asyncsignalsafe */ int socket(int family, int type, int protocol) { int rc; - if (family == AF_UNSPEC) family = AF_INET; - if (!IsWindows()) { + if (family == AF_UNSPEC) { + family = AF_INET; + } + if (family == -1) { + rc = eafnosupport(); + } else if (!IsWindows()) { rc = sys_socket(family, type, protocol); } else { rc = sys_socket_nt(family, type, protocol); diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index 9c3bd2388..a3d86fa18 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -285,7 +285,9 @@ DIR *opendir(const char *name) { res->zip.offset = GetZipCdirOffset(zip->cdir); res->zip.records = GetZipCdirRecords(zip->cdir); res->zip.prefix = malloc(zipname.len + 2); - memcpy(res->zip.prefix, zipname.path, zipname.len); + if (zipname.len) { + memcpy(res->zip.prefix, zipname.path, zipname.len); + } if (zipname.len && res->zip.prefix[zipname.len - 1] != '/') { res->zip.prefix[zipname.len++] = '/'; } @@ -364,7 +366,9 @@ static struct dirent *readdir_impl(DIR *dir) { ent->d_off = dir->zip.offset; ent->d_reclen = MIN(n, 255); ent->d_type = S_ISDIR(mode) ? DT_DIR : DT_REG; - memcpy(ent->d_name, s, ent->d_reclen); + if (ent->d_reclen) { + memcpy(ent->d_name, s, ent->d_reclen); + } ent->d_name[ent->d_reclen] = 0; } else { lastent = (struct dirent *)dir->buf; @@ -377,7 +381,9 @@ static struct dirent *readdir_impl(DIR *dir) { ent->d_off = -1; ent->d_reclen = n; ent->d_type = DT_DIR; - memcpy(ent->d_name, s, ent->d_reclen); + if (ent->d_reclen) { + memcpy(ent->d_name, s, ent->d_reclen); + } ent->d_name[ent->d_reclen] = 0; } } @@ -474,7 +480,9 @@ errno_t readdir_r(DIR *dir, struct dirent *output, struct dirent **result) { return err; } if (entry) { - memcpy(output, entry, entry->d_reclen); + if (entry->d_reclen) { + memcpy(output, entry, entry->d_reclen); + } } else { output = 0; } diff --git a/libc/stdio/fgets_unlocked.c b/libc/stdio/fgets_unlocked.c index 813435a2f..a8f398e46 100644 --- a/libc/stdio/fgets_unlocked.c +++ b/libc/stdio/fgets_unlocked.c @@ -47,7 +47,7 @@ char *fgets_unlocked(char *s, int size, FILE *f) { if ((t = memchr(b, '\n', n))) { n = t + 1 - b; } - memcpy(p, b, n); + if (n) memcpy(p, b, n); f->beg += n; size -= n - 1; p += n; diff --git a/libc/stdio/mkostempsm.c b/libc/stdio/mkostempsm.c index aed32cffe..21c615a58 100644 --- a/libc/stdio/mkostempsm.c +++ b/libc/stdio/mkostempsm.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" @@ -39,7 +40,8 @@ int mkostempsmi(char *tpl, int slen, unsigned flags, uint64_t *rando, int mode, if (len < wildlen || slen > len - wildlen) return einval(); char *ss = tpl + len - wildlen - slen; npassert(memcmp(ss, WILDCARD, wildlen) == 0); - flags = (flags & ~(flags & O_ACCMODE)) | O_RDWR | O_CREAT | O_EXCL; + flags = (flags & ~(flags & O_ACCMODE)) | O_RDWR | O_CREAT | O_EXCL | + (IsWindows() ? 0x00410000 : 0); unsigned attempts = ATTEMPTS; do { char *p = ss; @@ -74,8 +76,7 @@ static uint64_t g_mkostemps_reseed; * or -1 w/ errno * @see kTmpPath */ -dontdiscard int mkostempsm(char *template, int suffixlen, unsigned flags, - int mode) { +int mkostempsm(char *template, int suffixlen, unsigned flags, int mode) { int fd; if (g_mkostemps_reseed++ % RESEED == 0) g_mkostemps_rand = _rand64(); fd = mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open); diff --git a/libc/stdio/posix_spawn.c b/libc/stdio/posix_spawn.c index 62d6c2c83..0c6afe48f 100644 --- a/libc/stdio/posix_spawn.c +++ b/libc/stdio/posix_spawn.c @@ -87,13 +87,13 @@ errno_t posix_spawn(int *pid, const char *path, posix_spawnattr_getflags(attrp, &flags); if (flags & POSIX_SPAWN_SETSID) { if (setsid()) { - STRACE("posix_spawn fail #%d", 1); + STRACE("posix_spawn fail #%d% m", 1); _Exit(127); } } if (flags & POSIX_SPAWN_SETPGROUP) { if (setpgid(0, (*attrp)->pgroup)) { - STRACE("posix_spawn fail #%d", 1); + STRACE("posix_spawn fail #%d% m", 2); _Exit(127); } } @@ -103,14 +103,14 @@ errno_t posix_spawn(int *pid, const char *path, } if ((flags & POSIX_SPAWN_RESETIDS) && (setgid(getgid()) || setuid(getuid()))) { - STRACE("posix_spawn fail #%d", 2); + STRACE("posix_spawn fail #%d% m", 3); _Exit(127); } if (flags & POSIX_SPAWN_SETSIGDEF) { for (s = 1; s < 32; s++) { if (sigismember(&(*attrp)->sigdefault, s)) { if (sigaction(s, &dfl, 0) == -1) { - STRACE("posix_spawn fail #%d", 3); + STRACE("posix_spawn fail #%d% m", 4); _Exit(127); } } @@ -119,7 +119,7 @@ errno_t posix_spawn(int *pid, const char *path, } if (file_actions) { if (RunFileActions(*file_actions) == -1) { - STRACE("posix_spawn fail #%d", 4); + STRACE("posix_spawn fail #%d% m", 5); _Exit(127); } } @@ -128,21 +128,21 @@ errno_t posix_spawn(int *pid, const char *path, posix_spawnattr_getschedpolicy(attrp, &policy); posix_spawnattr_getschedparam(attrp, ¶m); if (sched_setscheduler(0, policy, ¶m) == -1) { - STRACE("posix_spawn fail #%d", 5); + STRACE("posix_spawn fail #%d% m", 6); _Exit(127); } } if (flags & POSIX_SPAWN_SETSCHEDPARAM) { posix_spawnattr_getschedparam(attrp, ¶m); if (sched_setparam(0, ¶m) == -1) { - STRACE("posix_spawn fail #%d", 6); + STRACE("posix_spawn fail #%d% m", 7); _Exit(127); } } } if (!envp) envp = environ; execve(path, argv, envp); - STRACE("posix_spawn fail #%d", 7); + STRACE("posix_spawn fail #%d% m", 8); _Exit(127); } else if (child != -1) { if (pid) *pid = child; diff --git a/libc/stdio/system.c b/libc/stdio/system.c index 671c1869d..bc55a7995 100644 --- a/libc/stdio/system.c +++ b/libc/stdio/system.c @@ -46,34 +46,34 @@ int system(const char *cmdline) { int pid, wstatus; sigset_t chldmask, savemask; - struct sigaction ignore, saveint, savequit; if (!cmdline) return 1; BLOCK_CANCELLATIONS; - ignore.sa_flags = 0; - ignore.sa_handler = SIG_IGN; - sigemptyset(&ignore.sa_mask); - sigaction(SIGINT, &ignore, &saveint); - sigaction(SIGQUIT, &ignore, &savequit); sigemptyset(&chldmask); + sigaddset(&chldmask, SIGINT); + sigaddset(&chldmask, SIGQUIT); sigaddset(&chldmask, SIGCHLD); sigprocmask(SIG_BLOCK, &chldmask, &savemask); if (!(pid = fork())) { - sigaction(SIGINT, &saveint, 0); - sigaction(SIGQUIT, &savequit, 0); sigprocmask(SIG_SETMASK, &savemask, 0); _Exit(_cocmd(3, (char *[]){"system", "-c", cmdline, 0}, environ)); - } else if (pid != -1) { + } else if (pid == -1) { + wstatus = -1; + } else { + struct sigaction ignore, saveint, savequit; + ignore.sa_flags = 0; + ignore.sa_handler = SIG_IGN; + sigemptyset(&ignore.sa_mask); + sigaction(SIGINT, &ignore, &saveint); + sigaction(SIGQUIT, &ignore, &savequit); while (wait4(pid, &wstatus, 0, 0) == -1) { if (errno != EINTR) { wstatus = -1; break; } } - } else { - wstatus = -1; + sigaction(SIGINT, &saveint, 0); + sigaction(SIGQUIT, &savequit, 0); } - sigaction(SIGINT, &saveint, 0); - sigaction(SIGQUIT, &savequit, 0); sigprocmask(SIG_SETMASK, &savemask, 0); ALLOW_CANCELLATIONS; return wstatus; diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index e2d66a494..6b7df79cd 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -180,7 +180,6 @@ syscon compat SIGIOT 6 6 6 6 6 6 6 6 # PDP-11 feature; same # open() flags # # group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD Windoze Commentary -syscon open O_RDWR 2 2 2 2 2 2 2 2 # consensus syscon open O_APPEND 0x00000400 0x00000400 8 8 8 8 8 0x00000400 # bsd consensus & kNtFileAppendData; won't pose issues w/ mknod(S_IFIFO) [SYNC libc/calls/open-nt.c] syscon open O_CREAT 0x00000040 0x00000040 0x00000200 0x00000200 0x00000200 0x00000200 0x00000200 0x00000040 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] syscon open O_EXCL 0x00000080 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] @@ -606,45 +605,23 @@ syscon poll POLLWRBAND 0x0200 0x0200 0x0100 0x0100 0x0100 0x0100 syscon poll POLLWRNORM 0x0100 0x0100 4 4 4 4 4 0x0010 # bsd consensus syscon poll POLLRDHUP 0x2000 0x2000 0x10 0x10 0x10 0x10 0x10 2 # bsd consensus (POLLHUP on non-Linux) -# epoll -# -# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary -syscon epoll EPOLL_CLOEXEC 0x080000 0x080000 0x01000000 0x01000000 0x100000 0x010000 0x010000 0x80000 # O_CLOEXEC -syscon epoll EPOLL_CTL_ADD 1 1 1 1 1 1 1 1 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLL_CTL_DEL 2 2 2 2 2 2 2 2 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLL_CTL_MOD 3 3 3 3 3 3 3 3 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLIN 1 1 1 1 1 1 1 1 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLOUT 4 4 4 4 4 4 4 4 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLERR 8 8 8 8 8 8 8 8 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLPRI 2 2 2 2 2 2 2 2 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLHUP 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLRDNORM 0x40 0x40 0x40 0x40 0x40 0x40 0x40 0x40 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLRDBAND 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLWRNORM 0x0100 0x0100 0x0100 0x0100 0x0100 0x0100 0x0100 0x0100 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLWRBAND 0x0200 0x0200 0x0200 0x0200 0x0200 0x0200 0x0200 0x0200 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLMSG 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLRDHUP 0x2000 0x2000 0x2000 0x2000 0x2000 0x2000 0x2000 0x2000 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLEXCLUSIVE 0x10000000 0x10000000 0x10000000 0x10000000 0x10000000 0x10000000 0x10000000 0x10000000 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLWAKEUP 0x20000000 0x20000000 0x20000000 0x20000000 0x20000000 0x20000000 0x20000000 0x20000000 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLONESHOT 0x40000000 0x40000000 0x40000000 0x40000000 0x40000000 0x40000000 0x40000000 0x40000000 # forced consensus, linux only natively, polyfilled elsewhere -syscon epoll EPOLLET 0x80000000 0x80000000 0x80000000 0x80000000 0x80000000 0x80000000 0x80000000 0x80000000 # forced consensus, linux only natively, polyfilled elsewhere - # {set,get}sockopt(fd, level=SOL_SOCKET, X, ...) # +# Unsupported magic numbers are set to zero. +# # group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon so SOL_SOCKET 1 1 0xffff 0xffff 0xffff 0xffff 0xffff 0xffff # yes it's actually 0xffff; bsd+nt consensus (todo: what's up with ipproto_icmp overlap) syscon so SO_DEBUG 1 1 1 1 1 1 1 1 # debugging is enabled; consensus syscon so SO_TYPE 3 3 0x1008 0x1008 0x1008 0x1008 0x1008 0x1008 # bsd consensus syscon so SO_ERROR 4 4 0x1007 0x1007 0x1007 0x1007 0x1007 0x1007 # takes int pointer and stores/clears the pending error code; bsd consensus syscon so SO_ACCEPTCONN 30 30 2 2 2 2 2 2 # takes int pointer and stores boolean indicating if listen() was called on fd; bsd consensus -syscon so SO_REUSEPORT 15 15 0x0200 0x0200 0x0200 0x0200 0x0200 4 # bsd consensus (NT calls it SO_REUSEADDR) +syscon so SO_REUSEPORT 15 15 0x0200 0x0200 0x0200 0x0200 0x0200 0 # bsd consensus; no windows support syscon so SO_REUSEADDR 2 2 4 4 4 4 4 4 # bsd consensus (default behavior on NT) -syscon so SO_EXCLUSIVEADDRUSE 0 0 0 0 0 0 0 ~4 # bsd consensus (default behavior on NT) syscon so SO_KEEPALIVE 9 9 8 8 8 8 8 8 # bsd consensus syscon so SO_DONTROUTE 5 5 0x10 0x10 0x10 0x10 0x10 0x10 # bsd consensus syscon so SO_BROADCAST 6 6 0x20 0x20 0x20 0x20 0x20 0x20 # socket is configured for broadcast messages; bsd consensus syscon so SO_USELOOPBACK 0 0 0x40 0x40 0x40 0x40 0x40 0x40 # bsd consensus syscon so SO_LINGER 13 13 0x1080 0x1080 0x80 0x80 0x80 0x80 # takes struct linger; causes close() return value to actually mean something; SO_LINGER_SEC on XNU; bsd consensus -syscon so SO_DONTLINGER 0 0 0 0 0 0 0 ~0x80 # disables so_linger on windows syscon so SO_OOBINLINE 10 10 0x0100 0x0100 0x0100 0x0100 0x0100 0x0100 # bsd consensus syscon so SO_SNDBUF 7 7 0x1001 0x1001 0x1001 0x1001 0x1001 0x1001 # bsd consensus syscon so SO_RCVBUF 8 8 0x1002 0x1002 0x1002 0x1002 0x1002 0x1002 # bsd consensus @@ -652,120 +629,6 @@ syscon so SO_RCVTIMEO 20 20 0x1006 0x1006 0x1006 0x1006 0x100c syscon so SO_SNDTIMEO 21 21 0x1005 0x1005 0x1005 0x1005 0x100b 0x1005 # send timeout; takes struct timeval; bsd consensus syscon so SO_RCVLOWAT 18 18 0x1004 0x1004 0x1004 0x1004 0x1004 0x1004 # bsd consensus syscon so SO_SNDLOWAT 19 19 0x1003 0x1003 0x1003 0x1003 0x1003 0x1003 # bsd consensus -syscon so SO_TIMESTAMP 29 29 0x0400 0x0400 0x0400 0x0800 0x2000 0 -syscon so SO_SETFIB 0 0 0 0 0x1014 0 0 0 -syscon so SO_DOMAIN 39 39 0 0 0x1019 0x1024 0 0 -syscon so SO_MAX_PACING_RATE 47 47 0 0 0x1018 0 0 0 -syscon so SO_PEERCRED 17 17 0 0 0 0x1022 0 0 -syscon so SO_EXCLUSIVEADDRUSE 0 0 0 0 0 0 0 0xfffffffb # hoo boy -syscon so LOCAL_PEERCRED 0 0 1 1 1 0 0 0 -syscon so SO_PROTOCOL 38 38 0 0 0x1016 0x1025 0 0 -syscon so SO_ATTACH_BPF 50 50 0 0 0 0 0 0 -syscon so SO_ATTACH_FILTER 26 26 0 0 0 0 0 0 -syscon so SO_ATTACH_REUSEPORT_CBPF 51 51 0 0 0 0 0 0 -syscon so SO_ATTACH_REUSEPORT_EBPF 52 52 0 0 0 0 0 0 -syscon so SO_BINDTODEVICE 25 25 0 0 0 0 0 0 -syscon so SO_BPF_EXTENSIONS 48 48 0 0 0 0 0 0 -syscon so SO_BSDCOMPAT 14 14 0 0 0 0 0 0 -syscon so SO_BUSY_POLL 46 46 0 0 0 0 0 0 -syscon so SO_CNX_ADVICE 53 53 0 0 0 0 0 0 -syscon so SO_DETACH_BPF 27 27 0 0 0 0 0 0 -syscon so SO_DETACH_FILTER 27 27 0 0 0 0 0 0 -syscon so SO_GET_FILTER 26 26 0 0 0 0 0 0 -syscon so SO_INCOMING_CPU 49 49 0 0 0 0 0 0 -syscon so SO_LOCK_FILTER 44 44 0 0 0 0 0 0 -syscon so SO_MARK 36 36 0 0 0 0 0 0 -syscon so SO_NOFCS 43 43 0 0 0 0 0 0 -syscon so SO_NO_CHECK 11 11 0 0 0 0 0 0 -syscon so SO_PASSCRED 0x10 0x10 0 0 0 0 0 0 -syscon so SO_PASSSEC 34 34 0 0 0 0 0 0 -syscon so SO_PEEK_OFF 42 42 0 0 0 0 0 0 -syscon so SO_PEERNAME 28 28 0 0 0 0 0 0 -syscon so SO_PEERSEC 31 31 0 0 0 0 0 0 -syscon so SO_PRIORITY 12 12 0 0 0 0 0 0 -syscon so SO_RCVBUFFORCE 33 33 0 0 0 0 0 0 -syscon so SO_RXQ_OVFL 40 40 0 0 0 0 0 0 -syscon so SO_SECURITY_AUTHENTICATION 22 22 0 0 0 0 0 0 -syscon so SO_SECURITY_ENCRYPTION_NETWORK 24 24 0 0 0 0 0 0 -syscon so SO_SECURITY_ENCRYPTION_TRANSPORT 23 23 0 0 0 0 0 0 -syscon so SO_SELECT_ERR_QUEUE 45 45 0 0 0 0 0 0 -syscon so SO_SNDBUFFORCE 0x20 0x20 0 0 0 0 0 0 -syscon so SO_TIMESTAMPING 37 37 0 0 0 0 0 0 -syscon so SO_TIMESTAMPNS 35 35 0 0 0 0 0 0 -syscon so SO_WIFI_STATUS 41 41 0 0 0 0 0 0 - -# these are IPPROTO_* on non-Linux -syscon sol SOL_IP 0 0 0 0 0 0 0 0 # consensus -syscon sol SOL_SOCKET 1 1 0xffff 0xffff 0xffff 0xffff 0xffff 0xffff # yes it's actually 0xffff; bsd+nt consensus (todo: what's up with ipproto_icmp overlap) -syscon sol SOL_TCP 6 6 6 6 6 6 6 6 # consensus -syscon sol SOL_UDP 17 17 17 17 17 17 17 17 # consensus -syscon sol SOL_RAW 255 255 -1 -1 -1 -1 -1 -1 -syscon sol SOL_IPV6 41 41 41 41 41 41 41 41 -syscon sol SOL_ICMPV6 58 58 58 58 58 58 58 -1 -syscon sol SOL_AAL 265 265 -1 -1 -1 -1 -1 -1 -syscon sol SOL_ALG 279 279 -1 -1 -1 -1 -1 -1 -syscon sol SOL_ATM 264 264 -1 -1 -1 -1 -1 -1 -syscon sol SOL_BLUETOOTH 274 274 -1 -1 -1 -1 -1 -1 -syscon sol SOL_CAIF 278 278 -1 -1 -1 -1 -1 -1 -syscon sol SOL_DCCP 269 269 -1 -1 -1 -1 -1 -1 -syscon sol SOL_DECNET 261 261 -1 -1 -1 -1 -1 -1 -syscon sol SOL_IRDA 266 266 -1 -1 -1 -1 -1 -1 -syscon sol SOL_IUCV 277 277 -1 -1 -1 -1 -1 -1 -syscon sol SOL_KCM 281 281 -1 -1 -1 -1 -1 -1 -syscon sol SOL_LLC 268 268 -1 -1 -1 -1 -1 -1 -syscon sol SOL_NETBEUI 267 267 -1 -1 -1 -1 -1 -1 -syscon sol SOL_NETLINK 270 270 -1 -1 -1 -1 -1 -1 -syscon sol SOL_NFC 280 280 -1 -1 -1 -1 -1 -1 -syscon sol SOL_PACKET 263 263 -1 -1 -1 -1 -1 -1 -syscon sol SOL_PNPIPE 275 275 -1 -1 -1 -1 -1 -1 -syscon sol SOL_PPPOL2TP 273 273 -1 -1 -1 -1 -1 -1 -syscon sol SOL_RDS 276 276 -1 -1 -1 -1 -1 -1 -syscon sol SOL_RXRPC 272 272 -1 -1 -1 -1 -1 -1 -syscon sol SOL_TIPC 271 271 -1 -1 -1 -1 -1 -1 -syscon sol SOL_X25 262 262 -1 -1 -1 -1 -1 -1 - -# IPPROTO_* -# -# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary -syscon iproto IPPROTO_IP 0 0 0 0 0 0 0 0 # consensus -syscon iproto IPPROTO_ICMP 1 1 1 1 1 1 1 1 # consensus -syscon iproto IPPROTO_TCP 6 6 6 6 6 6 6 6 # consensus -syscon iproto IPPROTO_UDP 17 17 17 17 17 17 17 17 # consensus -syscon iproto IPPROTO_RAW 255 255 255 255 255 255 255 255 # consensus -syscon iproto IPPROTO_HOPOPTS 0 0 0 0 0 0 0 -1 # consensus -syscon iproto IPPROTO_IDP 22 22 22 22 22 22 22 22 # consensus -syscon iproto IPPROTO_IGMP 2 2 2 2 2 2 2 2 # consensus -syscon iproto IPPROTO_PUP 12 12 12 12 12 12 12 12 # consensus -syscon iproto IPPROTO_AH 51 51 51 51 51 51 51 -1 # unix consensus -syscon iproto IPPROTO_DSTOPTS 60 60 60 60 60 60 60 -1 # unix consensus -syscon iproto IPPROTO_EGP 8 8 8 8 8 8 8 -1 # unix consensus -syscon iproto IPPROTO_ENCAP 98 98 98 98 98 98 98 -1 # unix consensus -syscon iproto IPPROTO_ESP 50 50 50 50 50 50 50 -1 # unix consensus -syscon iproto IPPROTO_FRAGMENT 44 44 44 44 44 44 44 -1 # unix consensus -syscon iproto IPPROTO_GRE 47 47 47 47 47 47 47 -1 # unix consensus -syscon iproto IPPROTO_ICMPV6 58 58 58 58 58 58 58 -1 # unix consensus -syscon iproto IPPROTO_IPIP 4 4 4 4 4 4 4 -1 # unix consensus -syscon iproto IPPROTO_IPV6 41 41 41 41 41 41 41 -1 # unix consensus -syscon iproto IPPROTO_NONE 59 59 59 59 59 59 59 -1 # unix consensus -syscon iproto IPPROTO_PIM 103 103 103 103 103 103 103 -1 # unix consensus -syscon iproto IPPROTO_ROUTING 43 43 43 43 43 43 43 -1 # unix consensus -syscon iproto IPPROTO_RSVP 46 46 46 46 46 46 46 -1 # unix consensus -syscon iproto IPPROTO_TP 29 29 29 29 29 29 29 -1 # unix consensus -syscon iproto IPPROTO_MPLS 137 137 -1 -1 137 137 137 -1 -syscon iproto IPPROTO_MTP 92 92 92 92 92 -1 -1 -1 -syscon iproto IPPROTO_SCTP 132 132 132 132 132 -1 -1 -1 -syscon iproto IPPROTO_MH 135 135 -1 -1 135 -1 -1 -1 -syscon iproto IPPROTO_UDPLITE 136 136 -1 -1 136 -1 -1 -1 -syscon iproto IPPROTO_BEETPH 94 94 -1 -1 -1 -1 -1 -1 -syscon iproto IPPROTO_COMP 108 108 -1 -1 -1 -1 -1 -1 -syscon iproto IPPROTO_DCCP 33 33 -1 -1 -1 -1 -1 -1 - -syscon alg ALG_SET_KEY 1 1 0 0 0 0 0 0 -syscon alg ALG_SET_IV 2 2 0 0 0 0 0 0 -syscon alg ALG_SET_OP 3 3 0 0 0 0 0 0 -syscon alg ALG_SET_AEAD_ASSOCLEN 4 4 0 0 0 0 0 0 -syscon alg ALG_SET_AEAD_AUTHSIZE 5 5 0 0 0 0 0 0 -syscon alg ALG_SET_DRBG_ENTROPY 6 6 0 0 0 0 0 0 # {set,get}sockopt(fd, level=SOL_TCP, X, ...) # » most elite of all tuning groups @@ -1004,48 +867,48 @@ syscon ioctl SIOGIFINDEX 0x8933 0x8933 0 0 0 0 0 0 syscon af AF_UNSPEC 0 0 0 0 0 0 0 0 # consensus syscon af AF_UNIX 1 1 1 1 1 1 1 1 # consensus syscon af AF_LOCAL 1 1 1 1 1 1 1 1 # consensus -syscon af AF_FILE 1 1 0 0 0 0 0 0 syscon af AF_INET 2 2 2 2 2 2 2 2 # consensus syscon af AF_INET6 10 10 30 30 28 24 24 23 -syscon af AF_AX25 3 3 0 0 0 0 0 0 syscon af AF_IPX 4 4 23 23 23 23 23 6 # bsd consensus syscon af AF_APPLETALK 5 5 0x10 0x10 0x10 0x10 0x10 0x10 # bsd consensus -syscon af AF_NETROM 6 6 0 0 0 0 0 0 -syscon af AF_BRIDGE 7 7 0 0 0 0 0 0 -syscon af AF_ATMPVC 8 8 0 0 0 0 0 0 -syscon af AF_X25 9 9 0 0 0 0 0 0 -syscon af AF_ROSE 11 11 0 0 0 0 0 0 -syscon af AF_NETBEUI 13 13 0 0 0 0 0 0 -syscon af AF_SECURITY 14 14 0 0 0 0 0 0 -syscon af AF_KEY 15 15 0 0 0 30 0 0 -syscon af AF_ROUTE 16 16 17 17 17 17 34 0 # bsd consensus -syscon af AF_NETLINK 16 16 0 0 0 0 0 0 -syscon af AF_PACKET 17 17 0 0 0 0 0 0 -syscon af AF_LINK 0 0 18 18 18 18 18 0 -syscon af AF_ASH 18 18 0 0 0 0 0 0 -syscon af AF_ECONET 19 19 0 0 0 0 0 0 -syscon af AF_ATMSVC 20 20 0 0 0 0 0 0 -syscon af AF_RDS 21 21 0 0 0 0 0 0 +syscon af AF_ROUTE 16 16 17 17 17 17 34 -1 # bsd consensus +syscon af AF_LINK -1 -1 18 18 18 18 18 -1 syscon af AF_SNA 22 22 11 11 11 11 11 11 # bsd consensus -syscon af AF_IRDA 23 23 0 0 0 0 0 0 -syscon af AF_PPPOX 24 24 0 0 0 0 0 0 -syscon af AF_WANPIPE 25 25 0 0 0 0 0 0 -syscon af AF_LLC 26 26 0 0 0 0 0 0 -syscon af AF_IB 27 27 0 0 0 0 0 0 -syscon af AF_MPLS 28 28 0 0 0 33 33 0 -syscon af AF_CAN 29 29 0 0 0 0 35 0 -syscon af AF_TIPC 30 30 0 0 0 0 0 0 -syscon af AF_BLUETOOTH 31 31 0 0 36 0x20 31 0 -syscon af AF_IUCV 0x20 0x20 0 0 0 0 0 0 -syscon af AF_RXRPC 33 33 0 0 0 0 0 0 -syscon af AF_ISDN 34 34 28 28 26 26 26 0 -syscon af AF_PHONET 35 35 0 0 0 0 0 0 -syscon af AF_IEEE802154 36 36 0 0 0 0 0 0 -syscon af AF_CAIF 37 37 0 0 0 0 0 0 -syscon af AF_ALG 38 38 0 0 0 0 0 0 -syscon af AF_NFC 39 39 0 0 0 0 0 0 -syscon af AF_VSOCK 40 40 0 0 0 0 0 0 -syscon af AF_KCM 41 41 0 0 0 0 0 0 +syscon af AF_FILE 1 1 -1 -1 -1 -1 -1 -1 +syscon af AF_AX25 3 3 -1 -1 -1 -1 -1 -1 +syscon af AF_NETROM 6 6 -1 -1 -1 -1 -1 -1 +syscon af AF_BRIDGE 7 7 -1 -1 -1 -1 -1 -1 +syscon af AF_ATMPVC 8 8 -1 -1 -1 -1 -1 -1 +syscon af AF_X25 9 9 -1 -1 -1 -1 -1 -1 +syscon af AF_ROSE 11 11 -1 -1 -1 -1 -1 -1 +syscon af AF_NETBEUI 13 13 -1 -1 -1 -1 -1 -1 +syscon af AF_SECURITY 14 14 -1 -1 -1 -1 -1 -1 +syscon af AF_KEY 15 15 -1 -1 -1 30 -1 -1 +syscon af AF_NETLINK 16 16 -1 -1 -1 -1 -1 -1 +syscon af AF_PACKET 17 17 -1 -1 -1 -1 -1 -1 +syscon af AF_ASH 18 18 -1 -1 -1 -1 -1 -1 +syscon af AF_ECONET 19 19 -1 -1 -1 -1 -1 -1 +syscon af AF_ATMSVC 20 20 -1 -1 -1 -1 -1 -1 +syscon af AF_RDS 21 21 -1 -1 -1 -1 -1 -1 +syscon af AF_IRDA 23 23 -1 -1 -1 -1 -1 -1 +syscon af AF_PPPOX 24 24 -1 -1 -1 -1 -1 -1 +syscon af AF_WANPIPE 25 25 -1 -1 -1 -1 -1 -1 +syscon af AF_LLC 26 26 -1 -1 -1 -1 -1 -1 +syscon af AF_IB 27 27 -1 -1 -1 -1 -1 -1 +syscon af AF_MPLS 28 28 -1 -1 -1 33 33 -1 +syscon af AF_CAN 29 29 -1 -1 -1 -1 35 -1 +syscon af AF_TIPC 30 30 -1 -1 -1 -1 -1 -1 +syscon af AF_BLUETOOTH 31 31 -1 -1 36 0x20 31 -1 +syscon af AF_IUCV 0x20 0x20 -1 -1 -1 -1 -1 -1 +syscon af AF_RXRPC 33 33 -1 -1 -1 -1 -1 -1 +syscon af AF_ISDN 34 34 28 28 26 26 26 -1 +syscon af AF_PHONET 35 35 -1 -1 -1 -1 -1 -1 +syscon af AF_IEEE802154 36 36 -1 -1 -1 -1 -1 -1 +syscon af AF_CAIF 37 37 -1 -1 -1 -1 -1 -1 +syscon af AF_ALG 38 38 -1 -1 -1 -1 -1 -1 +syscon af AF_NFC 39 39 -1 -1 -1 -1 -1 -1 +syscon af AF_VSOCK 40 40 -1 -1 -1 -1 -1 -1 +syscon af AF_KCM 41 41 -1 -1 -1 -1 -1 -1 syscon af AF_MAX 42 42 40 40 42 36 37 35 syscon pf PF_UNIX 1 1 1 1 1 1 1 1 # consensus diff --git a/libc/sysv/consts/ALG_SET_AEAD_ASSOCLEN.S b/libc/sysv/consts/ALG_SET_AEAD_ASSOCLEN.S deleted file mode 100644 index c1e9b5ffd..000000000 --- a/libc/sysv/consts/ALG_SET_AEAD_ASSOCLEN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon alg,ALG_SET_AEAD_ASSOCLEN,4,4,0,0,0,0,0,0 diff --git a/libc/sysv/consts/ALG_SET_AEAD_AUTHSIZE.S b/libc/sysv/consts/ALG_SET_AEAD_AUTHSIZE.S deleted file mode 100644 index da7490e7c..000000000 --- a/libc/sysv/consts/ALG_SET_AEAD_AUTHSIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon alg,ALG_SET_AEAD_AUTHSIZE,5,5,0,0,0,0,0,0 diff --git a/libc/sysv/consts/ALG_SET_DRBG_ENTROPY.S b/libc/sysv/consts/ALG_SET_DRBG_ENTROPY.S deleted file mode 100644 index b7b855307..000000000 --- a/libc/sysv/consts/ALG_SET_DRBG_ENTROPY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon alg,ALG_SET_DRBG_ENTROPY,6,6,0,0,0,0,0,0 diff --git a/libc/sysv/consts/ALG_SET_IV.S b/libc/sysv/consts/ALG_SET_IV.S deleted file mode 100644 index dca740be2..000000000 --- a/libc/sysv/consts/ALG_SET_IV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon alg,ALG_SET_IV,2,2,0,0,0,0,0,0 diff --git a/libc/sysv/consts/ALG_SET_KEY.S b/libc/sysv/consts/ALG_SET_KEY.S deleted file mode 100644 index 7bb9f69ed..000000000 --- a/libc/sysv/consts/ALG_SET_KEY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon alg,ALG_SET_KEY,1,1,0,0,0,0,0,0 diff --git a/libc/sysv/consts/ALG_SET_OP.S b/libc/sysv/consts/ALG_SET_OP.S deleted file mode 100644 index c069480d4..000000000 --- a/libc/sysv/consts/ALG_SET_OP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon alg,ALG_SET_OP,3,3,0,0,0,0,0,0 diff --git a/libc/sysv/consts/EPOLLERR.S b/libc/sysv/consts/EPOLLERR.S deleted file mode 100644 index 4f4204eb4..000000000 --- a/libc/sysv/consts/EPOLLERR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLERR,8,8,8,8,8,8,8,8 diff --git a/libc/sysv/consts/EPOLLET.S b/libc/sysv/consts/EPOLLET.S deleted file mode 100644 index 3a47fb4f8..000000000 --- a/libc/sysv/consts/EPOLLET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLET,0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000000 diff --git a/libc/sysv/consts/EPOLLEXCLUSIVE.S b/libc/sysv/consts/EPOLLEXCLUSIVE.S deleted file mode 100644 index aa182fd17..000000000 --- a/libc/sysv/consts/EPOLLEXCLUSIVE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLEXCLUSIVE,0x10000000,0x10000000,0x10000000,0x10000000,0x10000000,0x10000000,0x10000000,0x10000000 diff --git a/libc/sysv/consts/EPOLLHUP.S b/libc/sysv/consts/EPOLLHUP.S deleted file mode 100644 index 9bdc4603d..000000000 --- a/libc/sysv/consts/EPOLLHUP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLHUP,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 diff --git a/libc/sysv/consts/EPOLLIN.S b/libc/sysv/consts/EPOLLIN.S deleted file mode 100644 index 62b51613d..000000000 --- a/libc/sysv/consts/EPOLLIN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLIN,1,1,1,1,1,1,1,1 diff --git a/libc/sysv/consts/EPOLLMSG.S b/libc/sysv/consts/EPOLLMSG.S deleted file mode 100644 index d44d0b012..000000000 --- a/libc/sysv/consts/EPOLLMSG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLMSG,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400 diff --git a/libc/sysv/consts/EPOLLONESHOT.S b/libc/sysv/consts/EPOLLONESHOT.S deleted file mode 100644 index fc67623f6..000000000 --- a/libc/sysv/consts/EPOLLONESHOT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLONESHOT,0x40000000,0x40000000,0x40000000,0x40000000,0x40000000,0x40000000,0x40000000,0x40000000 diff --git a/libc/sysv/consts/EPOLLOUT.S b/libc/sysv/consts/EPOLLOUT.S deleted file mode 100644 index f48f77591..000000000 --- a/libc/sysv/consts/EPOLLOUT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLOUT,4,4,4,4,4,4,4,4 diff --git a/libc/sysv/consts/EPOLLPRI.S b/libc/sysv/consts/EPOLLPRI.S deleted file mode 100644 index 9b8224652..000000000 --- a/libc/sysv/consts/EPOLLPRI.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLPRI,2,2,2,2,2,2,2,2 diff --git a/libc/sysv/consts/EPOLLRDBAND.S b/libc/sysv/consts/EPOLLRDBAND.S deleted file mode 100644 index b115e3493..000000000 --- a/libc/sysv/consts/EPOLLRDBAND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLRDBAND,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 diff --git a/libc/sysv/consts/EPOLLRDHUP.S b/libc/sysv/consts/EPOLLRDHUP.S deleted file mode 100644 index d48df0de5..000000000 --- a/libc/sysv/consts/EPOLLRDHUP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLRDHUP,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000 diff --git a/libc/sysv/consts/EPOLLRDNORM.S b/libc/sysv/consts/EPOLLRDNORM.S deleted file mode 100644 index b5c54058d..000000000 --- a/libc/sysv/consts/EPOLLRDNORM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLRDNORM,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 diff --git a/libc/sysv/consts/EPOLLWAKEUP.S b/libc/sysv/consts/EPOLLWAKEUP.S deleted file mode 100644 index 2026ea0ca..000000000 --- a/libc/sysv/consts/EPOLLWAKEUP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLWAKEUP,0x20000000,0x20000000,0x20000000,0x20000000,0x20000000,0x20000000,0x20000000,0x20000000 diff --git a/libc/sysv/consts/EPOLLWRBAND.S b/libc/sysv/consts/EPOLLWRBAND.S deleted file mode 100644 index 6fefcdaad..000000000 --- a/libc/sysv/consts/EPOLLWRBAND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLWRBAND,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200 diff --git a/libc/sysv/consts/EPOLLWRNORM.S b/libc/sysv/consts/EPOLLWRNORM.S deleted file mode 100644 index 8b280726c..000000000 --- a/libc/sysv/consts/EPOLLWRNORM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLLWRNORM,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100 diff --git a/libc/sysv/consts/EPOLL_CLOEXEC.S b/libc/sysv/consts/EPOLL_CLOEXEC.S deleted file mode 100644 index e045cc8b3..000000000 --- a/libc/sysv/consts/EPOLL_CLOEXEC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLL_CLOEXEC,0x080000,0x080000,0x01000000,0x01000000,0x100000,0x010000,0x010000,0x80000 diff --git a/libc/sysv/consts/EPOLL_CTL_ADD.S b/libc/sysv/consts/EPOLL_CTL_ADD.S deleted file mode 100644 index f186a0047..000000000 --- a/libc/sysv/consts/EPOLL_CTL_ADD.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLL_CTL_ADD,1,1,1,1,1,1,1,1 diff --git a/libc/sysv/consts/EPOLL_CTL_DEL.S b/libc/sysv/consts/EPOLL_CTL_DEL.S deleted file mode 100644 index bbf481de8..000000000 --- a/libc/sysv/consts/EPOLL_CTL_DEL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLL_CTL_DEL,2,2,2,2,2,2,2,2 diff --git a/libc/sysv/consts/EPOLL_CTL_MOD.S b/libc/sysv/consts/EPOLL_CTL_MOD.S deleted file mode 100644 index abdf94fd0..000000000 --- a/libc/sysv/consts/EPOLL_CTL_MOD.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon epoll,EPOLL_CTL_MOD,3,3,3,3,3,3,3,3 diff --git a/libc/sysv/consts/IPPROTO_AH.S b/libc/sysv/consts/IPPROTO_AH.S deleted file mode 100644 index 90f04f5c0..000000000 --- a/libc/sysv/consts/IPPROTO_AH.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_AH,51,51,51,51,51,51,51,-1 diff --git a/libc/sysv/consts/IPPROTO_BEETPH.S b/libc/sysv/consts/IPPROTO_BEETPH.S deleted file mode 100644 index 45b2dcc2f..000000000 --- a/libc/sysv/consts/IPPROTO_BEETPH.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_BEETPH,94,94,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/IPPROTO_COMP.S b/libc/sysv/consts/IPPROTO_COMP.S deleted file mode 100644 index 343b06619..000000000 --- a/libc/sysv/consts/IPPROTO_COMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_COMP,108,108,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/IPPROTO_DCCP.S b/libc/sysv/consts/IPPROTO_DCCP.S deleted file mode 100644 index dc0bd49e3..000000000 --- a/libc/sysv/consts/IPPROTO_DCCP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_DCCP,33,33,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/IPPROTO_DSTOPTS.S b/libc/sysv/consts/IPPROTO_DSTOPTS.S deleted file mode 100644 index 8b2ea1187..000000000 --- a/libc/sysv/consts/IPPROTO_DSTOPTS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_DSTOPTS,60,60,60,60,60,60,60,-1 diff --git a/libc/sysv/consts/IPPROTO_EGP.S b/libc/sysv/consts/IPPROTO_EGP.S deleted file mode 100644 index 63073f344..000000000 --- a/libc/sysv/consts/IPPROTO_EGP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_EGP,8,8,8,8,8,8,8,-1 diff --git a/libc/sysv/consts/IPPROTO_ENCAP.S b/libc/sysv/consts/IPPROTO_ENCAP.S deleted file mode 100644 index 21b3cf220..000000000 --- a/libc/sysv/consts/IPPROTO_ENCAP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_ENCAP,98,98,98,98,98,98,98,-1 diff --git a/libc/sysv/consts/IPPROTO_ESP.S b/libc/sysv/consts/IPPROTO_ESP.S deleted file mode 100644 index c15805f23..000000000 --- a/libc/sysv/consts/IPPROTO_ESP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_ESP,50,50,50,50,50,50,50,-1 diff --git a/libc/sysv/consts/IPPROTO_FRAGMENT.S b/libc/sysv/consts/IPPROTO_FRAGMENT.S deleted file mode 100644 index d6516e4dc..000000000 --- a/libc/sysv/consts/IPPROTO_FRAGMENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_FRAGMENT,44,44,44,44,44,44,44,-1 diff --git a/libc/sysv/consts/IPPROTO_GRE.S b/libc/sysv/consts/IPPROTO_GRE.S deleted file mode 100644 index 19e85f62f..000000000 --- a/libc/sysv/consts/IPPROTO_GRE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_GRE,47,47,47,47,47,47,47,-1 diff --git a/libc/sysv/consts/IPPROTO_HOPOPTS.S b/libc/sysv/consts/IPPROTO_HOPOPTS.S deleted file mode 100644 index 834d549db..000000000 --- a/libc/sysv/consts/IPPROTO_HOPOPTS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_HOPOPTS,0,0,0,0,0,0,0,-1 diff --git a/libc/sysv/consts/IPPROTO_ICMP.S b/libc/sysv/consts/IPPROTO_ICMP.S deleted file mode 100644 index fb2affedf..000000000 --- a/libc/sysv/consts/IPPROTO_ICMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_ICMP,1,1,1,1,1,1,1,1 diff --git a/libc/sysv/consts/IPPROTO_ICMPV6.S b/libc/sysv/consts/IPPROTO_ICMPV6.S deleted file mode 100644 index f3691d1b1..000000000 --- a/libc/sysv/consts/IPPROTO_ICMPV6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_ICMPV6,58,58,58,58,58,58,58,-1 diff --git a/libc/sysv/consts/IPPROTO_IDP.S b/libc/sysv/consts/IPPROTO_IDP.S deleted file mode 100644 index f6e6f4c61..000000000 --- a/libc/sysv/consts/IPPROTO_IDP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_IDP,22,22,22,22,22,22,22,22 diff --git a/libc/sysv/consts/IPPROTO_IGMP.S b/libc/sysv/consts/IPPROTO_IGMP.S deleted file mode 100644 index 179ada0b1..000000000 --- a/libc/sysv/consts/IPPROTO_IGMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_IGMP,2,2,2,2,2,2,2,2 diff --git a/libc/sysv/consts/IPPROTO_IP.S b/libc/sysv/consts/IPPROTO_IP.S deleted file mode 100644 index 88de4024a..000000000 --- a/libc/sysv/consts/IPPROTO_IP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_IP,0,0,0,0,0,0,0,0 diff --git a/libc/sysv/consts/IPPROTO_IPIP.S b/libc/sysv/consts/IPPROTO_IPIP.S deleted file mode 100644 index d09860057..000000000 --- a/libc/sysv/consts/IPPROTO_IPIP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_IPIP,4,4,4,4,4,4,4,-1 diff --git a/libc/sysv/consts/IPPROTO_IPV6.S b/libc/sysv/consts/IPPROTO_IPV6.S deleted file mode 100644 index 3763b9ebe..000000000 --- a/libc/sysv/consts/IPPROTO_IPV6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_IPV6,41,41,41,41,41,41,41,-1 diff --git a/libc/sysv/consts/IPPROTO_MH.S b/libc/sysv/consts/IPPROTO_MH.S deleted file mode 100644 index c720ab5c5..000000000 --- a/libc/sysv/consts/IPPROTO_MH.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_MH,135,135,-1,-1,135,-1,-1,-1 diff --git a/libc/sysv/consts/IPPROTO_MPLS.S b/libc/sysv/consts/IPPROTO_MPLS.S deleted file mode 100644 index b77eae938..000000000 --- a/libc/sysv/consts/IPPROTO_MPLS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_MPLS,137,137,-1,-1,137,137,137,-1 diff --git a/libc/sysv/consts/IPPROTO_MTP.S b/libc/sysv/consts/IPPROTO_MTP.S deleted file mode 100644 index 9522a9ae7..000000000 --- a/libc/sysv/consts/IPPROTO_MTP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_MTP,92,92,92,92,92,-1,-1,-1 diff --git a/libc/sysv/consts/IPPROTO_NONE.S b/libc/sysv/consts/IPPROTO_NONE.S deleted file mode 100644 index 919029800..000000000 --- a/libc/sysv/consts/IPPROTO_NONE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_NONE,59,59,59,59,59,59,59,-1 diff --git a/libc/sysv/consts/IPPROTO_PIM.S b/libc/sysv/consts/IPPROTO_PIM.S deleted file mode 100644 index ecbf8dc2e..000000000 --- a/libc/sysv/consts/IPPROTO_PIM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_PIM,103,103,103,103,103,103,103,-1 diff --git a/libc/sysv/consts/IPPROTO_PUP.S b/libc/sysv/consts/IPPROTO_PUP.S deleted file mode 100644 index d231ffec2..000000000 --- a/libc/sysv/consts/IPPROTO_PUP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_PUP,12,12,12,12,12,12,12,12 diff --git a/libc/sysv/consts/IPPROTO_RAW.S b/libc/sysv/consts/IPPROTO_RAW.S deleted file mode 100644 index 70dd282f6..000000000 --- a/libc/sysv/consts/IPPROTO_RAW.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_RAW,255,255,255,255,255,255,255,255 diff --git a/libc/sysv/consts/IPPROTO_ROUTING.S b/libc/sysv/consts/IPPROTO_ROUTING.S deleted file mode 100644 index a6f75d133..000000000 --- a/libc/sysv/consts/IPPROTO_ROUTING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_ROUTING,43,43,43,43,43,43,43,-1 diff --git a/libc/sysv/consts/IPPROTO_RSVP.S b/libc/sysv/consts/IPPROTO_RSVP.S deleted file mode 100644 index 5c69f0066..000000000 --- a/libc/sysv/consts/IPPROTO_RSVP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_RSVP,46,46,46,46,46,46,46,-1 diff --git a/libc/sysv/consts/IPPROTO_SCTP.S b/libc/sysv/consts/IPPROTO_SCTP.S deleted file mode 100644 index bc27f9a58..000000000 --- a/libc/sysv/consts/IPPROTO_SCTP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_SCTP,132,132,132,132,132,-1,-1,-1 diff --git a/libc/sysv/consts/IPPROTO_TCP.S b/libc/sysv/consts/IPPROTO_TCP.S deleted file mode 100644 index 183995000..000000000 --- a/libc/sysv/consts/IPPROTO_TCP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_TCP,6,6,6,6,6,6,6,6 diff --git a/libc/sysv/consts/IPPROTO_TP.S b/libc/sysv/consts/IPPROTO_TP.S deleted file mode 100644 index 83f5ac7b9..000000000 --- a/libc/sysv/consts/IPPROTO_TP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_TP,29,29,29,29,29,29,29,-1 diff --git a/libc/sysv/consts/IPPROTO_UDP.S b/libc/sysv/consts/IPPROTO_UDP.S deleted file mode 100644 index 9175c58b6..000000000 --- a/libc/sysv/consts/IPPROTO_UDP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_UDP,17,17,17,17,17,17,17,17 diff --git a/libc/sysv/consts/IPPROTO_UDPLITE.S b/libc/sysv/consts/IPPROTO_UDPLITE.S deleted file mode 100644 index 0b3d3785a..000000000 --- a/libc/sysv/consts/IPPROTO_UDPLITE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon iproto,IPPROTO_UDPLITE,136,136,-1,-1,136,-1,-1,-1 diff --git a/libc/sysv/consts/LOCAL_PEERCRED.S b/libc/sysv/consts/LOCAL_PEERCRED.S deleted file mode 100644 index d58dca56b..000000000 --- a/libc/sysv/consts/LOCAL_PEERCRED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,LOCAL_PEERCRED,0,0,1,1,1,0,0,0 diff --git a/libc/sysv/consts/O_RDWR.S b/libc/sysv/consts/O_RDWR.S deleted file mode 100644 index dc735bfd8..000000000 --- a/libc/sysv/consts/O_RDWR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_RDWR,2,2,2,2,2,2,2,2 diff --git a/libc/sysv/consts/SOL_AAL.S b/libc/sysv/consts/SOL_AAL.S deleted file mode 100644 index 19f6e61e0..000000000 --- a/libc/sysv/consts/SOL_AAL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_AAL,265,265,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_ALG.S b/libc/sysv/consts/SOL_ALG.S deleted file mode 100644 index c8ff07c43..000000000 --- a/libc/sysv/consts/SOL_ALG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_ALG,279,279,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_ATM.S b/libc/sysv/consts/SOL_ATM.S deleted file mode 100644 index 6753d0058..000000000 --- a/libc/sysv/consts/SOL_ATM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_ATM,264,264,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_BLUETOOTH.S b/libc/sysv/consts/SOL_BLUETOOTH.S deleted file mode 100644 index b95b32c86..000000000 --- a/libc/sysv/consts/SOL_BLUETOOTH.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_BLUETOOTH,274,274,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_CAIF.S b/libc/sysv/consts/SOL_CAIF.S deleted file mode 100644 index e5cb33346..000000000 --- a/libc/sysv/consts/SOL_CAIF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_CAIF,278,278,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_DCCP.S b/libc/sysv/consts/SOL_DCCP.S deleted file mode 100644 index b8c3b6388..000000000 --- a/libc/sysv/consts/SOL_DCCP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_DCCP,269,269,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_DECNET.S b/libc/sysv/consts/SOL_DECNET.S deleted file mode 100644 index 4940e5a6d..000000000 --- a/libc/sysv/consts/SOL_DECNET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_DECNET,261,261,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_ICMPV6.S b/libc/sysv/consts/SOL_ICMPV6.S deleted file mode 100644 index 51ed7344d..000000000 --- a/libc/sysv/consts/SOL_ICMPV6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_ICMPV6,58,58,58,58,58,58,58,-1 diff --git a/libc/sysv/consts/SOL_IP.S b/libc/sysv/consts/SOL_IP.S deleted file mode 100644 index 5e0c8a1f4..000000000 --- a/libc/sysv/consts/SOL_IP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_IP,0,0,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SOL_IPV6.S b/libc/sysv/consts/SOL_IPV6.S deleted file mode 100644 index c54a62a99..000000000 --- a/libc/sysv/consts/SOL_IPV6.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_IPV6,41,41,41,41,41,41,41,41 diff --git a/libc/sysv/consts/SOL_IRDA.S b/libc/sysv/consts/SOL_IRDA.S deleted file mode 100644 index cc6eade21..000000000 --- a/libc/sysv/consts/SOL_IRDA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_IRDA,266,266,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_IUCV.S b/libc/sysv/consts/SOL_IUCV.S deleted file mode 100644 index 619a0938f..000000000 --- a/libc/sysv/consts/SOL_IUCV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_IUCV,277,277,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_KCM.S b/libc/sysv/consts/SOL_KCM.S deleted file mode 100644 index c5d970f6a..000000000 --- a/libc/sysv/consts/SOL_KCM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_KCM,281,281,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_LLC.S b/libc/sysv/consts/SOL_LLC.S deleted file mode 100644 index 667b1f66c..000000000 --- a/libc/sysv/consts/SOL_LLC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_LLC,268,268,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_NETBEUI.S b/libc/sysv/consts/SOL_NETBEUI.S deleted file mode 100644 index 4e3e9d4c4..000000000 --- a/libc/sysv/consts/SOL_NETBEUI.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_NETBEUI,267,267,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_NETLINK.S b/libc/sysv/consts/SOL_NETLINK.S deleted file mode 100644 index 87a265a1b..000000000 --- a/libc/sysv/consts/SOL_NETLINK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_NETLINK,270,270,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_NFC.S b/libc/sysv/consts/SOL_NFC.S deleted file mode 100644 index 7bc21fbf3..000000000 --- a/libc/sysv/consts/SOL_NFC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_NFC,280,280,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_PACKET.S b/libc/sysv/consts/SOL_PACKET.S deleted file mode 100644 index 8a37a5731..000000000 --- a/libc/sysv/consts/SOL_PACKET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_PACKET,263,263,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_PNPIPE.S b/libc/sysv/consts/SOL_PNPIPE.S deleted file mode 100644 index bdbc4fae5..000000000 --- a/libc/sysv/consts/SOL_PNPIPE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_PNPIPE,275,275,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_PPPOL2TP.S b/libc/sysv/consts/SOL_PPPOL2TP.S deleted file mode 100644 index e44c96a5f..000000000 --- a/libc/sysv/consts/SOL_PPPOL2TP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_PPPOL2TP,273,273,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_RAW.S b/libc/sysv/consts/SOL_RAW.S deleted file mode 100644 index 4205f6466..000000000 --- a/libc/sysv/consts/SOL_RAW.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_RAW,255,255,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_RDS.S b/libc/sysv/consts/SOL_RDS.S deleted file mode 100644 index e57b144e6..000000000 --- a/libc/sysv/consts/SOL_RDS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_RDS,276,276,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_RXRPC.S b/libc/sysv/consts/SOL_RXRPC.S deleted file mode 100644 index 4559aac9e..000000000 --- a/libc/sysv/consts/SOL_RXRPC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_RXRPC,272,272,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_SOCKET.S b/libc/sysv/consts/SOL_SOCKET.S index 5c6e79b86..dc0b84c34 100644 --- a/libc/sysv/consts/SOL_SOCKET.S +++ b/libc/sysv/consts/SOL_SOCKET.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_SOCKET,1,1,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff +.syscon so,SOL_SOCKET,1,1,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff diff --git a/libc/sysv/consts/SOL_TCP.S b/libc/sysv/consts/SOL_TCP.S deleted file mode 100644 index 98d18cb9c..000000000 --- a/libc/sysv/consts/SOL_TCP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_TCP,6,6,6,6,6,6,6,6 diff --git a/libc/sysv/consts/SOL_TIPC.S b/libc/sysv/consts/SOL_TIPC.S deleted file mode 100644 index 2d0739ad9..000000000 --- a/libc/sysv/consts/SOL_TIPC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_TIPC,271,271,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SOL_UDP.S b/libc/sysv/consts/SOL_UDP.S deleted file mode 100644 index 104f3bff7..000000000 --- a/libc/sysv/consts/SOL_UDP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_UDP,17,17,17,17,17,17,17,17 diff --git a/libc/sysv/consts/SOL_X25.S b/libc/sysv/consts/SOL_X25.S deleted file mode 100644 index 9ca1ef176..000000000 --- a/libc/sysv/consts/SOL_X25.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon sol,SOL_X25,262,262,-1,-1,-1,-1,-1,-1 diff --git a/libc/sysv/consts/SO_ATTACH_BPF.S b/libc/sysv/consts/SO_ATTACH_BPF.S deleted file mode 100644 index 5bf4857a5..000000000 --- a/libc/sysv/consts/SO_ATTACH_BPF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_ATTACH_BPF,50,50,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_ATTACH_FILTER.S b/libc/sysv/consts/SO_ATTACH_FILTER.S deleted file mode 100644 index 250195a4a..000000000 --- a/libc/sysv/consts/SO_ATTACH_FILTER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_ATTACH_FILTER,26,26,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_ATTACH_REUSEPORT_CBPF.S b/libc/sysv/consts/SO_ATTACH_REUSEPORT_CBPF.S deleted file mode 100644 index f01f9f7a1..000000000 --- a/libc/sysv/consts/SO_ATTACH_REUSEPORT_CBPF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_ATTACH_REUSEPORT_CBPF,51,51,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_ATTACH_REUSEPORT_EBPF.S b/libc/sysv/consts/SO_ATTACH_REUSEPORT_EBPF.S deleted file mode 100644 index abb627c7a..000000000 --- a/libc/sysv/consts/SO_ATTACH_REUSEPORT_EBPF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_ATTACH_REUSEPORT_EBPF,52,52,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_BINDTODEVICE.S b/libc/sysv/consts/SO_BINDTODEVICE.S deleted file mode 100644 index 9bcdb11a1..000000000 --- a/libc/sysv/consts/SO_BINDTODEVICE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_BINDTODEVICE,25,25,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_BPF_EXTENSIONS.S b/libc/sysv/consts/SO_BPF_EXTENSIONS.S deleted file mode 100644 index 7868e2a84..000000000 --- a/libc/sysv/consts/SO_BPF_EXTENSIONS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_BPF_EXTENSIONS,48,48,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_BSDCOMPAT.S b/libc/sysv/consts/SO_BSDCOMPAT.S deleted file mode 100644 index 3e73082c3..000000000 --- a/libc/sysv/consts/SO_BSDCOMPAT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_BSDCOMPAT,14,14,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_BUSY_POLL.S b/libc/sysv/consts/SO_BUSY_POLL.S deleted file mode 100644 index 51034741e..000000000 --- a/libc/sysv/consts/SO_BUSY_POLL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_BUSY_POLL,46,46,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_CNX_ADVICE.S b/libc/sysv/consts/SO_CNX_ADVICE.S deleted file mode 100644 index 78058fc3c..000000000 --- a/libc/sysv/consts/SO_CNX_ADVICE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_CNX_ADVICE,53,53,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_DETACH_BPF.S b/libc/sysv/consts/SO_DETACH_BPF.S deleted file mode 100644 index ea5e67b91..000000000 --- a/libc/sysv/consts/SO_DETACH_BPF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_DETACH_BPF,27,27,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_DETACH_FILTER.S b/libc/sysv/consts/SO_DETACH_FILTER.S deleted file mode 100644 index 4068e7025..000000000 --- a/libc/sysv/consts/SO_DETACH_FILTER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_DETACH_FILTER,27,27,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_DOMAIN.S b/libc/sysv/consts/SO_DOMAIN.S deleted file mode 100644 index 1be02004f..000000000 --- a/libc/sysv/consts/SO_DOMAIN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_DOMAIN,39,39,0,0,0x1019,0x1024,0,0 diff --git a/libc/sysv/consts/SO_DONTLINGER.S b/libc/sysv/consts/SO_DONTLINGER.S deleted file mode 100644 index 67491dbfd..000000000 --- a/libc/sysv/consts/SO_DONTLINGER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_DONTLINGER,0,0,0,0,0,0,0,~0x80 diff --git a/libc/sysv/consts/SO_EXCLUSIVEADDRUSE.S b/libc/sysv/consts/SO_EXCLUSIVEADDRUSE.S deleted file mode 100644 index bb609fde6..000000000 --- a/libc/sysv/consts/SO_EXCLUSIVEADDRUSE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_EXCLUSIVEADDRUSE,0,0,0,0,0,0,0,0xfffffffb diff --git a/libc/sysv/consts/SO_GET_FILTER.S b/libc/sysv/consts/SO_GET_FILTER.S deleted file mode 100644 index 4a1710474..000000000 --- a/libc/sysv/consts/SO_GET_FILTER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_GET_FILTER,26,26,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_INCOMING_CPU.S b/libc/sysv/consts/SO_INCOMING_CPU.S deleted file mode 100644 index af10fc5d1..000000000 --- a/libc/sysv/consts/SO_INCOMING_CPU.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_INCOMING_CPU,49,49,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_LOCK_FILTER.S b/libc/sysv/consts/SO_LOCK_FILTER.S deleted file mode 100644 index f01b8f2a1..000000000 --- a/libc/sysv/consts/SO_LOCK_FILTER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_LOCK_FILTER,44,44,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_MARK.S b/libc/sysv/consts/SO_MARK.S deleted file mode 100644 index 0b7a152a4..000000000 --- a/libc/sysv/consts/SO_MARK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_MARK,36,36,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_MAX_PACING_RATE.S b/libc/sysv/consts/SO_MAX_PACING_RATE.S deleted file mode 100644 index b5dba9a26..000000000 --- a/libc/sysv/consts/SO_MAX_PACING_RATE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_MAX_PACING_RATE,47,47,0,0,0x1018,0,0,0 diff --git a/libc/sysv/consts/SO_NOFCS.S b/libc/sysv/consts/SO_NOFCS.S deleted file mode 100644 index 0c42ce3e2..000000000 --- a/libc/sysv/consts/SO_NOFCS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_NOFCS,43,43,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_NO_CHECK.S b/libc/sysv/consts/SO_NO_CHECK.S deleted file mode 100644 index ba6a7be05..000000000 --- a/libc/sysv/consts/SO_NO_CHECK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_NO_CHECK,11,11,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PASSCRED.S b/libc/sysv/consts/SO_PASSCRED.S deleted file mode 100644 index 9336292ad..000000000 --- a/libc/sysv/consts/SO_PASSCRED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PASSCRED,0x10,0x10,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PASSSEC.S b/libc/sysv/consts/SO_PASSSEC.S deleted file mode 100644 index 27e6a839a..000000000 --- a/libc/sysv/consts/SO_PASSSEC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PASSSEC,34,34,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PEEK_OFF.S b/libc/sysv/consts/SO_PEEK_OFF.S deleted file mode 100644 index 2b9e54f31..000000000 --- a/libc/sysv/consts/SO_PEEK_OFF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PEEK_OFF,42,42,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PEERCRED.S b/libc/sysv/consts/SO_PEERCRED.S deleted file mode 100644 index 1c4aba7d3..000000000 --- a/libc/sysv/consts/SO_PEERCRED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PEERCRED,17,17,0,0,0,0x1022,0,0 diff --git a/libc/sysv/consts/SO_PEERNAME.S b/libc/sysv/consts/SO_PEERNAME.S deleted file mode 100644 index 0d033acb9..000000000 --- a/libc/sysv/consts/SO_PEERNAME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PEERNAME,28,28,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PEERSEC.S b/libc/sysv/consts/SO_PEERSEC.S deleted file mode 100644 index ef45c34e4..000000000 --- a/libc/sysv/consts/SO_PEERSEC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PEERSEC,31,31,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PRIORITY.S b/libc/sysv/consts/SO_PRIORITY.S deleted file mode 100644 index 9559fab0e..000000000 --- a/libc/sysv/consts/SO_PRIORITY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PRIORITY,12,12,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_PROTOCOL.S b/libc/sysv/consts/SO_PROTOCOL.S deleted file mode 100644 index b63c921a9..000000000 --- a/libc/sysv/consts/SO_PROTOCOL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_PROTOCOL,38,38,0,0,0x1016,0x1025,0,0 diff --git a/libc/sysv/consts/SO_RCVBUFFORCE.S b/libc/sysv/consts/SO_RCVBUFFORCE.S deleted file mode 100644 index ad9f2bbed..000000000 --- a/libc/sysv/consts/SO_RCVBUFFORCE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_RCVBUFFORCE,33,33,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_REUSEPORT.S b/libc/sysv/consts/SO_REUSEPORT.S index f1f66930f..c1b3e8dd0 100644 --- a/libc/sysv/consts/SO_REUSEPORT.S +++ b/libc/sysv/consts/SO_REUSEPORT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_REUSEPORT,15,15,0x0200,0x0200,0x0200,0x0200,0x0200,4 +.syscon so,SO_REUSEPORT,15,15,0x0200,0x0200,0x0200,0x0200,0x0200,0 diff --git a/libc/sysv/consts/SO_RXQ_OVFL.S b/libc/sysv/consts/SO_RXQ_OVFL.S deleted file mode 100644 index 2f94588cc..000000000 --- a/libc/sysv/consts/SO_RXQ_OVFL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_RXQ_OVFL,40,40,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_SECURITY_AUTHENTICATION.S b/libc/sysv/consts/SO_SECURITY_AUTHENTICATION.S deleted file mode 100644 index 7832f02df..000000000 --- a/libc/sysv/consts/SO_SECURITY_AUTHENTICATION.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_SECURITY_AUTHENTICATION,22,22,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_SECURITY_ENCRYPTION_NETWORK.S b/libc/sysv/consts/SO_SECURITY_ENCRYPTION_NETWORK.S deleted file mode 100644 index 43736217d..000000000 --- a/libc/sysv/consts/SO_SECURITY_ENCRYPTION_NETWORK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_SECURITY_ENCRYPTION_NETWORK,24,24,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_SECURITY_ENCRYPTION_TRANSPORT.S b/libc/sysv/consts/SO_SECURITY_ENCRYPTION_TRANSPORT.S deleted file mode 100644 index 2998ef772..000000000 --- a/libc/sysv/consts/SO_SECURITY_ENCRYPTION_TRANSPORT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_SECURITY_ENCRYPTION_TRANSPORT,23,23,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_SELECT_ERR_QUEUE.S b/libc/sysv/consts/SO_SELECT_ERR_QUEUE.S deleted file mode 100644 index a74aa8631..000000000 --- a/libc/sysv/consts/SO_SELECT_ERR_QUEUE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_SELECT_ERR_QUEUE,45,45,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_SETFIB.S b/libc/sysv/consts/SO_SETFIB.S deleted file mode 100644 index 43cf6b9f5..000000000 --- a/libc/sysv/consts/SO_SETFIB.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_SETFIB,0,0,0,0,0x1014,0,0,0 diff --git a/libc/sysv/consts/SO_SNDBUFFORCE.S b/libc/sysv/consts/SO_SNDBUFFORCE.S deleted file mode 100644 index 142711461..000000000 --- a/libc/sysv/consts/SO_SNDBUFFORCE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_SNDBUFFORCE,0x20,0x20,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_TIMESTAMP.S b/libc/sysv/consts/SO_TIMESTAMP.S deleted file mode 100644 index bcac46be1..000000000 --- a/libc/sysv/consts/SO_TIMESTAMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_TIMESTAMP,29,29,0x0400,0x0400,0x0400,0x0800,0x2000,0 diff --git a/libc/sysv/consts/SO_TIMESTAMPING.S b/libc/sysv/consts/SO_TIMESTAMPING.S deleted file mode 100644 index c5502ed4c..000000000 --- a/libc/sysv/consts/SO_TIMESTAMPING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_TIMESTAMPING,37,37,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_TIMESTAMPNS.S b/libc/sysv/consts/SO_TIMESTAMPNS.S deleted file mode 100644 index 1f7d236cb..000000000 --- a/libc/sysv/consts/SO_TIMESTAMPNS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_TIMESTAMPNS,35,35,0,0,0,0,0,0 diff --git a/libc/sysv/consts/SO_WIFI_STATUS.S b/libc/sysv/consts/SO_WIFI_STATUS.S deleted file mode 100644 index 0d650a248..000000000 --- a/libc/sysv/consts/SO_WIFI_STATUS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon so,SO_WIFI_STATUS,41,41,0,0,0,0,0,0 diff --git a/libc/sysv/consts/alg.h b/libc/sysv/consts/alg.h deleted file mode 100644 index cb6f74dc2..000000000 --- a/libc/sysv/consts/alg.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ALG_H_ -#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ALG_H_ - -#define ALG_SET_AEAD_ASSOCLEN ALG_SET_AEAD_ASSOCLEN -#define ALG_SET_AEAD_AUTHSIZE ALG_SET_AEAD_AUTHSIZE -#define ALG_SET_DRBG_ENTROPY ALG_SET_DRBG_ENTROPY -#define ALG_SET_IV ALG_SET_IV -#define ALG_SET_KEY ALG_SET_KEY -#define ALG_SET_OP ALG_SET_OP - -#define ALG_OP_DECRYPT ALG_OP_DECRYPT -#define ALG_OP_ENCRYPT ALG_OP_ENCRYPT - -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const int ALG_SET_AEAD_ASSOCLEN; -extern const int ALG_SET_AEAD_AUTHSIZE; -extern const int ALG_SET_DRBG_ENTROPY; -extern const int ALG_SET_IV; -extern const int ALG_SET_KEY; -extern const int ALG_SET_OP; - -extern const int ALG_OP_DECRYPT; -extern const int ALG_OP_ENCRYPT; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ALG_H_ */ diff --git a/libc/sysv/consts/at.h b/libc/sysv/consts/at.h index 8a36c7408..7663fecde 100644 --- a/libc/sysv/consts/at.h +++ b/libc/sysv/consts/at.h @@ -22,8 +22,5 @@ COSMOPOLITAN_C_END_ #define AT_SYMLINK_FOLLOW AT_SYMLINK_FOLLOW #define AT_SYMLINK_NOFOLLOW AT_SYMLINK_NOFOLLOW #define AT_REMOVEDIR AT_REMOVEDIR -#define AT_EACCESS AT_EACCESS -#define AT_EMPTY_PATH AT_EMPTY_PATH - #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AT_H_ */ diff --git a/libc/sysv/consts/baud.internal.h b/libc/sysv/consts/baud.internal.h index decb72c64..8b279c494 100644 --- a/libc/sysv/consts/baud.internal.h +++ b/libc/sysv/consts/baud.internal.h @@ -63,7 +63,6 @@ extern const uint32_t B4000000; #define B3500000 B3500000 #define B4000000 B4000000 - COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_BAUD_H_ */ diff --git a/libc/sysv/consts/clock.h b/libc/sysv/consts/clock.h index c2c0b620b..1a0ac068c 100644 --- a/libc/sysv/consts/clock.h +++ b/libc/sysv/consts/clock.h @@ -29,5 +29,4 @@ COSMOPOLITAN_C_END_ #define CLOCK_REALTIME 0 #define CLOCK_MONOTONIC CLOCK_MONOTONIC - #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLOCK_H_ */ diff --git a/libc/sysv/consts/epoll.h b/libc/sysv/consts/epoll.h index 1b8ad3ed5..44dd42cec 100644 --- a/libc/sysv/consts/epoll.h +++ b/libc/sysv/consts/epoll.h @@ -1,32 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_EPOLL_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_EPOLL_H_ #include "libc/sysv/consts/o.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const int EPOLL_CLOEXEC; - -extern const int EPOLL_CTL_ADD; -extern const int EPOLL_CTL_DEL; -extern const int EPOLL_CTL_MOD; - -extern const uint32_t EPOLLIN; -extern const uint32_t EPOLLPRI; -extern const uint32_t EPOLLOUT; -extern const uint32_t EPOLLERR; -extern const uint32_t EPOLLHUP; -extern const uint32_t EPOLLRDNORM; -extern const uint32_t EPOLLRDBAND; -extern const uint32_t EPOLLWRNORM; -extern const uint32_t EPOLLWRBAND; -extern const uint32_t EPOLLMSG; -extern const uint32_t EPOLLRDHUP; -extern const uint32_t EPOLLEXCLUSIVE; -extern const uint32_t EPOLLWAKEUP; -extern const uint32_t EPOLLONESHOT; -extern const uint32_t EPOLLET; - -#define EPOLL_CLOEXEC O_CLOEXEC #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_DEL 2 @@ -48,6 +22,12 @@ extern const uint32_t EPOLLET; #define EPOLLONESHOT 0x40000000 #define EPOLLET 0x80000000 +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern const int EPOLL_CLOEXEC; +#define EPOLL_CLOEXEC O_CLOEXEC + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_EPOLL_H_ */ diff --git a/libc/sysv/consts/ipproto.h b/libc/sysv/consts/ipproto.h index d1c524162..03425a23b 100644 --- a/libc/sysv/consts/ipproto.h +++ b/libc/sysv/consts/ipproto.h @@ -1,78 +1,13 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPROTO_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPROTO_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -extern const int IPPROTO_AH; -extern const int IPPROTO_BEETPH; -extern const int IPPROTO_COMP; -extern const int IPPROTO_DCCP; -extern const int IPPROTO_DSTOPTS; -extern const int IPPROTO_EGP; -extern const int IPPROTO_ENCAP; -extern const int IPPROTO_ESP; -extern const int IPPROTO_FRAGMENT; -extern const int IPPROTO_GRE; -extern const int IPPROTO_HOPOPTS; -extern const int IPPROTO_ICMP; -extern const int IPPROTO_ICMPV6; -extern const int IPPROTO_IDP; -extern const int IPPROTO_IGMP; -extern const int IPPROTO_IP; -extern const int IPPROTO_IPIP; -extern const int IPPROTO_IPV6; -extern const int IPPROTO_MAX; -extern const int IPPROTO_MH; -extern const int IPPROTO_MPLS; -extern const int IPPROTO_MTP; -extern const int IPPROTO_NONE; -extern const int IPPROTO_PIM; -extern const int IPPROTO_PUP; -extern const int IPPROTO_RAW; -extern const int IPPROTO_ROUTING; -extern const int IPPROTO_RSVP; -extern const int IPPROTO_SCTP; -extern const int IPPROTO_TCP; -extern const int IPPROTO_TP; -extern const int IPPROTO_UDP; -extern const int IPPROTO_UDPLITE; +#define IPPROTO_IP 0 +#define IPPROTO_ICMP 1 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#define IPPROTO_IPV6 41 +#define IPPROTO_ICMPV6 58 +#define IPPROTO_RAW 255 +#define IPPROTO_MAX 263 /* xxx */ -#define IPPROTO_IP 0 -#define IPPROTO_ICMP 1 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 -#define IPPROTO_RAW 255 -#define IPPROTO_MAX 263 /* xxx */ - -#define IPPROTO_AH IPPROTO_AH -#define IPPROTO_BEETPH IPPROTO_BEETPH -#define IPPROTO_COMP IPPROTO_COMP -#define IPPROTO_DCCP IPPROTO_DCCP -#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS -#define IPPROTO_EGP IPPROTO_EGP -#define IPPROTO_ENCAP IPPROTO_ENCAP -#define IPPROTO_ESP IPPROTO_ESP -#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT -#define IPPROTO_GRE IPPROTO_GRE -#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS -#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 -#define IPPROTO_IDP IPPROTO_IDP -#define IPPROTO_IGMP IPPROTO_IGMP -#define IPPROTO_IPIP IPPROTO_IPIP -#define IPPROTO_IPV6 IPPROTO_IPV6 -#define IPPROTO_MH IPPROTO_MH -#define IPPROTO_MPLS IPPROTO_MPLS -#define IPPROTO_MTP IPPROTO_MTP -#define IPPROTO_NONE IPPROTO_NONE -#define IPPROTO_PIM IPPROTO_PIM -#define IPPROTO_PUP IPPROTO_PUP -#define IPPROTO_ROUTING IPPROTO_ROUTING -#define IPPROTO_RSVP IPPROTO_RSVP -#define IPPROTO_SCTP IPPROTO_SCTP -#define IPPROTO_TP IPPROTO_TP -#define IPPROTO_UDPLITE IPPROTO_UDPLITE - - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_IPPROTO_H_ */ diff --git a/libc/sysv/consts/o.h b/libc/sysv/consts/o.h index 2d280138b..35780fc41 100644 --- a/libc/sysv/consts/o.h +++ b/libc/sysv/consts/o.h @@ -36,7 +36,7 @@ extern const unsigned O_SEQUENTIAL; extern const unsigned O_SHLOCK; extern const unsigned O_SPARSE; extern const unsigned O_SYNC; -extern const unsigned O_TMPFILE; +extern const unsigned O_TMPFILE; /* use tmpfd() or tmpfile() */ extern const unsigned O_TRUNC; extern const unsigned O_TTY_INIT; extern const unsigned O_VERIFY; @@ -62,7 +62,6 @@ extern const unsigned O_VERIFY; #define O_SYNC O_SYNC #define O_TRUNC O_TRUNC - COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_O_H_ */ diff --git a/libc/sysv/consts/so.h b/libc/sysv/consts/so.h index a46eb5d9d..d32ae9fc3 100644 --- a/libc/sysv/consts/so.h +++ b/libc/sysv/consts/so.h @@ -1,130 +1,51 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_SO_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -extern const int LOCAL_PEERCRED; -extern const int SO_ACCEPTCONN; -extern const int SO_ATTACH_BPF; -extern const int SO_ATTACH_FILTER; -extern const int SO_ATTACH_REUSEPORT_CBPF; -extern const int SO_ATTACH_REUSEPORT_EBPF; -extern const int SO_BINDTODEVICE; -extern const int SO_BPF_EXTENSIONS; -extern const int SO_BROADCAST; -extern const int SO_BSDCOMPAT; -extern const int SO_BUSY_POLL; -extern const int SO_CNX_ADVICE; -extern const int SO_DEBUG; -extern const int SO_DETACH_BPF; -extern const int SO_DETACH_FILTER; -extern const int SO_DOMAIN; -extern const int SO_DONTROUTE; -extern const int SO_ERROR; -extern const int SO_EXCLUSIVEADDRUSE; -extern const int SO_GET_FILTER; -extern const int SO_INCOMING_CPU; -extern const int SO_KEEPALIVE; -extern const int SO_LINGER; -extern const int SO_LOCK_FILTER; -extern const int SO_MARK; -extern const int SO_MAX_PACING_RATE; -extern const int SO_NOFCS; -extern const int SO_NO_CHECK; -extern const int SO_OOBINLINE; -extern const int SO_PASSCRED; -extern const int SO_PASSSEC; -extern const int SO_PEEK_OFF; -extern const int SO_PEERCRED; -extern const int SO_PEERNAME; -extern const int SO_PEERSEC; -extern const int SO_PRIORITY; -extern const int SO_PROTOCOL; -extern const int SO_RCVBUF; -extern const int SO_RCVBUFFORCE; -extern const int SO_RCVLOWAT; -extern const int SO_RCVTIMEO; -extern const int SO_REUSEADDR; -extern const int SO_REUSEPORT; -extern const int SO_RXQ_OVFL; -extern const int SO_SECURITY_AUTHENTICATION; -extern const int SO_SECURITY_ENCRYPTION_NETWORK; -extern const int SO_SECURITY_ENCRYPTION_TRANSPORT; -extern const int SO_SELECT_ERR_QUEUE; -extern const int SO_SETFIB; -extern const int SO_SNDBUF; -extern const int SO_SNDBUFFORCE; -extern const int SO_SNDLOWAT; -extern const int SO_SNDTIMEO; -extern const int SO_TIMESTAMP; -extern const int SO_TIMESTAMPING; -extern const int SO_TIMESTAMPNS; -extern const int SO_TYPE; -extern const int SO_USELOOPBACK; -extern const int SO_WIFI_STATUS; #define SO_DEBUG 1 -#define LOCAL_PEERCRED LOCAL_PEERCRED -#define SO_ACCEPTCONN SO_ACCEPTCONN -#define SO_ATTACH_BPF SO_ATTACH_BPF -#define SO_ATTACH_FILTER SO_ATTACH_FILTER -#define SO_ATTACH_REUSEPORT_CBPF SO_ATTACH_REUSEPORT_CBPF -#define SO_ATTACH_REUSEPORT_EBPF SO_ATTACH_REUSEPORT_EBPF -#define SO_BINDTODEVICE SO_BINDTODEVICE -#define SO_BPF_EXTENSIONS SO_BPF_EXTENSIONS -#define SO_BROADCAST SO_BROADCAST -#define SO_BSDCOMPAT SO_BSDCOMPAT -#define SO_BUSY_POLL SO_BUSY_POLL -#define SO_CNX_ADVICE SO_CNX_ADVICE -#define SO_DETACH_BPF SO_DETACH_BPF -#define SO_DETACH_FILTER SO_DETACH_FILTER -#define SO_DOMAIN SO_DOMAIN -#define SO_DONTROUTE SO_DONTROUTE -#define SO_ERROR SO_ERROR -#define SO_EXCLUSIVEADDRUSE SO_EXCLUSIVEADDRUSE -#define SO_GET_FILTER SO_GET_FILTER -#define SO_INCOMING_CPU SO_INCOMING_CPU -#define SO_KEEPALIVE SO_KEEPALIVE -#define SO_LINGER SO_LINGER -#define SO_LOCK_FILTER SO_LOCK_FILTER -#define SO_MARK SO_MARK -#define SO_MAX_PACING_RATE SO_MAX_PACING_RATE -#define SO_NOFCS SO_NOFCS -#define SO_NO_CHECK SO_NO_CHECK -#define SO_OOBINLINE SO_OOBINLINE -#define SO_PASSCRED SO_PASSCRED -#define SO_PASSSEC SO_PASSSEC -#define SO_PEEK_OFF SO_PEEK_OFF -#define SO_PEERCRED SO_PEERCRED -#define SO_PEERNAME SO_PEERNAME -#define SO_PEERSEC SO_PEERSEC -#define SO_PRIORITY SO_PRIORITY -#define SO_PROTOCOL SO_PROTOCOL -#define SO_RCVBUF SO_RCVBUF -#define SO_RCVBUFFORCE SO_RCVBUFFORCE -#define SO_RCVLOWAT SO_RCVLOWAT -#define SO_RCVTIMEO SO_RCVTIMEO -#define SO_REUSEADDR SO_REUSEADDR -#define SO_REUSEPORT SO_REUSEPORT -#define SO_RXQ_OVFL SO_RXQ_OVFL -#define SO_SELECT_ERR_QUEUE SO_SELECT_ERR_QUEUE -#define SO_SETFIB SO_SETFIB -#define SO_SNDBUF SO_SNDBUF -#define SO_SNDBUFFORCE SO_SNDBUFFORCE -#define SO_SNDLOWAT SO_SNDLOWAT -#define SO_SNDTIMEO SO_SNDTIMEO -#define SO_TIMESTAMP SO_TIMESTAMP -#define SO_TIMESTAMPING SO_TIMESTAMPING -#define SO_TIMESTAMPNS SO_TIMESTAMPNS -#define SO_TYPE SO_TYPE -#define SO_USELOOPBACK SO_USELOOPBACK -#define SO_WIFI_STATUS SO_WIFI_STATUS +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ -#define SO_SECURITY_AUTHENTICATION SO_SECURITY_AUTHENTICATION -#define SO_SECURITY_ENCRYPTION_NETWORK SO_SECURITY_ENCRYPTION_NETWORK -#define SO_SECURITY_ENCRYPTION_TRANSPORT SO_SECURITY_ENCRYPTION_TRANSPORT +extern const int SO_TYPE; +extern const int SO_ERROR; +extern const int SO_ACCEPTCONN; +extern const int SO_REUSEADDR; +extern const int SO_KEEPALIVE; +extern const int SO_DONTROUTE; +extern const int SO_BROADCAST; +extern const int SO_USELOOPBACK; +extern const int SO_LINGER; +extern const int SO_OOBINLINE; +extern const int SO_SNDBUF; +extern const int SO_RCVBUF; +extern const int SO_RCVTIMEO; +extern const int SO_SNDTIMEO; +extern const int SO_RCVLOWAT; +extern const int SO_SNDLOWAT; +#define SO_TYPE SO_TYPE +#define SO_ERROR SO_ERROR +#define SO_ACCEPTCONN SO_ACCEPTCONN +#define SO_REUSEADDR SO_REUSEADDR +#define SO_KEEPALIVE SO_KEEPALIVE +#define SO_DONTROUTE SO_DONTROUTE +#define SO_BROADCAST SO_BROADCAST +#define SO_USELOOPBACK SO_USELOOPBACK +#define SO_LINGER SO_LINGER +#define SO_OOBINLINE SO_OOBINLINE +#define SO_SNDBUF SO_SNDBUF +#define SO_RCVBUF SO_RCVBUF +#define SO_RCVTIMEO SO_RCVTIMEO +#define SO_SNDTIMEO SO_SNDTIMEO +#define SO_RCVLOWAT SO_RCVLOWAT +#define SO_SNDLOWAT SO_SNDLOWAT + +/* + * this isn't available on windows, but it should be fine to use anyway, + * setsockopt will return ENOPROTOOPT which is perfectly fine to ignore. + */ +extern const int SO_REUSEPORT; +#define SO_REUSEPORT SO_REUSEPORT COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/sysv/consts/sol.h b/libc/sysv/consts/sol.h index e2ff7e688..3ecb1bc7f 100644 --- a/libc/sysv/consts/sol.h +++ b/libc/sysv/consts/sol.h @@ -1,69 +1,20 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ + +#define SOL_IP 0 +#define SOL_ICMP 1 +#define SOL_TCP 6 +#define SOL_UDP 17 +#define SOL_IPV6 41 +#define SOL_ICMPV6 58 +#define SOL_RAW 255 + #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const int SOL_AAL; -extern const int SOL_ALG; -extern const int SOL_ATM; -extern const int SOL_BLUETOOTH; -extern const int SOL_CAIF; -extern const int SOL_DCCP; -extern const int SOL_DECNET; -extern const int SOL_ICMPV6; -extern const int SOL_IP; -extern const int SOL_IPV6; -extern const int SOL_IRDA; -extern const int SOL_IUCV; -extern const int SOL_KCM; -extern const int SOL_LLC; -extern const int SOL_NETBEUI; -extern const int SOL_NETLINK; -extern const int SOL_NFC; -extern const int SOL_PACKET; -extern const int SOL_PNPIPE; -extern const int SOL_PPPOL2TP; -extern const int SOL_RAW; -extern const int SOL_RDS; -extern const int SOL_RXRPC; extern const int SOL_SOCKET; -extern const int SOL_TCP; -extern const int SOL_TIPC; -extern const int SOL_UDP; -extern const int SOL_X25; +#define SOL_SOCKET SOL_SOCKET COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ - -#define SOL_IP 0 -#define SOL_TCP 6 -#define SOL_UDP 17 - -#define SOL_AAL SOL_AAL -#define SOL_ALG SOL_ALG -#define SOL_ATM SOL_ATM -#define SOL_BLUETOOTH SOL_BLUETOOTH -#define SOL_CAIF SOL_CAIF -#define SOL_DCCP SOL_DCCP -#define SOL_DECNET SOL_DECNET -#define SOL_ICMPV6 SOL_ICMPV6 -#define SOL_IPV6 SOL_IPV6 -#define SOL_IRDA SOL_IRDA -#define SOL_IUCV SOL_IUCV -#define SOL_KCM SOL_KCM -#define SOL_LLC SOL_LLC -#define SOL_NETBEUI SOL_NETBEUI -#define SOL_NETLINK SOL_NETLINK -#define SOL_NFC SOL_NFC -#define SOL_PACKET SOL_PACKET -#define SOL_PNPIPE SOL_PNPIPE -#define SOL_PPPOL2TP SOL_PPPOL2TP -#define SOL_RAW SOL_RAW -#define SOL_RDS SOL_RDS -#define SOL_RXRPC SOL_RXRPC -#define SOL_SOCKET SOL_SOCKET -#define SOL_TIPC SOL_TIPC -#define SOL_X25 SOL_X25 - - #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SOL_H_ */ diff --git a/libc/testlib/quota.c b/libc/testlib/quota.c index ea4bf84ef..f6e93b71e 100644 --- a/libc/testlib/quota.c +++ b/libc/testlib/quota.c @@ -20,6 +20,7 @@ #include "libc/calls/struct/sigaction.h" #include "libc/errno.h" #include "libc/intrin/bits.h" +#include "libc/intrin/bsr.h" #include "libc/intrin/kprintf.h" #include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" @@ -64,6 +65,10 @@ static relegated void OnXfsz(int sig) { DieBecauseOfQuota(25, "\n\nSIGXFSZ: exceeded maximum file size"); } +static unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; +} + relegated void __oom_hook(size_t request) { int e; uint64_t toto, newlim; @@ -75,7 +80,7 @@ relegated void __oom_hook(size_t request) { if (IsRunningUnderMake()) { newlim = toto + request; newlim += newlim >> 1; - newlim = _roundup2pow(newlim); + newlim = roundup2pow(newlim); kprintf("FIX CODE OR TUNE QUOTA += -M%dm\n", newlim / (1024 * 1024)); } kprintf("\n"); diff --git a/libc/thread/pthread_cancel.c b/libc/thread/pthread_cancel.c index 882cab2a9..9757834cc 100644 --- a/libc/thread/pthread_cancel.c +++ b/libc/thread/pthread_cancel.c @@ -54,9 +54,11 @@ int _pthread_cancel_sys(void) { static void OnSigThr(int sig, siginfo_t *si, void *ctx) { ucontext_t *uc = ctx; - struct CosmoTib *t = __get_tls(); - struct PosixThread *pt = (struct PosixThread *)t->tib_pthread; - if (pt && !(pt->flags & PT_NOCANCEL) && + struct CosmoTib *t; + struct PosixThread *pt; + if ((t = __get_tls()) && // TODO: why can it be null on freebsd? + (pt = (struct PosixThread *)t->tib_pthread) && + !(pt->flags & PT_NOCANCEL) && atomic_load_explicit(&pt->cancelled, memory_order_acquire)) { sigaddset(&uc->uc_sigmask, sig); if (systemfive_cancellable <= (char *)uc->uc_mcontext.rip && @@ -255,14 +257,21 @@ static void ListenForSigThr(void) { * while running read(). Masked mode doesn't have second chances. You * must rigorously check the results of each cancellation point call. * + * Unit tests should be able to safely ignore the return value, or at + * the very least be programmed to consider ESRCH a successful status + * * @return 0 on success, or errno on error - * @raise ESRCH if thread isn't alive + * @raise ESRCH if system thread wasn't alive or we lost a race */ errno_t pthread_cancel(pthread_t thread) { int e, rc, tid; static bool once; struct PosixThread *pt; - if (!once) ListenForSigThr(), once = true; + __require_tls(); + if (!once) { + ListenForSigThr(); + once = true; + } pt = (struct PosixThread *)thread; switch (atomic_load_explicit(&pt->status, memory_order_acquire)) { case kPosixThreadZombie: diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 8ac005e80..0e807fb9d 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -26,6 +26,7 @@ #include "libc/intrin/asan.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bits.h" +#include "libc/intrin/bsr.h" #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/log/internal.h" @@ -53,6 +54,10 @@ __static_yoink("_pthread_atfork"); #define MAP_ANON_OPENBSD 0x1000 #define MAP_STACK_OPENBSD 0x4000 +static unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; +} + void _pthread_free(struct PosixThread *pt) { if (pt->flags & PT_STATIC) return; free(pt->tls); @@ -104,13 +109,14 @@ static int FixupCustomStackOnOpenbsd(pthread_attr_t *attr) { // in order to successfully call mmap(), which will return EINVAL if // these calculations should overflow. size_t n; - int e, rc; uintptr_t x, y; + int e, rc, pagesz; + pagesz = getauxval(AT_PAGESZ); n = attr->__stacksize; x = (uintptr_t)attr->__stackaddr; - y = ROUNDUP(x, PAGESIZE); + y = ROUNDUP(x, pagesz); n -= y - x; - n = ROUNDDOWN(n, PAGESIZE); + n = ROUNDDOWN(n, pagesz); e = errno; if (__sys_mmap((void *)y, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANON_OPENBSD | MAP_STACK_OPENBSD, @@ -176,7 +182,7 @@ static errno_t pthread_create_impl(pthread_t *thread, default_guardsize = getauxval(AT_PAGESZ); pt->flags = PT_OWNSTACK; pt->attr.__stacksize = MAX(pt->attr.__stacksize, GetStackSize()); - pt->attr.__stacksize = _roundup2pow(pt->attr.__stacksize); + pt->attr.__stacksize = roundup2pow(pt->attr.__stacksize); pt->attr.__guardsize = ROUNDUP(pt->attr.__guardsize, default_guardsize); if (pt->attr.__guardsize + default_guardsize >= pt->attr.__stacksize) { _pthread_free(pt); diff --git a/libc/intrin/pthread_once.c b/libc/thread/pthread_once.c similarity index 70% rename from libc/intrin/pthread_once.c rename to libc/thread/pthread_once.c index 05e969f79..25f603ca9 100644 --- a/libc/intrin/pthread_once.c +++ b/libc/thread/pthread_once.c @@ -16,17 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/errno.h" -#include "libc/intrin/atomic.h" -#include "libc/intrin/weaken.h" #include "libc/thread/thread.h" #include "third_party/nsync/once.h" -#define INIT 0 -#define CALLING 1 -#define FINISHED 2 - /** * Ensures initialization function is called exactly once, e.g. * @@ -42,33 +34,13 @@ * return g_factory; * } * + * If multiple threads try to initialize at the same time, then only a + * single one will call `init` and the other threads will block until + * the winner has returned from the `init` function. + * * @return 0 on success, or errno on error */ errno_t pthread_once(pthread_once_t *once, void init(void)) { - uint32_t old; - if (_weaken(nsync_run_once)) { - _weaken(nsync_run_once)((nsync_once *)once, init); - return 0; - } - switch ((old = atomic_load_explicit(&once->_lock, memory_order_relaxed))) { - case INIT: - if (atomic_compare_exchange_strong_explicit(&once->_lock, &old, CALLING, - memory_order_acquire, - memory_order_relaxed)) { - init(); - atomic_store_explicit(&once->_lock, FINISHED, memory_order_release); - return 0; - } - // fallthrough - case CALLING: - do { - pthread_yield(); - } while (atomic_load_explicit(&once->_lock, memory_order_acquire) == - CALLING); - return 0; - case FINISHED: - return 0; - default: - return EINVAL; - } + nsync_run_once((nsync_once *)once, init); + return 0; } diff --git a/libc/thread/sem_open.c b/libc/thread/sem_open.c index 5c8a48762..02f0c55d3 100644 --- a/libc/thread/sem_open.c +++ b/libc/thread/sem_open.c @@ -86,11 +86,11 @@ static sem_t *sem_open_impl(const char *path, int oflag, unsigned mode, return SEM_FAILED; } npassert(!fstat(fd, &st)); - if (st.st_size < PAGESIZE && ftruncate(fd, PAGESIZE) == -1) { + if (st.st_size < 4096 && ftruncate(fd, 4096) == -1) { npassert(!close(fd)); return SEM_FAILED; } - sem = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + sem = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (sem != MAP_FAILED) { atomic_store_explicit(&sem->sem_value, value, memory_order_relaxed); sem->sem_magic = SEM_MAGIC_NAMED; @@ -272,7 +272,7 @@ int sem_close(sem_t *sem) { } sem_open_unlock(); if (unmap) { - npassert(!munmap(sem, PAGESIZE)); + npassert(!munmap(sem, 4096)); } if (delete) { unlink(s->path); diff --git a/libc/thread/thread.h b/libc/thread/thread.h index c13a84655..798b51488 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -146,7 +146,7 @@ int pthread_condattr_destroy(pthread_condattr_t *) paramsnonnull(); int pthread_condattr_getpshared(const pthread_condattr_t *, int *) paramsnonnull(); int pthread_condattr_init(pthread_condattr_t *) paramsnonnull(); int pthread_condattr_setpshared(pthread_condattr_t *, int) paramsnonnull(); -int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *) paramsnonnull((1, 3)); +int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *) paramsnonnull((1)); int pthread_detach(pthread_t); int pthread_equal(pthread_t, pthread_t); int pthread_getattr_np(pthread_t, pthread_attr_t *) paramsnonnull(); diff --git a/libc/x/x.h b/libc/x/x.h index 587f6c991..e3da23ed7 100644 --- a/libc/x/x.h +++ b/libc/x/x.h @@ -91,7 +91,7 @@ char *xjoinpaths(const char *, const char *) paramsnonnull() void xfixpath(void); void *xslurp(const char *, size_t *) paramsnonnull((1)) returnspointerwithnoaliases - returnsaligned((PAGESIZE)) dontdiscard; + returnsaligned((4096)) dontdiscard; int xbarf(const char *, const void *, size_t); #endif /* COSMO */ diff --git a/libc/x/xslurp.c b/libc/x/xslurp.c index 8c2edfeb2..610859763 100644 --- a/libc/x/xslurp.c +++ b/libc/x/xslurp.c @@ -39,7 +39,7 @@ void *xslurp(const char *path, size_t *opt_out_size) { res = NULL; if ((fd = open(path, O_RDONLY)) != -1) { if ((size = lseek(fd, 0, SEEK_END)) != -1 && - (res = memalign(PAGESIZE, size + 1))) { + (res = memalign(4096, size + 1))) { if (size > 2 * 1024 * 1024) { fadvise(fd, 0, size, MADV_SEQUENTIAL); } diff --git a/net/https/getsslroots.c b/net/https/getsslroots.c index 8c78bffb0..4827da1cf 100644 --- a/net/https/getsslroots.c +++ b/net/https/getsslroots.c @@ -18,11 +18,11 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/struct/dirent.h" +#include "libc/cosmo.h" #include "libc/mem/mem.h" #include "libc/str/str.h" #include "libc/sysv/consts/dt.h" #include "libc/sysv/consts/o.h" -#include "libc/thread/thread.h" #include "third_party/mbedtls/x509_crt.h" __static_yoink("ssl_root_support"); @@ -30,7 +30,7 @@ __static_yoink("ssl_root_support"); #define SSL_ROOT_DIR "/zip/usr/share/ssl/root" static struct { - pthread_once_t once; + _Atomic(uint32_t) once; mbedtls_x509_crt chain; } g_ssl_roots; @@ -74,6 +74,6 @@ static void InitSslRoots(void) { * Returns singleton of SSL roots stored in /zip/usr/share/ssl/root/... */ mbedtls_x509_crt *GetSslRoots(void) { - pthread_once(&g_ssl_roots.once, InitSslRoots); + cosmo_once(&g_ssl_roots.once, InitSslRoots); return &g_ssl_roots.chain; } diff --git a/net/https/sslcache.c b/net/https/sslcache.c index fb602a810..68854bfc0 100644 --- a/net/https/sslcache.c +++ b/net/https/sslcache.c @@ -21,6 +21,7 @@ #include "libc/calls/struct/stat.h" #include "libc/errno.h" #include "libc/intrin/bits.h" +#include "libc/intrin/bsr.h" #include "libc/intrin/cmpxchg.h" #include "libc/intrin/safemacros.internal.h" #include "libc/log/check.h" @@ -79,12 +80,16 @@ static struct SslCache *OpenSslCache(const char *path, size_t size) { return c; } +static unsigned long rounddown2pow(unsigned long x) { + return x ? 1ul << _bsrl(x) : 0; +} + struct SslCache *CreateSslCache(const char *path, size_t bytes, int lifetime) { size_t ents, size; struct SslCache *c; if (!bytes) bytes = 10 * 1024 * 1024; if (lifetime <= 0) lifetime = 24 * 60 * 60; - ents = _rounddown2pow(MAX(2, bytes / sizeof(struct SslCacheEntry))); + ents = rounddown2pow(MAX(2, bytes / sizeof(struct SslCacheEntry))); size = sizeof(struct SslCache) + sizeof(struct SslCacheEntry) * ents; size = ROUNDUP(size, FRAMESIZE); c = OpenSslCache(path, size); diff --git a/test/libc/calls/execve_test.c b/test/libc/calls/execve_test.c index 7c2242d99..f6eaa6709 100644 --- a/test/libc/calls/execve_test.c +++ b/test/libc/calls/execve_test.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/struct/rusage.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" @@ -24,7 +25,9 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" #include "libc/runtime/runtime.h" +#include "libc/stdio/temp.h" #include "libc/str/str.h" +#include "libc/testlib/ezbench.h" #include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" @@ -93,4 +96,59 @@ TEST(execve, ziposAPE) { EXITS(42); } +// clang-format off +#define TINY_ELF_PROGRAM "\ +\177\105\114\106\002\001\001\000\000\000\000\000\000\000\000\000\ +\002\000\076\000\001\000\000\000\170\000\100\000\000\000\000\000\ +\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\100\000\070\000\001\000\000\000\000\000\000\000\ +\001\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\100\000\000\000\000\000\000\000\100\000\000\000\000\000\ +\200\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\ +\000\020\000\000\000\000\000\000\152\052\137\152\074\130\017\005" +// clang-format on + +void ExecvTinyElf(const char *path) { + int ws; + if (!vfork()) { + execv(path, (char *[]){path, 0}); + abort(); + } + ASSERT_NE(-1, wait(&ws)); + ASSERT_EQ(42, WEXITSTATUS(ws)); +} + +void ExecvpTinyElf(const char *path) { + int ws; + if (!vfork()) { + execvp(path, (char *[]){path, 0}); + abort(); + } + ASSERT_NE(-1, wait(&ws)); + ASSERT_EQ(42, WEXITSTATUS(ws)); +} + +void ExecveTinyElf(const char *path) { + int ws; + if (!vfork()) { + execve(path, (char *[]){path, 0}, (char *[]){0}); + abort(); + } + ASSERT_NE(-1, wait(&ws)); + ASSERT_EQ(42, WEXITSTATUS(ws)); +} + +BENCH(execve, bench) { + if (!IsLinux()) return; + char path[128] = "/tmp/tinyelf.XXXXXX"; + int fd = mkstemp(path); + fchmod(fd, 0700); + write(fd, TINY_ELF_PROGRAM, sizeof(TINY_ELF_PROGRAM)); + close(fd); + EZBENCH2("execv", donothing, ExecvTinyElf(path)); + EZBENCH2("execvp", donothing, ExecvpTinyElf(path)); + EZBENCH2("execve", donothing, ExecveTinyElf(path)); + unlink(path); +} + #endif diff --git a/test/libc/calls/pledge_test.c b/test/libc/calls/pledge_test.c index 317fa8b06..5fe4cd92f 100644 --- a/test/libc/calls/pledge_test.c +++ b/test/libc/calls/pledge_test.c @@ -348,7 +348,6 @@ TEST(pledge, inet_forbidsOtherSockets) { ASSERT_SYS(EPERM, -1, socket(AF_BLUETOOTH, SOCK_DGRAM, IPPROTO_UDP)); ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_RAW, IPPROTO_UDP)); ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_DGRAM, IPPROTO_RAW)); - ASSERT_SYS(EPERM, -1, setsockopt(3, SOL_SOCKET, SO_TIMESTAMP, &yes, 4)); struct sockaddr_in sin = {AF_INET, 0, {htonl(0x7f000001)}}; ASSERT_SYS(0, 0, bind(4, (struct sockaddr *)&sin, sizeof(sin))); struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6, @@ -372,7 +371,6 @@ TEST(pledge, anet_forbidsUdpSocketsAndConnect) { ASSERT_SYS(0, 0, pledge("stdio anet", 0)); ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); - ASSERT_SYS(EPERM, -1, setsockopt(3, SOL_SOCKET, SO_TIMESTAMP, &yes, 4)); struct sockaddr_in sin = {AF_INET, 0, {htonl(0x7f000001)}}; ASSERT_SYS(EPERM, -1, connect(4, (struct sockaddr *)&sin, sizeof(sin))); _Exit(0); diff --git a/test/libc/calls/_timespec_test.c b/test/libc/calls/timespec_test.c similarity index 100% rename from test/libc/calls/_timespec_test.c rename to test/libc/calls/timespec_test.c diff --git a/test/libc/intrin/pthread_once_test.c b/test/libc/intrin/cosmo_once_test.c similarity index 78% rename from test/libc/intrin/pthread_once_test.c rename to test/libc/intrin/cosmo_once_test.c index 07b075bc9..e9be25218 100644 --- a/test/libc/intrin/pthread_once_test.c +++ b/test/libc/intrin/cosmo_once_test.c @@ -17,49 +17,46 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/atomic.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/intrin/atomic.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" +#define N 32 + int i, n; struct spawn *t; atomic_int x, y; pthread_barrier_t b; -static pthread_once_t once = PTHREAD_ONCE_INIT; +static _Atomic(uint32_t) once; void InitFactory(void) { ASSERT_EQ(0, atomic_load(&x)); atomic_fetch_add(&y, 1); } -int Worker(void *arg, int tid) { +void *Worker(void *arg) { pthread_barrier_wait(&b); - ASSERT_EQ(0, pthread_once(&once, InitFactory)); + ASSERT_EQ(0, cosmo_once(&once, InitFactory)); ASSERT_EQ(1, atomic_load(&y)); atomic_fetch_add(&x, 1); return 0; } -TEST(pthread_once, test) { - n = 32; +TEST(cosmo_once, test) { + pthread_t th[N]; x = y = 0; - ASSERT_EQ(0, pthread_barrier_init(&b, 0, n)); - t = gc(malloc(sizeof(struct spawn) * n)); - for (i = 0; i < n; ++i) ASSERT_SYS(0, 0, _spawn(Worker, 0, t + i)); - for (i = 0; i < n; ++i) EXPECT_SYS(0, 0, _join(t + i)); - ASSERT_EQ(n, atomic_load(&x)); + ASSERT_EQ(0, pthread_barrier_init(&b, 0, N)); + for (i = 0; i < N; ++i) { + ASSERT_EQ(0, pthread_create(th + i, 0, Worker, 0)); + } + for (i = 0; i < N; ++i) { + ASSERT_EQ(0, pthread_join(th[i], 0)); + } + ASSERT_EQ(N, atomic_load(&x)); ASSERT_EQ(1, atomic_load(&y)); ASSERT_EQ(0, pthread_barrier_destroy(&b)); } - -__attribute__((__constructor__)) static void init(void) { - // try to test both the nsync and non-nsync versions with regular builds - if (!IsTiny()) { - pthread_cond_t c = {0}; - pthread_cond_broadcast(&c); - } -} diff --git a/test/libc/intrin/morton_test.c b/test/libc/intrin/morton_test.c deleted file mode 100644 index 1280dae74..000000000 --- a/test/libc/intrin/morton_test.c +++ /dev/null @@ -1,65 +0,0 @@ -/*-*- 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 2020 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/intrin/morton.h" -#include "libc/calls/calls.h" -#include "libc/errno.h" -#include "libc/nexgen32e/kcpuids.h" -#include "libc/str/str.h" -#include "libc/testlib/ezbench.h" -#include "libc/testlib/testlib.h" - -void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio rpath", 0)); -} - -TEST(morton, test) { - EXPECT_EQ(0, morton(0, 0)); - EXPECT_EQ(1, morton(0, 1)); - EXPECT_EQ(2, morton(1, 0)); - EXPECT_EQ(3, morton(1, 1)); - EXPECT_EQ(4, morton(0, 2)); - EXPECT_EQ(~0ul, morton(~0ul, ~0ul)); - EXPECT_EQ(0x7ffffffffffffffdul, morton(0x7ffffffeul, 0xfffffffful)); - EXPECT_EQ(0b1010101000010101010, morton(0b0000001111, 0b1111000000)); -} - -TEST(unmorton, test) { - EXPECT_EQ(0, unmorton(0).ax); - EXPECT_EQ(0, unmorton(0).dx); - EXPECT_EQ(0, unmorton(1).ax); - EXPECT_EQ(1, unmorton(1).dx); - EXPECT_EQ(1, unmorton(2).ax); - EXPECT_EQ(0, unmorton(2).dx); - EXPECT_EQ(1, unmorton(3).ax); - EXPECT_EQ(1, unmorton(3).dx); - EXPECT_EQ(0, unmorton(4).ax); - EXPECT_EQ(2, unmorton(4).dx); - EXPECT_EQ(0xffffffffu, unmorton(~0ul).ax); - EXPECT_EQ(0xffffffffu, unmorton(~0ul).dx); - EXPECT_EQ(0x7ffffffeul, unmorton(0x7ffffffffffffffdul).ax); - EXPECT_EQ(0xfffffffful, unmorton(0x7ffffffffffffffdul).dx); - EXPECT_EQ(0b0000001111000000, unmorton(0b010101010000001010101).ax); - EXPECT_EQ(0b0000000000001111, unmorton(0b010101010000001010101).dx); -} - -BENCH(morton, bench) { - EZBENCH2("morton", donothing, - __expropriate(morton(__conceal("r", 123), __conceal("r", 123)))); - EZBENCH2("unmorton", donothing, __expropriate(unmorton(__conceal("r", 123)))); -} diff --git a/test/libc/intrin/pthread_atfork_test.c b/test/libc/intrin/pthread_atfork_test.c index 0d7da5e2e..4fd22c198 100644 --- a/test/libc/intrin/pthread_atfork_test.c +++ b/test/libc/intrin/pthread_atfork_test.c @@ -99,7 +99,6 @@ void *Worker(void *arg) { } TEST(pthread_atfork, torture) { - if (IsWindows()) return; // TODO(jart): why do we get EBADF? it worked before pthread_mutex_init(&mu, 0); pthread_atfork(mu_lock, mu_unlock, mu_funlock); int i, n = 4; diff --git a/test/libc/intrin/rounddown2pow_test.c b/test/libc/intrin/rounddown2pow_test.c deleted file mode 100644 index b077756e9..000000000 --- a/test/libc/intrin/rounddown2pow_test.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/testlib/testlib.h" - -void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio", 0)); -} - -TEST(_rounddown2pow, test) { - EXPECT_EQ(0, _rounddown2pow(0)); - EXPECT_EQ(1, _rounddown2pow(1)); - EXPECT_EQ(2, _rounddown2pow(2)); - EXPECT_EQ(2, _rounddown2pow(3)); - EXPECT_EQ(4, _rounddown2pow(4)); - EXPECT_EQ(PAGESIZE / 2, _rounddown2pow(PAGESIZE - 1)); - EXPECT_EQ(PAGESIZE, _rounddown2pow(PAGESIZE)); - EXPECT_EQ(PAGESIZE, _rounddown2pow(PAGESIZE + 1)); - EXPECT_EQ(PAGESIZE / 2, _rounddown2pow(PAGESIZE - 1)); - EXPECT_EQ(PAGESIZE, _rounddown2pow(PAGESIZE)); - EXPECT_EQ(PAGESIZE, _rounddown2pow(PAGESIZE + 1)); -} diff --git a/test/libc/intrin/roundup2log_test.c b/test/libc/intrin/roundup2log_test.c deleted file mode 100644 index 1ee2acc79..000000000 --- a/test/libc/intrin/roundup2log_test.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/testlib/testlib.h" - -void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio", 0)); -} - -TEST(_roundup2log, test) { - EXPECT_EQ(0, _roundup2log(0)); - EXPECT_EQ(1, _roundup2log(1)); - EXPECT_EQ(1, _roundup2log(2)); - EXPECT_EQ(2, _roundup2log(3)); - EXPECT_EQ(2, _roundup2log(4)); - EXPECT_EQ(12, _roundup2log(PAGESIZE - 1)); - EXPECT_EQ(12, _roundup2log(PAGESIZE)); - EXPECT_EQ(13, _roundup2log(PAGESIZE + 1)); - EXPECT_EQ(12, _roundup2log(PAGESIZE - 1)); - EXPECT_EQ(12, _roundup2log(PAGESIZE)); - EXPECT_EQ(13, _roundup2log(PAGESIZE + 1)); -} diff --git a/test/libc/intrin/roundup2pow_test.c b/test/libc/intrin/roundup2pow_test.c deleted file mode 100644 index 535fad83b..000000000 --- a/test/libc/intrin/roundup2pow_test.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/testlib/testlib.h" - -void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio", 0)); -} - -TEST(_roundup2pow, test) { - EXPECT_EQ(0, _roundup2pow(0)); - EXPECT_EQ(1, _roundup2pow(1)); - EXPECT_EQ(2, _roundup2pow(2)); - EXPECT_EQ(4, _roundup2pow(3)); - EXPECT_EQ(4, _roundup2pow(4)); - EXPECT_EQ(PAGESIZE, _roundup2pow(PAGESIZE - 1)); - EXPECT_EQ(PAGESIZE, _roundup2pow(PAGESIZE)); - EXPECT_EQ(PAGESIZE * 2, _roundup2pow(PAGESIZE + 1)); - EXPECT_EQ(PAGESIZE, _roundup2pow(PAGESIZE - 1)); - EXPECT_EQ(PAGESIZE, _roundup2pow(PAGESIZE)); - EXPECT_EQ(PAGESIZE * 2, _roundup2pow(PAGESIZE + 1)); -} diff --git a/test/libc/intrin/strcmp_test.c b/test/libc/intrin/strcmp_test.c index c7d9a1bab..e54c9b4e0 100644 --- a/test/libc/intrin/strcmp_test.c +++ b/test/libc/intrin/strcmp_test.c @@ -325,30 +325,30 @@ TEST(wcscasecmp, testItWorksCase) { ╚────────────────────────────────────────────────────────────────────────────│*/ TEST(strncmp, testEqualManyNs) { - char *s1 = malloc(PAGESIZE); - char *s2 = malloc(PAGESIZE); - memset(s1, 7, PAGESIZE); - memset(s2, 7, PAGESIZE); - s1[PAGESIZE - 1] = '\0'; - s2[PAGESIZE - 1] = '\0'; + char *s1 = malloc(4096); + char *s2 = malloc(4096); + memset(s1, 7, 4096); + memset(s2, 7, 4096); + s1[4096 - 1] = '\0'; + s2[4096 - 1] = '\0'; for (unsigned i = 1; i <= 128; ++i) { - ASSERT_EQ(0, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 0)); - ASSERT_EQ(0, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 1)); + ASSERT_EQ(0, strncmp(s1 + 4096 - i, s2 + 4096 - i, i + 0)); + ASSERT_EQ(0, strncmp(s1 + 4096 - i, s2 + 4096 - i, i + 1)); } free(s2); free(s1); } TEST(strncmp, testNotEqualManyNs) { - char *s1 = malloc(PAGESIZE); - char *s2 = malloc(PAGESIZE); + char *s1 = malloc(4096); + char *s2 = malloc(4096); for (unsigned i = 1; i <= 128; ++i) { - memset(s1, 7, PAGESIZE); - memset(s2, 7, PAGESIZE); - s1[PAGESIZE - 1] = (unsigned char)0; - s2[PAGESIZE - 1] = (unsigned char)255; - ASSERT_EQ(-255, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 0)); - ASSERT_EQ(-255, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 1)); + memset(s1, 7, 4096); + memset(s2, 7, 4096); + s1[4096 - 1] = (unsigned char)0; + s2[4096 - 1] = (unsigned char)255; + ASSERT_EQ(-255, strncmp(s1 + 4096 - i, s2 + 4096 - i, i + 0)); + ASSERT_EQ(-255, strncmp(s1 + 4096 - i, s2 + 4096 - i, i + 1)); } free(s2); free(s1); diff --git a/test/libc/mem/arena_test.c b/test/libc/mem/arena_test.c deleted file mode 100644 index 9b09bf5cb..000000000 --- a/test/libc/mem/arena_test.c +++ /dev/null @@ -1,107 +0,0 @@ -/*-*- 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/log/libfatal.internal.h" -#include "libc/mem/arena.h" -#include "libc/mem/mem.h" -#include "libc/mem/gc.internal.h" -#include "libc/stdio/append.h" -#include "libc/str/str.h" -#include "libc/testlib/ezbench.h" -#include "libc/testlib/hyperion.h" -#include "libc/testlib/testlib.h" - -TEST(arena, test) { - EXPECT_STREQ("hello", gc(strdup("hello"))); - __arena_push(); - EXPECT_STREQ("hello", strdup("hello")); - __arena_push(); - EXPECT_STREQ("hello", strdup("hello")); - for (int i = 0; i < 5000; ++i) { - EXPECT_STREQ("hello", strdup("hello")); - } - free(strdup("hello")); - __arena_pop(); - EXPECT_STREQ("", calloc(1, 16)); - EXPECT_STREQ("hello", strdup("hello")); - __arena_pop(); -} - -TEST(arena, testRealloc) { - char *b = 0; - size_t i, n = 0; - __arena_push(); - for (i = 0; i < kHyperionSize; ++i) { - b = realloc(b, ++n * sizeof(*b)); - b[n - 1] = kHyperion[i]; - } - ASSERT_EQ(0, memcmp(b, kHyperion, kHyperionSize)); - __arena_pop(); -} - -void *memalign_(size_t, size_t) asm("memalign"); -void *calloc_(size_t, size_t) asm("calloc"); - -void Ca(size_t n) { - __arena_push(); - for (int i = 0; i < n; ++i) { - memalign_(1, 1); - } - __arena_pop(); -} - -void Cb(size_t n) { - void **P; - P = malloc(n * sizeof(void *)); - for (int i = 0; i < n; ++i) { - P[i] = calloc_(1, 1); - } - bulk_free(P, n); - free(P); -} - -BENCH(arena, benchMalloc) { - EZBENCH2("arena calloc(1)", donothing, Ca(100)); - EZBENCH2("dlmalloc calloc(1)", donothing, Cb(100)); -} - -void Ra(void) { - long *b = 0; - size_t i, n = 0; - __arena_push(); - for (i = 0; i < kHyperionSize; ++i) { - b = realloc(b, ++n * sizeof(*b)); - b[n - 1] = kHyperion[i]; - } - __arena_pop(); -} - -void Rb(void) { - long *b = 0; - size_t i, n = 0; - for (i = 0; i < kHyperionSize; ++i) { - b = realloc(b, ++n * sizeof(*b)); - b[n - 1] = kHyperion[i]; - } - free(b); -} - -BENCH(arena, benchRealloc) { - EZBENCH2("arena realloc", donothing, Ra()); - EZBENCH2("dlmalloc realloc", donothing, Rb()); -} diff --git a/test/libc/mem/arraylist_test.c b/test/libc/mem/arraylist_test.c deleted file mode 100644 index 2cb7f226e..000000000 --- a/test/libc/mem/arraylist_test.c +++ /dev/null @@ -1,103 +0,0 @@ -/*-*- 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 2020 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/log/libfatal.internal.h" -#include "libc/mem/alg.h" -#include "libc/mem/arraylist.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/testlib/testlib.h" - -struct string { - size_t i, n; - char *p; -}; - -struct string16 { - size_t i, n; - char16_t *p; -}; - -struct ArrayListInteger { - size_t i, n; - int *p; -}; - -TEST(append, worksGreatForScalars) { - char c = 'a'; - struct string s; - memset(&s, 0, sizeof(s)); - for (size_t i = 0; i < 1024; ++i) { - ASSERT_EQ(i, append(&s, &c)); - } - ASSERT_EQ(1024, s.i); - for (size_t i = 0; i < s.i; ++i) ASSERT_EQ('a', s.p[i]); - free(s.p); - s.p = 0; -} - -TEST(append, isGenericallyTyped) { - int c = 0x31337; - struct ArrayListInteger s; - memset(&s, 0, sizeof(s)); - for (size_t i = 0; i < 1024; ++i) { - ASSERT_EQ(i, append(&s, &c)); - } - ASSERT_EQ(1024, s.i); - ASSERT_GT(malloc_usable_size(s.p), 1024 * sizeof(int)); - for (size_t i = 0; i < s.i; ++i) { - ASSERT_EQ(0x31337, s.p[i]); - } - free(s.p); - s.p = 0; -} - -TEST(concat, worksGreatForStrings) { - const char *ks = "Und wird die Welt auch in Flammen stehen\n" - "Wir werden wieder auferstehen\n"; - struct string s; - memset(&s, 0, sizeof(s)); - ASSERT_EQ(0, concat(&s, ks, strlen(ks))); - ASSERT_EQ(strlen(ks), concat(&s, ks, strlen(ks) + 1)); - ASSERT_STREQ("Und wird die Welt auch in Flammen stehen\n" - "Wir werden wieder auferstehen\n" - "Und wird die Welt auch in Flammen stehen\n" - "Wir werden wieder auferstehen\n", - s.p); - ASSERT_EQ(strlen(ks) * 2 + 1, s.i); - free(s.p); - s.p = 0; -} - -TEST(concat, isGenericallyTyped) { - const char16_t *ks = u"Drum hoch die Fäuste, hoch zum Licht.\n" - u"Unsere schwarzen Seelen bekommt ihr nicht.\n"; - struct string16 s; - memset(&s, 0, sizeof(s)); - ASSERT_EQ(0, concat(&s, ks, strlen16(ks))); - ASSERT_EQ(strlen16(ks), concat(&s, ks, strlen16(ks) + 1)); - ASSERT_STREQ(u"Drum hoch die Fäuste, hoch zum Licht.\n" - u"Unsere schwarzen Seelen bekommt ihr nicht.\n" - u"Drum hoch die Fäuste, hoch zum Licht.\n" - u"Unsere schwarzen Seelen bekommt ihr nicht.\n", - s.p); - ASSERT_EQ(strlen16(ks) * 2 + 1, s.i); - free(s.p); - s.p = 0; -} diff --git a/test/libc/mem/bisectcarleft_test.c b/test/libc/mem/bisectcarleft_test.c deleted file mode 100644 index c42ff3ac0..000000000 --- a/test/libc/mem/bisectcarleft_test.c +++ /dev/null @@ -1,57 +0,0 @@ -/*-*- 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 2020 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/mem/alg.h" -#include "libc/mem/bisectcarleft.internal.h" -#include "libc/intrin/bits.h" -#include "libc/macros.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/testlib/testlib.h" - -TEST(bisectcarleft, testEmpty) { - const int32_t cells[][2] = {}; - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123)); -} - -TEST(bisectcarleft, testOneEntry) { - const int32_t cells[][2] = {{123, 31337}}; - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 122)); - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123)); - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 124)); -} - -TEST(bisectcarleft, testNegativity_usesSignedBehavior) { - const int32_t cells[][2] = {{-2, 31337}}; - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -3)); - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -2)); - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -1)); -} - -TEST(bisectcarleft, testMultipleEntries) { - const int32_t cells[][2] = {{00, 0}, {11, 0}, {20, 0}, {33, 0}, {40, 0}, - {50, 0}, {60, 0}, {70, 0}, {80, 0}, {90, 0}}; - EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 10)); - EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 11)); - EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 12)); - EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 19)); - EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 20)); - EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 21)); - EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 32)); - EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 33)); - EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 34)); -} diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c index 75037a557..8b34f3f8a 100644 --- a/test/libc/mem/malloc_test.c +++ b/test/libc/mem/malloc_test.c @@ -20,6 +20,7 @@ #include "libc/calls/struct/stat.h" #include "libc/calls/struct/timespec.h" #include "libc/dce.h" +#include "libc/intrin/asan.internal.h" #include "libc/intrin/bits.h" #include "libc/intrin/cxaatexit.internal.h" #include "libc/intrin/safemacros.internal.h" @@ -51,12 +52,59 @@ void SetUp(void) { if (IsWindows()) exit(0); } -TEST(malloc, zeroMeansOne) { - ASSERT_GE(malloc_usable_size(gc(malloc(0))), 1); +TEST(malloc, zero) { + char *p; + ASSERT_NE(NULL, (p = malloc(0))); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p, 1)); + free(p); } -TEST(calloc, zerosMeansOne) { - ASSERT_GE(malloc_usable_size(gc(calloc(0, 0))), 1); +TEST(realloc, bothAreZero_createsMinimalAllocation) { + char *p; + ASSERT_NE(NULL, (p = realloc(0, 0))); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p, 1)); + free(p); +} + +TEST(realloc, ptrIsZero_createsAllocation) { + char *p; + ASSERT_NE(NULL, (p = realloc(0, 1))); + if (IsAsan()) ASSERT_TRUE(__asan_is_valid(p, 1)); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p + 1, 1)); + ASSERT_EQ(p, realloc(p, 0)); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p, 1)); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p + 1, 1)); + free(p); +} + +TEST(realloc, sizeIsZero_shrinksAllocation) { + char *p; + ASSERT_NE(NULL, (p = malloc(1))); + if (IsAsan()) ASSERT_TRUE(__asan_is_valid(p, 1)); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p + 1, 1)); + ASSERT_EQ(p, realloc(p, 0)); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p, 1)); + if (IsAsan()) ASSERT_FALSE(__asan_is_valid(p + 1, 1)); + free(p); +} + +TEST(realloc_in_place, test) { + char *x = malloc(16); + EXPECT_EQ(x, realloc_in_place(x, 0)); + EXPECT_EQ(x, realloc_in_place(x, 1)); + *x = 2; + free(x); +} + +BENCH(realloc_in_place, bench) { + volatile int i = 1000; + volatile char *x = malloc(i); + EZBENCH2("malloc", donothing, free(malloc(i))); + EZBENCH2("memalign", donothing, free(memalign(16, i))); + EZBENCH2("memalign", donothing, free(memalign(32, i))); + EZBENCH2("realloc", donothing, x = realloc(x, --i)); + EZBENCH2("realloc_in_place", donothing, realloc_in_place(x, --i)); + free(x); } void AppendStuff(char **p, size_t *n) { diff --git a/test/libc/mem/realloc_in_place_test.c b/test/libc/mem/realloc_in_place_test.c deleted file mode 100644 index 32a0bc8da..000000000 --- a/test/libc/mem/realloc_in_place_test.c +++ /dev/null @@ -1,42 +0,0 @@ -/*-*- 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/mem/mem.h" -#include "libc/mem/gc.internal.h" -#include "libc/testlib/ezbench.h" -#include "libc/testlib/testlib.h" - -TEST(realloc_in_place, test) { - char *x = malloc(16); - EXPECT_EQ(x, realloc_in_place(x, 0)); - EXPECT_EQ(x, realloc_in_place(x, 1)); - *x = 2; - free(x); -} - -BENCH(realloc_in_place, bench) { - volatile int i = 1000; - volatile char *x = malloc(i); - EZBENCH2("malloc", donothing, free(malloc(i))); - EZBENCH2("malloc", donothing, free(malloc(i))); - EZBENCH2("memalign", donothing, free(memalign(16, i))); - EZBENCH2("memalign", donothing, free(memalign(32, i))); - EZBENCH2("realloc", donothing, x = realloc(x, --i)); - EZBENCH2("realloc_in_place", donothing, realloc_in_place(x, --i)); - free(x); -} diff --git a/test/libc/mem/reverse_test.c b/test/libc/mem/reverse_test.c deleted file mode 100644 index 7a7140f8e..000000000 --- a/test/libc/mem/reverse_test.c +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- 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 2020 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/mem/reverse.internal.h" -#include "libc/dce.h" -#include "libc/macros.internal.h" -#include "libc/testlib/testlib.h" - -TEST(reverse, test) { - /* this test gets DCE'd :) */ - int A[3] = {1, 2, 3}; - reverse(A, ARRAYLEN(A)); - EXPECT_EQ(3, A[0]); - EXPECT_EQ(2, A[1]); - EXPECT_EQ(1, A[2]); -} - -TEST(reverse, testEmpty) { - int A[3] = {1, 2, 3}; - reverse(A, 0); - EXPECT_EQ(1, A[0]); - EXPECT_EQ(2, A[1]); - EXPECT_EQ(3, A[2]); -} diff --git a/test/libc/runtime/fork_test.c b/test/libc/runtime/fork_test.c index 24f3c6f66..1b1899907 100644 --- a/test/libc/runtime/fork_test.c +++ b/test/libc/runtime/fork_test.c @@ -16,15 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/timespec.h" #include "libc/dce.h" +#include "libc/errno.h" #include "libc/intrin/kprintf.h" #include "libc/log/check.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" #include "libc/sysv/consts/prot.h" @@ -38,6 +42,7 @@ TEST(fork, testPipes) { int a, b; int ws, pid; int pipefds[2]; + alarm(5); ASSERT_NE(-1, pipe(pipefds)); ASSERT_NE(-1, (pid = fork())); if (!pid) { @@ -52,9 +57,11 @@ TEST(fork, testPipes) { EXPECT_NE(-1, close(pipefds[0])); EXPECT_NE(-1, waitpid(pid, &ws, 0)); EXPECT_EQ(31337, b); + alarm(0); } TEST(fork, testSharedMemory) { + alarm(5); int ws, pid; int stackvar; int *sharedvar; @@ -86,6 +93,7 @@ TEST(fork, testSharedMemory) { EXPECT_EQ(1, *privatevar); EXPECT_NE(-1, munmap(sharedvar, FRAMESIZE)); EXPECT_NE(-1, munmap(privatevar, FRAMESIZE)); + alarm(0); } static volatile bool gotsigusr1; @@ -109,6 +117,7 @@ TEST(fork, childToChild) { signal(SIGUSR1, OnSigusr1); signal(SIGUSR2, OnSigusr2); sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); sigprocmask(SIG_BLOCK, &mask, &oldmask); ASSERT_NE(-1, (child1 = fork())); @@ -117,28 +126,27 @@ TEST(fork, childToChild) { sigsuspend(0); _Exit(!gotsigusr1); } - sigdelset(&mask, SIGUSR2); - sigsuspend(&mask); + sigsuspend(0); ASSERT_NE(-1, (child2 = fork())); if (!child2) { kill(child1, SIGUSR1); _Exit(0); } ASSERT_NE(-1, wait(&ws)); - EXPECT_TRUE(WIFEXITED(ws)); - EXPECT_EQ(0, WEXITSTATUS(ws)); + EXPECT_EQ(0, ws); ASSERT_NE(-1, wait(&ws)); - EXPECT_TRUE(WIFEXITED(ws)); - EXPECT_EQ(0, WEXITSTATUS(ws)); + EXPECT_EQ(0, ws); sigprocmask(SIG_SETMASK, &oldmask, 0); } TEST(fork, preservesTlsMemory) { + alarm(5); int pid; __get_tls()->tib_errno = 31337; SPAWN(fork); ASSERT_EQ(31337, __get_tls()->tib_errno); EXITS(0); + alarm(0); } void ForkInSerial(void) { diff --git a/test/libc/runtime/mmap_test.c b/test/libc/runtime/mmap_test.c index 453305575..3fce7930b 100644 --- a/test/libc/runtime/mmap_test.c +++ b/test/libc/runtime/mmap_test.c @@ -22,6 +22,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" +#include "libc/intrin/asan.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bits.h" #include "libc/intrin/kprintf.h" @@ -37,6 +38,7 @@ #include "libc/stdio/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" +#include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" #include "libc/sysv/consts/o.h" @@ -94,7 +96,8 @@ TEST(mmap, noreplaceExistingMap) { TEST(mmap, smallerThanPage_mapsRemainder) { long pagesz = sysconf(_SC_PAGESIZE); - char *map = mmap(0, 1, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + char *map = + mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_NE(MAP_FAILED, map); EXPECT_TRUE(testlib_memoryexists(map)); EXPECT_TRUE(testlib_memoryexists(map + (pagesz - 1))); @@ -103,6 +106,16 @@ TEST(mmap, smallerThanPage_mapsRemainder) { EXPECT_FALSE(testlib_memoryexists(map + (pagesz - 1))); } +TEST(mmap, smallerThanPage_remainderIsPoisoned) { + if (!IsAsan()) return; + char *map; + ASSERT_NE(MAP_FAILED, (map = mmap(0, 1, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_TRUE(__asan_is_valid(map, 1)); + EXPECT_FALSE(__asan_is_valid(map + 1, 1)); + EXPECT_SYS(0, 0, munmap(map, 1)); +} + TEST(mmap, testMapFile) { int fd; char *p; @@ -130,7 +143,7 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { EXPECT_NE(-1, close(fd)); EXPECT_STREQN("hello", p, 5); p[1] = 'a'; - EXPECT_NE(-1, msync(p, PAGESIZE, MS_SYNC)); + EXPECT_NE(-1, msync(p, getauxval(AT_PAGESZ), MS_SYNC)); ASSERT_NE(-1, (fd = open(path, O_RDONLY))); EXPECT_EQ(5, read(fd, buf, 5)); EXPECT_STREQN("hallo", buf, 5); @@ -179,15 +192,16 @@ TEST(mmap, customStackMemory_isAuthorized) { TEST(mmap, fileOffset) { int fd; char *map; + int offset_align = IsWindows() ? FRAMESIZE : getauxval(AT_PAGESZ); ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644))); - EXPECT_NE(-1, ftruncate(fd, FRAMESIZE * 2)); - EXPECT_NE(-1, pwrite(fd, "hello", 5, FRAMESIZE * 0)); - EXPECT_NE(-1, pwrite(fd, "there", 5, FRAMESIZE * 1)); + EXPECT_NE(-1, ftruncate(fd, offset_align * 2)); + EXPECT_NE(-1, pwrite(fd, "hello", 5, offset_align * 0)); + EXPECT_NE(-1, pwrite(fd, "there", 5, offset_align * 1)); EXPECT_NE(-1, fdatasync(fd)); - ASSERT_NE(MAP_FAILED, (map = mmap(NULL, FRAMESIZE, PROT_READ, MAP_PRIVATE, fd, - FRAMESIZE))); + ASSERT_NE(MAP_FAILED, (map = mmap(NULL, offset_align, PROT_READ, MAP_PRIVATE, + fd, offset_align))); EXPECT_EQ(0, memcmp(map, "there", 5), "%#.*s", 5, map); - EXPECT_NE(-1, munmap(map, FRAMESIZE)); + EXPECT_NE(-1, munmap(map, offset_align)); EXPECT_NE(-1, close(fd)); } diff --git a/test/libc/sock/nonblock_test.c b/test/libc/sock/nonblock_test.c index ef6abb55e..498a20f56 100644 --- a/test/libc/sock/nonblock_test.c +++ b/test/libc/sock/nonblock_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/errno.h" +#include "libc/intrin/kprintf.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" @@ -106,8 +107,9 @@ TEST(O_NONBLOCK, canBeTunedWithFcntl_toMakeReadNonBlocking) { PARENT(); EXPECT_SYS(0, 0, close(3)); ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); + ASSERT_SYS(0, O_RDWR, fcntl(3, F_GETFL)); ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr))); - ASSERT_SYS(0, 0, fcntl(3, F_SETFL, O_NONBLOCK)); + ASSERT_SYS(0, 0, fcntl(3, F_SETFL, O_RDWR | O_NONBLOCK)); ASSERT_SYS(EAGAIN, -1, read(3, buf, 16)); EXPECT_EQ(0, pthread_spin_unlock(phaser + 0)); TryAgain: diff --git a/test/libc/sock/socket_test.c b/test/libc/sock/socket_test.c index 10c710c66..c958b3212 100644 --- a/test/libc/sock/socket_test.c +++ b/test/libc/sock/socket_test.c @@ -17,6 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/fd.internal.h" +#include "libc/dce.h" +#include "libc/nt/winsock.h" +#include "libc/runtime/runtime.h" #include "libc/sock/sock.h" #include "libc/sock/struct/sockaddr.h" #include "libc/sock/struct/sockaddr6.h" @@ -25,6 +30,7 @@ #include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/sock.h" +#include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" TEST(ipv4, test) { @@ -40,27 +46,20 @@ TEST(ipv4, test) { ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr))); ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize)); ASSERT_SYS(0, 0, listen(3, SOMAXCONN)); - ASSERT_NE(-1, (pid = fork())); - if (!pid) { - ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize)); - ASSERT_SYS(0, 5, send(4, "hello", 5, 0)); - ASSERT_SYS(0, 0, close(4)); - ASSERT_SYS(0, 0, close(3)); - _Exit(0); - } + SPAWN(fork); + ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize)); + ASSERT_SYS(0, 5, send(4, "hello", 5, 0)); + PARENT(); EXPECT_SYS(0, 0, close(3)); EXPECT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); EXPECT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr))); EXPECT_SYS(0, 5, read(3, buf, 16)); EXPECT_STREQ("hello", buf); EXPECT_SYS(0, 0, close(3)); - EXPECT_NE(-1, wait(&ws)); - ASSERT_TRUE(WIFEXITED(ws)); - ASSERT_EQ(0, WEXITSTATUS(ws)); + WAIT(exit, 0); } TEST(ipv6, test) { - int ws, pid; char buf[16] = {0}; int64_t inoffset; uint32_t addrsize = sizeof(struct sockaddr_in6); @@ -74,23 +73,19 @@ TEST(ipv6, test) { ASSERT_EQ(AF_INET6, addr.sin6_family); ASSERT_NE(0, addr.sin6_port); ASSERT_SYS(0, 0, listen(3, SOMAXCONN)); - ASSERT_NE(-1, (pid = fork())); - if (!pid) { - ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize)); - ASSERT_SYS(0, 5, send(4, "hello", 5, 0)); - ASSERT_SYS(0, 0, close(4)); - ASSERT_SYS(0, 0, close(3)); - _Exit(0); - } + SPAWN(fork); + ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize)); + ASSERT_SYS(0, 5, send(4, "hello", 5, 0)); + ASSERT_SYS(0, 0, close(4)); + ASSERT_SYS(0, 0, close(3)); + PARENT(); EXPECT_SYS(0, 0, close(3)); EXPECT_SYS(0, 3, socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)); EXPECT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr))); EXPECT_SYS(0, 5, read(3, buf, 16)); EXPECT_STREQ("hello", buf); EXPECT_SYS(0, 0, close(3)); - EXPECT_NE(-1, wait(&ws)); - ASSERT_TRUE(WIFEXITED(ws)); - ASSERT_EQ(0, WEXITSTATUS(ws)); + WAIT(exit, 0); } TEST(getsockname, defaultsToZero) { @@ -118,3 +113,76 @@ TEST(getsockname, copiesSafely_givesFullSize) { ASSERT_EQ(0xffff, addr.sin_port); EXPECT_SYS(0, 0, close(3)); } + +TEST(socket, canBeInheritedByForkedWorker) { + char buf[16] = {0}; + int64_t inoffset; + uint32_t addrsize = sizeof(struct sockaddr_in); + struct sockaddr_in addr = { + .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 *)&addr, sizeof(addr))); + ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize)); + ASSERT_SYS(0, 0, listen(3, SOMAXCONN)); + SPAWN(fork); + ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize)); + ASSERT_SYS(0, 0, close(3)); + SPAWN(fork); + ASSERT_SYS(0, 5, write(4, "hello", 5)); + PARENT(); + ASSERT_SYS(0, 0, close(4)); + WAIT(exit, 0); + PARENT(); + EXPECT_SYS(0, 0, close(3)); + EXPECT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); + EXPECT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr))); + EXPECT_SYS(0, 5, read(3, buf, 16)); + EXPECT_STREQ("hello", buf); + EXPECT_SYS(0, 0, close(3)); + WAIT(exit, 0); +} + +__attribute__((__constructor__)) static void StdioPro(int argc, char *argv[]) { + if (argc >= 2 && !strcmp(argv[1], "StdioProg")) { + ASSERT_EQ(NULL, getenv("__STDIO_SOCKETS")); + ASSERT_EQ(5, write(1, "hello", 5)); + exit(0); + } +} + +TEST(socket, canBeUsedAsExecutedStdio) { + char buf[16] = {0}; + int64_t inoffset; + const char *prog; + uint32_t addrsize = sizeof(struct sockaddr_in); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(0x7f000001), + }; + prog = GetProgramExecutableName(); + ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP)); + ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr))); + ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize)); + ASSERT_SYS(0, 0, listen(3, SOMAXCONN)); + SPAWN(fork); + ASSERT_SYS(0, 4, + accept4(3, (struct sockaddr *)&addr, &addrsize, SOCK_CLOEXEC)); + ASSERT_SYS(0, 1, dup2(4, 1)); + SPAWN(vfork); + execve(prog, (char *[]){prog, "StdioProg", 0}, (char *[]){0}); + abort(); + PARENT(); + ASSERT_SYS(0, 0, close(4)); + ASSERT_SYS(0, 0, close(3)); + WAIT(exit, 0); + PARENT(); + EXPECT_SYS(0, 0, close(3)); + EXPECT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); + EXPECT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr))); + EXPECT_SYS(0, 5, read(3, buf, 16)); + EXPECT_STREQ("hello", buf); + EXPECT_SYS(0, 0, close(3)); + WAIT(exit, 0); +} diff --git a/test/libc/sock/unix_test.c b/test/libc/sock/unix_test.c index acfb955d9..146d00e41 100644 --- a/test/libc/sock/unix_test.c +++ b/test/libc/sock/unix_test.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/timeval.h" @@ -32,6 +33,7 @@ #include "libc/sysv/consts/so.h" #include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/sol.h" +#include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" #include "libc/time/time.h" @@ -41,13 +43,16 @@ void SetUpOnce(void) { ASSERT_SYS(0, 0, pledge("stdio rpath cpath proc unix", 0)); } -void DatagramServer(void) { +TEST(unix, datagram) { + if (IsWindows()) return; // no unix datagram on windows :'( + atomic_bool *ready = _mapshared(1); + SPAWN(fork); char buf[256] = {0}; uint32_t len = sizeof(struct sockaddr_un); struct sockaddr_un addr = {AF_UNIX, "foo.sock"}; - alarm(3); ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_DGRAM, 0)); ASSERT_SYS(0, 0, bind(3, (void *)&addr, len)); + *ready = true; bzero(&addr, sizeof(addr)); ASSERT_SYS(0, 0, getsockname(3, (void *)&addr, &len)); ASSERT_EQ(11, len); @@ -55,33 +60,21 @@ void DatagramServer(void) { ASSERT_SYS(0, 5, read(3, buf, 256)); EXPECT_STREQ("hello", buf); ASSERT_SYS(0, 0, close(3)); -} - -TEST(unix, datagram) { - if (IsWindows()) return; // no unix datagram on windows :'( - int ws; + PARENT(); + while (!*ready) sched_yield(); + ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_DGRAM, 0)); uint32_t len = sizeof(struct sockaddr_un); struct sockaddr_un addr = {AF_UNIX, "foo.sock"}; - if (!fork()) { - DatagramServer(); - _Exit(0); - } - alarm(3); - while (!fileexists(addr.sun_path)) usleep(10000); - ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_DGRAM, 0)); ASSERT_SYS(0, 5, sendto(3, "hello", 5, 0, (struct sockaddr *)&addr, len)); ASSERT_SYS(0, 0, close(3)); - ASSERT_NE(-1, wait(&ws)); - EXPECT_TRUE(WIFEXITED(ws)); - EXPECT_EQ(0, WEXITSTATUS(ws)); - alarm(0); + WAIT(exit, 0); + munmap(ready, 1); } -void StreamServer(void) { +void StreamServer(atomic_bool *ready) { char buf[256] = {0}; uint32_t len = sizeof(struct sockaddr_un); struct sockaddr_un addr = {AF_UNIX, "foo.sock"}; - alarm(3); ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_STREAM, 0)); ASSERT_SYS(0, 0, bind(3, (void *)&addr, len)); bzero(&addr, sizeof(addr)); @@ -92,6 +85,7 @@ void StreamServer(void) { ASSERT_SYS(0, 0, listen(3, 10)); bzero(&addr, sizeof(addr)); len = sizeof(addr); + *ready = true; ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &len)); ASSERT_EQ(AF_UNIX, addr.sun_family); EXPECT_STREQ("", addr.sun_path); @@ -101,26 +95,26 @@ void StreamServer(void) { } TEST(unix, stream) { - if (IsWindows() && !IsAtLeastWindows10()) return; int ws; - uint32_t len = sizeof(struct sockaddr_un); - struct sockaddr_un addr = {AF_UNIX, "foo.sock"}; + if (IsWindows() && !IsAtLeastWindows10()) return; + atomic_bool *ready = _mapshared(1); // TODO(jart): move this line down when kFdProcess is gone ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_STREAM, 0)); if (!fork()) { close(3); - StreamServer(); + StreamServer(ready); _Exit(0); } - alarm(3); - while (!fileexists(addr.sun_path)) usleep(10000); + while (!*ready) sched_yield(); + uint32_t len = sizeof(struct sockaddr_un); + struct sockaddr_un addr = {AF_UNIX, "foo.sock"}; ASSERT_SYS(0, 0, connect(3, (void *)&addr, len)); ASSERT_SYS(0, 5, write(3, "hello", 5)); ASSERT_SYS(0, 0, close(3)); ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(0, WEXITSTATUS(ws)); - alarm(0); + munmap(ready, 1); } TEST(unix, serverGoesDown_deletedSockFile) { // field of landmine diff --git a/test/libc/stdio/mkostempsm_test.c b/test/libc/stdio/mkostempsm_test.c deleted file mode 100644 index 53a022763..000000000 --- a/test/libc/stdio/mkostempsm_test.c +++ /dev/null @@ -1,80 +0,0 @@ -/*-*- 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 2020 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/intrin/bits.h" -#include "libc/errno.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/internal.h" -#include "libc/stdio/temp.h" -#include "libc/sysv/consts/o.h" -#include "libc/testlib/testlib.h" - -#define Mode() \ - ({ \ - va_list va; \ - unsigned Mode; \ - va_start(va, flags); \ - Mode = va_arg(va, unsigned); \ - va_end(va); \ - Mode; \ - }) - -static int MockOpen1(const char *file, int flags, ...) { - static bool once; - ASSERT_FALSE(once); - once = true; - EXPECT_STREQ("/tmp/mkostemps.ctre5m", file); - EXPECT_EQ(O_RDWR | O_CREAT | O_EXCL, flags); - EXPECT_EQ(0600, Mode()); - return 123; -} - -TEST(mkostempsm, test1) { - uint64_t rando = 1; - char path[PATH_MAX] = "/tmp/mkostemps.XXXXXX"; - EXPECT_EQ(123L, mkostempsmi(path, 0, 0, &rando, 0600, MockOpen1)); - EXPECT_STREQ("/tmp/mkostemps.ctre5m", path); -} - -static int MockOpen2(const char *file, int flags, ...) { - static int state; - switch (state) { - case 0: - state = 1; - EXPECT_STREQ("/tmp/mkostemps.ctre5m", file); - EXPECT_EQ((unsigned)(O_RDWR | O_CREAT | O_EXCL), flags); - EXPECT_EQ(0600, Mode()); - errno = EEXIST; - return -1; - case 1: - state = 1; - EXPECT_STREQ("/tmp/mkostemps.jl1h61", file); - EXPECT_EQ((unsigned)(O_RDWR | O_CREAT | O_EXCL), flags); - EXPECT_EQ(0600, Mode()); - return 123; - default: - abort(); - } -} - -TEST(mkostempsm, test2) { - uint64_t rando = 1; - char path[PATH_MAX] = "/tmp/mkostemps.XXXXXX"; - EXPECT_EQ(123, mkostempsmi(path, 0, 0, &rando, 0600, MockOpen2)); - EXPECT_STREQ("/tmp/mkostemps.jl1h61", path); -} diff --git a/test/libc/stdio/system_test.c b/test/libc/stdio/system_test.c index 5ddb15010..0649a1c87 100644 --- a/test/libc/stdio/system_test.c +++ b/test/libc/stdio/system_test.c @@ -107,13 +107,6 @@ TEST(system, testStderrRedirect_toStdout) { ASSERT_EQ(0, close(pipefd[0])); } -BENCH(system, bench) { - testlib_extract("/zip/echo.com", "echo.com", 0755); - EZBENCH2("system cmd", donothing, system("./echo.com hi >/dev/null")); - EZBENCH2("cocmd echo", donothing, system("echo hi >/dev/null")); - EZBENCH2("cocmd exit", donothing, system("exit")); -} - TEST(system, and) { ASSERT_EQ(1, WEXITSTATUS(system("false && false"))); ASSERT_EQ(1, WEXITSTATUS(system("true&& false"))); @@ -245,4 +238,13 @@ TEST(system, tr) { ASSERT_STREQ("HELLO\n", gc(xslurp("res", 0))); } +int system2(const char *); + +BENCH(system, bench) { + testlib_extract("/zip/echo.com", "echo.com", 0755); + EZBENCH2("system cmd", donothing, system("./echo.com hi >/dev/null")); + EZBENCH2("cocmd echo", donothing, system("echo hi >/dev/null")); + EZBENCH2("cocmd exit", donothing, system("exit")); +} + #endif /* __x86_64__ */ diff --git a/test/libc/str/memcpy_test.c b/test/libc/str/memcpy_test.c index 11bf35d83..885dd2d97 100644 --- a/test/libc/str/memcpy_test.c +++ b/test/libc/str/memcpy_test.c @@ -192,6 +192,6 @@ BENCH(memcpy, bench) { BB(256); BB(1023); BB(1024); - BB(PAGESIZE); + BB(4096); BB(FRAMESIZE); } diff --git a/test/libc/thread/pthread_cancel_test.c b/test/libc/thread/pthread_cancel_test.c index 7fe715d8d..9b2ff3b47 100644 --- a/test/libc/thread/pthread_cancel_test.c +++ b/test/libc/thread/pthread_cancel_test.c @@ -24,6 +24,7 @@ #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/nexgen32e.h" +#include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/testlib/testlib.h" #include "libc/thread/thread.h" @@ -80,7 +81,7 @@ TEST(pthread_cancel, synchronous) { pthread_t th; ASSERT_SYS(0, 0, pipe(pfds)); ASSERT_EQ(0, pthread_create(&th, 0, Worker, 0)); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(PTHREAD_CANCELED, rc); ASSERT_TRUE(gotcleanup); @@ -94,7 +95,7 @@ TEST(pthread_cancel, synchronous_delayed) { ASSERT_SYS(0, 0, pipe(pfds)); ASSERT_EQ(0, pthread_create(&th, 0, Worker, 0)); usleep(10); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(PTHREAD_CANCELED, rc); ASSERT_TRUE(gotcleanup); @@ -116,7 +117,7 @@ TEST(pthread_cancel, masked) { pthread_t th; ASSERT_SYS(0, 0, pipe(pfds)); ASSERT_EQ(0, pthread_create(&th, 0, DisabledWorker, 0)); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(0, rc); ASSERT_FALSE(gotcleanup); @@ -130,7 +131,7 @@ TEST(pthread_cancel, masked_delayed) { ASSERT_SYS(0, 0, pipe(pfds)); ASSERT_EQ(0, pthread_create(&th, 0, DisabledWorker, 0)); usleep(10); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(0, rc); ASSERT_FALSE(gotcleanup); @@ -150,7 +151,7 @@ TEST(pthread_cancel, condMaskedWait) { void *rc; pthread_t th; ASSERT_EQ(0, pthread_create(&th, 0, CondWaitMaskedWorker, 0)); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(0, rc); } @@ -160,7 +161,7 @@ TEST(pthread_cancel, condWaitMaskedDelayed) { pthread_t th; ASSERT_EQ(0, pthread_create(&th, 0, CondWaitMaskedWorker, 0)); usleep(10); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(0, rc); } @@ -177,7 +178,7 @@ TEST(pthread_cancel, condDeferredWait) { void *rc; pthread_t th; ASSERT_EQ(0, pthread_create(&th, 0, CondWaitDeferredWorker, 0)); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(PTHREAD_CANCELED, rc); ASSERT_EQ(0, pthread_mutex_trylock(&mu)); @@ -189,7 +190,7 @@ TEST(pthread_cancel, condDeferredWaitDelayed) { pthread_t th; ASSERT_EQ(0, pthread_create(&th, 0, CondWaitDeferredWorker, 0)); usleep(10); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(PTHREAD_CANCELED, rc); ASSERT_EQ(0, pthread_mutex_trylock(&mu)); @@ -252,7 +253,7 @@ TEST(pthread_cancel, async) { key_destructor_was_run = false; ASSERT_EQ(0, pthread_create(&th, 0, CpuBoundWorker, 0)); while (!is_in_infinite_loop) pthread_yield(); - ASSERT_EQ(0, pthread_cancel(th)); + pthread_cancel(th); ASSERT_EQ(0, pthread_join(th, &rc)); ASSERT_EQ(PTHREAD_CANCELED, rc); ASSERT_TRUE(key_destructor_was_run); diff --git a/third_party/chibicc/chibicc.main.c b/third_party/chibicc/chibicc.main.c index 537a9a4c7..6f58bcbb1 100644 --- a/third_party/chibicc/chibicc.main.c +++ b/third_party/chibicc/chibicc.main.c @@ -1,7 +1,6 @@ -#include "libc/mem/arena.h" +#include "third_party/chibicc/chibicc.h" #include "libc/runtime/internal.h" #include "libc/x/x.h" -#include "third_party/chibicc/chibicc.h" #include "tool/build/lib/getargs.h" int main(int argc, char **argv) { diff --git a/third_party/chibicc/dox2.c b/third_party/chibicc/dox2.c index 74f58a3ff..aeb290f1d 100644 --- a/third_party/chibicc/dox2.c +++ b/third_party/chibicc/dox2.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/bits.h" +#include "libc/intrin/bsr.h" #include "libc/mem/alg.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" @@ -281,9 +282,13 @@ static int CompareDoxIndexEntry(const void *p1, const void *p2, void *arg) { return strcasecmp(s1, s2); } +static unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; +} + static void IndexDox(struct Dox *dox) { size_t i, j, n; - dox->names.n = _roundup2pow(dox->objects.n + dox->macros.n) << 1; + dox->names.n = roundup2pow(dox->objects.n + dox->macros.n) << 1; dox->names.p = calloc(dox->names.n, sizeof(*dox->names.p)); n = 0; for (i = 0; i < dox->objects.n; ++i) { diff --git a/third_party/chibicc/preprocess.c b/third_party/chibicc/preprocess.c index f0209a23f..dd9780597 100644 --- a/third_party/chibicc/preprocess.c +++ b/third_party/chibicc/preprocess.c @@ -24,7 +24,6 @@ #include "libc/fmt/libgen.h" #include "libc/log/libfatal.internal.h" -#include "libc/mem/arena.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/x/xasprintf.h" @@ -267,7 +266,6 @@ static Token *read_const_expr(Token **rest, Token *tok) { // Read and evaluate a constant expression. static long eval_const_expr(Token **rest, Token *tok) { - __arena_push(); Token *start = tok; Token *expr = read_const_expr(rest, tok->next); expr = preprocess2(expr); @@ -290,7 +288,6 @@ static long eval_const_expr(Token **rest, Token *tok) { if (rest2->kind != TK_EOF && rest2->kind != TK_JAVADOWN) { error_tok(rest2, "extra token"); } - __arena_pop(); return val; } diff --git a/third_party/ctags/get.c b/third_party/ctags/get.c index 2d4ea0a40..23b8637d2 100644 --- a/third_party/ctags/get.c +++ b/third_party/ctags/get.c @@ -68,7 +68,7 @@ typedef struct sCppState { boolean hasAtLiteralStrings; /* supports @"c:\" strings */ struct sDirective { enum eState state; /* current directive being processed */ - boolean accept; /* is a directive syntactically permitted? */ + boolean accept_; /* is a directive syntactically permitted? */ vString * name; /* macro name */ unsigned int nestLevel; /* level 0 is not used */ conditionalInfo ifdef [MaxCppNestingLevel]; @@ -120,7 +120,7 @@ extern void cppInit (const boolean state, const boolean hasAtLiteralStrings) Cpp.hasAtLiteralStrings = hasAtLiteralStrings; Cpp.directive.state = DRCTV_NONE; - Cpp.directive.accept = TRUE; + Cpp.directive.accept_ = TRUE; Cpp.directive.nestLevel = 0; Cpp.directive.ifdef [0].ignoreAllBranches = FALSE; @@ -564,25 +564,25 @@ process: case NEWLINE: if (directive && ! ignore) directive = FALSE; - Cpp.directive.accept = TRUE; + Cpp.directive.accept_ = TRUE; break; case DOUBLE_QUOTE: - Cpp.directive.accept = FALSE; + Cpp.directive.accept_ = FALSE; c = skipToEndOfString (FALSE); break; case '#': - if (Cpp.directive.accept) + if (Cpp.directive.accept_) { directive = TRUE; - Cpp.directive.state = DRCTV_HASH; - Cpp.directive.accept = FALSE; + Cpp.directive.state = DRCTV_HASH; + Cpp.directive.accept_ = FALSE; } break; case SINGLE_QUOTE: - Cpp.directive.accept = FALSE; + Cpp.directive.accept_ = FALSE; c = skipToEndOfChar (); break; @@ -599,7 +599,7 @@ process: fileUngetc (c); } else - Cpp.directive.accept = FALSE; + Cpp.directive.accept_ = FALSE; break; } @@ -649,12 +649,12 @@ process: int next = fileGetc (); if (next == DOUBLE_QUOTE) { - Cpp.directive.accept = FALSE; + Cpp.directive.accept_ = FALSE; c = skipToEndOfString (TRUE); break; } } - Cpp.directive.accept = FALSE; + Cpp.directive.accept_ = FALSE; if (directive) ignore = handleDirective (c); break; diff --git a/third_party/dlmalloc/dlmalloc.c b/third_party/dlmalloc/dlmalloc.c index 548ca8d78..285466f48 100644 --- a/third_party/dlmalloc/dlmalloc.c +++ b/third_party/dlmalloc/dlmalloc.c @@ -1327,20 +1327,6 @@ void dlmalloc_atfork(void) { } #endif -void* dlvalloc(size_t bytes) { - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void* dlpvalloc(size_t bytes) { - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - void** dlindependent_calloc(size_t n_elements, size_t elem_size, void* chunks[]) { size_t sz = elem_size; /* serves as 1-element array */ diff --git a/third_party/dlmalloc/dlmalloc.h b/third_party/dlmalloc/dlmalloc.h index 0083d5480..b6d1f0ff6 100644 --- a/third_party/dlmalloc/dlmalloc.h +++ b/third_party/dlmalloc/dlmalloc.h @@ -98,13 +98,6 @@ void* dlmemalign(size_t, size_t); */ int dlposix_memalign(void**, size_t, size_t); -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* dlvalloc(size_t); - /* mallopt(int parameter_number, int parameter_value) Sets tunable parameters The format is to provide a @@ -348,13 +341,6 @@ void** dlindependent_comalloc(size_t, size_t*, void**); */ size_t dlbulk_free(void**, size_t n_elements); -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* dlpvalloc(size_t); - /* malloc_trim(size_t pad); diff --git a/third_party/make/file.c b/third_party/make/file.c index c8925de2f..fd5724a72 100644 --- a/third_party/make/file.c +++ b/third_party/make/file.c @@ -1140,7 +1140,8 @@ build_target_list (char *value) void init_hash_files (void) { - hash_init (&files, 1000, file_hash_1, file_hash_2, file_hash_cmp); + // [jart] increased from 1000 + hash_init (&files, 32768, file_hash_1, file_hash_2, file_hash_cmp); } /* EOF */ diff --git a/third_party/make/findprog.h b/third_party/make/findprog.h index 78ce8a7ac..6d2d5b373 100644 --- a/third_party/make/findprog.h +++ b/third_party/make/findprog.h @@ -1,5 +1,4 @@ /* clang-format off */ -/* clang-format off */ /* Locating a program in PATH. Copyright (C) 2001-2003, 2009-2020 Free Software Foundation, Inc. Written by Bruno Haible , 2001. diff --git a/third_party/make/job.c b/third_party/make/job.c index 34df3bf9e..be3a7a25b 100644 --- a/third_party/make/job.c +++ b/third_party/make/job.c @@ -2375,7 +2375,7 @@ exec_command (char **argv, char **envp) /* Run the program. */ environ = envp; - execv (argv[0], argv); + execvp (argv[0], argv); if(errno == ENOENT) OSS (error, NILF, "%s: command doesn't exist: %s", diff --git a/third_party/make/main.c b/third_party/make/main.c index 1034534d6..fdd265565 100644 --- a/third_party/make/main.c +++ b/third_party/make/main.c @@ -1036,6 +1036,10 @@ main (int argc, char **argv, char **envp) #undef FATAL_SIG +#ifndef NDEBUG + ShowCrashReports(); +#endif + /* Do not ignore the child-death signal. This must be done before any children could possibly be created; otherwise, the wait functions won't work on systems with the SVR4 ECHILD brain diff --git a/third_party/make/strcache.c b/third_party/make/strcache.c index 70a9e2f15..6add30cab 100644 --- a/third_party/make/strcache.c +++ b/third_party/make/strcache.c @@ -253,7 +253,8 @@ strcache_add_len (const char *str, size_t len) void strcache_init (void) { - hash_init (&strings, 8000, str_hash_1, str_hash_2, str_hash_cmp); + // [jart] increased from 8000 + hash_init (&strings, 131072, str_hash_1, str_hash_2, str_hash_cmp); } diff --git a/third_party/nsync/futex.c b/third_party/nsync/futex.c index 665b38111..326bbf049 100644 --- a/third_party/nsync/futex.c +++ b/third_party/nsync/futex.c @@ -26,6 +26,7 @@ #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" #include "libc/calls/syscall_support-nt.internal.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" @@ -41,7 +42,6 @@ #include "libc/sysv/errfuns.h" #include "libc/thread/freebsd.internal.h" #include "libc/thread/posixthread.internal.h" -#include "libc/thread/thread.h" #include "libc/thread/tls.h" #include "third_party/nsync/atomic.h" #include "third_party/nsync/common.internal.h" @@ -55,29 +55,32 @@ errno_t _futex (atomic_int *, int, int, const struct timespec *, int *, int); errno_t _futex_wake (atomic_int *, int, int) asm ("_futex"); int sys_futex_cp (atomic_int *, int, int, const struct timespec *, int *, int); -static int FUTEX_WAIT_; -static int FUTEX_PRIVATE_FLAG_; -static bool futex_is_supported; -static bool futex_timeout_is_relative; +static struct NsyncFutex { + _Atomic(uint32_t) once; + int FUTEX_WAIT_; + int FUTEX_PRIVATE_FLAG_; + bool is_supported; + bool timeout_is_relative; +} nsync_futex_; -__attribute__((__constructor__)) static void nsync_futex_init_ (void) { +static void nsync_futex_init_ (void) { int e; atomic_int x; - FUTEX_WAIT_ = FUTEX_WAIT; + nsync_futex_.FUTEX_WAIT_ = FUTEX_WAIT; if (IsWindows ()) { - futex_is_supported = true; + nsync_futex_.is_supported = true; return; } if (IsFreebsd ()) { - futex_is_supported = true; - FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; + nsync_futex_.is_supported = true; + nsync_futex_.FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; return; } - if (!(futex_is_supported = IsLinux () || IsOpenbsd ())) { + if (!(nsync_futex_.is_supported = IsLinux () || IsOpenbsd ())) { return; } @@ -96,22 +99,23 @@ __attribute__((__constructor__)) static void nsync_futex_init_ (void) { if (IsLinux () && _futex (&x, FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, 1, 0, 0, FUTEX_BITSET_MATCH_ANY) == -EAGAIN) { - FUTEX_WAIT_ = FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME; - FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; + nsync_futex_.FUTEX_WAIT_ = + FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME; + nsync_futex_.FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; } else if (!IsTiny () && IsLinux () && _futex (&x, FUTEX_WAIT_BITSET, 1, 0, 0, FUTEX_BITSET_MATCH_ANY) == -EAGAIN) { - FUTEX_WAIT_ = FUTEX_WAIT_BITSET; - FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; + nsync_futex_.FUTEX_WAIT_ = FUTEX_WAIT_BITSET; + nsync_futex_.FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; } else if (IsOpenbsd () || (!IsTiny () && IsLinux () && !_futex_wake (&x, FUTEX_WAKE_PRIVATE, 1))) { - FUTEX_WAIT_ = FUTEX_WAIT; - FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; - futex_timeout_is_relative = true; + nsync_futex_.FUTEX_WAIT_ = FUTEX_WAIT; + nsync_futex_.FUTEX_PRIVATE_FLAG_ = FUTEX_PRIVATE_FLAG; + nsync_futex_.timeout_is_relative = true; } else { - FUTEX_WAIT_ = FUTEX_WAIT; - futex_timeout_is_relative = true; + nsync_futex_.FUTEX_WAIT_ = FUTEX_WAIT; + nsync_futex_.timeout_is_relative = true; } errno = e; } @@ -197,7 +201,7 @@ static struct timespec *nsync_futex_timeout_ (struct timespec *memory, struct timespec now; if (!abstime) { return 0; - } else if (!futex_timeout_is_relative) { + } else if (!nsync_futex_.timeout_is_relative) { *memory = *abstime; return memory; } else { @@ -212,9 +216,11 @@ int nsync_futex_wait_ (atomic_int *w, int expect, char pshare, struct timespec * struct PosixThread *pt = 0; struct timespec tsmem, *timeout; - op = FUTEX_WAIT_; + cosmo_once (&nsync_futex_.once, nsync_futex_init_); + + op = nsync_futex_.FUTEX_WAIT_; if (pshare == PTHREAD_PROCESS_PRIVATE) { - op |= FUTEX_PRIVATE_FLAG_; + op |= nsync_futex_.FUTEX_PRIVATE_FLAG_; } if (abstime && timespec_cmp (*abstime, timespec_zero) <= 0) { @@ -234,7 +240,7 @@ int nsync_futex_wait_ (atomic_int *w, int expect, char pshare, struct timespec * DescribeFutexOp (op), expect, DescribeTimespec (0, timeout)); - if (futex_is_supported) { + if (nsync_futex_.is_supported) { e = errno; if (IsWindows ()) { // Windows 8 futexes don't support multiple processes :( @@ -296,12 +302,14 @@ int nsync_futex_wake_ (atomic_int *w, int count, char pshare) { ASSERT (count == 1 || count == INT_MAX); + cosmo_once (&nsync_futex_.once, nsync_futex_init_); + op = FUTEX_WAKE; if (pshare == PTHREAD_PROCESS_PRIVATE) { - op |= FUTEX_PRIVATE_FLAG_; + op |= nsync_futex_.FUTEX_PRIVATE_FLAG_; } - if (futex_is_supported) { + if (nsync_futex_.is_supported) { if (IsWindows ()) { if (pshare) { goto Polyfill; diff --git a/third_party/nsync/nsync.mk b/third_party/nsync/nsync.mk index dc9374dec..ccb17bff2 100644 --- a/third_party/nsync/nsync.mk +++ b/third_party/nsync/nsync.mk @@ -48,7 +48,7 @@ $(THIRD_PARTY_NSYNC_A).pkg: \ $(THIRD_PARTY_NSYNC_A_OBJS) \ $(foreach x,$(THIRD_PARTY_NSYNC_A_DIRECTDEPS),$($(x)_A).pkg) -#$(THIRD_PARTY_NSYNC_A_OBJS): private \ +$(THIRD_PARTY_NSYNC_A_OBJS): private \ CCFLAGS += \ -ffunction-sections \ -fdata-sections diff --git a/third_party/python/Lib/socket.py b/third_party/python/Lib/socket.py index 5ba8aef4f..62659d171 100644 --- a/third_party/python/Lib/socket.py +++ b/third_party/python/Lib/socket.py @@ -904,7 +904,6 @@ if __name__ == 'PYOBJ.COM': SO_PEERCRED = 0 SO_PEERSEC = 0 SO_PRIORITY = 0 - SO_PROTOCOL = 0 SO_RCVBUF = 0 SO_RCVLOWAT = 0 SO_RCVTIMEO = 0 diff --git a/third_party/python/Modules/socketmodule.c b/third_party/python/Modules/socketmodule.c index 7bfeac1f4..4f153f0d4 100644 --- a/third_party/python/Modules/socketmodule.c +++ b/third_party/python/Modules/socketmodule.c @@ -6760,7 +6760,6 @@ PyInit__socket(void) PyModule_AddIntMacro(m, SO_DEBUG); PyModule_AddIntMacro(m, SO_ACCEPTCONN); if (SO_REUSEADDR) PyModule_AddIntMacro(m, SO_REUSEADDR); - if (SO_EXCLUSIVEADDRUSE) PyModule_AddIntMacro(m, SO_EXCLUSIVEADDRUSE); PyModule_AddIntMacro(m, SO_KEEPALIVE); PyModule_AddIntMacro(m, SO_DONTROUTE); PyModule_AddIntMacro(m, SO_BROADCAST); @@ -6776,17 +6775,6 @@ PyInit__socket(void) PyModule_AddIntMacro(m, SO_RCVTIMEO); PyModule_AddIntMacro(m, SO_ERROR); PyModule_AddIntMacro(m, SO_TYPE); - if (SO_SETFIB) PyModule_AddIntMacro(m, SO_SETFIB); - if (SO_PASSCRED) PyModule_AddIntMacro(m, SO_PASSCRED); - if (SO_PEERCRED) PyModule_AddIntMacro(m, SO_PEERCRED); - if (LOCAL_PEERCRED) PyModule_AddIntMacro(m, LOCAL_PEERCRED); - if (SO_PASSSEC) PyModule_AddIntMacro(m, SO_PASSSEC); - if (SO_PEERSEC) PyModule_AddIntMacro(m, SO_PEERSEC); - if (SO_BINDTODEVICE) PyModule_AddIntMacro(m, SO_BINDTODEVICE); - if (SO_PRIORITY) PyModule_AddIntMacro(m, SO_PRIORITY); - if (SO_MARK) PyModule_AddIntMacro(m, SO_MARK); - if (SO_DOMAIN) PyModule_AddIntMacro(m, SO_DOMAIN); - if (SO_PROTOCOL) PyModule_AddIntMacro(m, SO_PROTOCOL); /* Maximum number of connections for "listen" */ PyModule_AddIntConstant(m, "SOMAXCONN", 0x80); @@ -6915,12 +6903,10 @@ PyInit__socket(void) #endif PyModule_AddIntMacro(m, IPPROTO_IP); - PyModule_AddIntMacro(m, IPPROTO_HOPOPTS); PyModule_AddIntMacro(m, IPPROTO_ICMP); PyModule_AddIntMacro(m, IPPROTO_TCP); PyModule_AddIntMacro(m, IPPROTO_UDP); PyModule_AddIntMacro(m, IPPROTO_RAW); - PyModule_AddIntMacro(m, IPPROTO_IGMP); #ifdef IPPROTO_GGP if (IPPROTO_GGP) PyModule_AddIntMacro(m, IPPROTO_GGP); #endif diff --git a/tool/build/compile.c b/tool/build/compile.c index 3a09cf656..169a62848 100644 --- a/tool/build/compile.c +++ b/tool/build/compile.c @@ -196,10 +196,13 @@ struct itimerval timer; struct timespec signalled; sigset_t mask; +char buf[4096]; sigset_t savemask; -char buf[PAGESIZE]; char tmpout[PATH_MAX]; +char *g_tmpout; +const char *g_tmpout_original; + const char *const kSafeEnv[] = { "ADDR2LINE", // needed by GetAddr2linePath "HOME", // needed by ~/.runit.psk @@ -454,7 +457,13 @@ char *StripPrefix(char *s, char *p) { } } -void AddArg(char *s) { +void AddArg(char *actual) { + const char *s; + if (actual == g_tmpout) { + s = g_tmpout_original; + } else { + s = actual; + } if (args.n) { appendw(&command, ' '); } @@ -487,7 +496,7 @@ void AddArg(char *s) { appendw(&shortened, ' '); appends(&shortened, s); } - AddStr(&args, s); + AddStr(&args, actual); } static int GetBaseCpuFreqMhz(void) { @@ -810,6 +819,7 @@ char *MakeTmpOut(const char *path) { int c; char *p = tmpout; char *e = tmpout + sizeof(tmpout) - 1; + g_tmpout_original = path; p = stpcpy(p, kTmpPath); while ((c = *path++)) { if (c == '/') c = '_'; @@ -820,6 +830,7 @@ char *MakeTmpOut(const char *path) { *p++ = c; } *p = 0; + g_tmpout = tmpout; return tmpout; } diff --git a/tool/build/lib/demangle.c b/tool/build/lib/demangle.c index 3baedd9fb..99c38c0d2 100644 --- a/tool/build/lib/demangle.c +++ b/tool/build/lib/demangle.c @@ -16,13 +16,13 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "tool/build/lib/demangle.h" #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/struct/iovec.h" #include "libc/intrin/safemacros.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" -#include "tool/build/lib/demangle.h" struct CxxFilt { int pid; @@ -83,7 +83,7 @@ char *DemangleCxxFilt(char *p, size_t pn, const char *s, size_t sn) { ssize_t rc; size_t got; struct iovec iov[2]; - static char buf[PAGESIZE]; + static char buf[4096]; if (!g_cxxfilt.pid) SpawnCxxFilt(); if (g_cxxfilt.pid == -1) return NULL; buf[0] = '\n'; diff --git a/tool/build/runitd.c b/tool/build/runitd.c index 6a6baf104..a6671fefe 100644 --- a/tool/build/runitd.c +++ b/tool/build/runitd.c @@ -105,9 +105,9 @@ bool use_ftrace; bool use_strace; char *g_exepath; +unsigned char g_buf[4096]; volatile bool g_interrupted; struct sockaddr_in g_servaddr; -unsigned char g_buf[PAGESIZE]; bool g_daemonize, g_sendready; int g_timeout, g_bogusfd, g_servfd, g_clifd, g_exefd; diff --git a/tool/emacs/c.lang b/tool/emacs/c.lang index 15761c496..efccfc0f4 100644 --- a/tool/emacs/c.lang +++ b/tool/emacs/c.lang @@ -1770,7 +1770,6 @@ Keywords={ "FLT_MIN", "FLT_MAX", "__SAUCE__", -"PAGESIZE", "FRAMESIZE", "ARG_MAX", "PATH_MAX", diff --git a/tool/emacs/cosmo-cpp-constants.el b/tool/emacs/cosmo-cpp-constants.el index 9f7bec4f1..038a4976f 100644 --- a/tool/emacs/cosmo-cpp-constants.el +++ b/tool/emacs/cosmo-cpp-constants.el @@ -176,7 +176,6 @@ (defconst cosmo-cpp-constants-cosmopolitan '("__SAUCE__" - "PAGESIZE" "APE_STACKSIZE" "FRAMESIZE" "ARG_MAX" diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 60b1127d7..4c07a2279 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -2134,6 +2134,10 @@ static void FreeStrings(struct Strings *l) { l->n = 0; } +static unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; +} + static void IndexAssets(void) { uint64_t cf; struct Asset *p; @@ -2145,7 +2149,7 @@ static void IndexAssets(void) { CHECK(READ32LE(zcdir) == kZipCdir64HdrMagic || READ32LE(zcdir) == kZipCdirHdrMagic); n = GetZipCdirRecords(zcdir); - m = _roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR); + m = roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR); p = xcalloc(m, sizeof(struct Asset)); for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) { CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf)); @@ -6675,9 +6679,10 @@ static int MemoryMonitor(void *arg, int tid) { addr = (char *)((int64_t)((uint64_t)mi[i].x << 32) >> 16); color = 0; appendf(&b, "\e[0m%lx", addr); - pages = (mi[i].size + PAGESIZE - 1) / PAGESIZE; + int pagesz = getauxval(AT_PAGESZ); + pages = (mi[i].size + pagesz - 1) / pagesz; for (j = 0; j < pages; ++j) { - rc = mincore(addr + j * PAGESIZE, PAGESIZE, &rez); + rc = mincore(addr + j * pagesz, pagesz, &rez); if (!rc) { if (rez & 1) { if (mi[i].flags & MAP_SHARED) { diff --git a/tool/viz/bf.c b/tool/viz/bf.c index 6c1ac367b..81a5c820b 100644 --- a/tool/viz/bf.c +++ b/tool/viz/bf.c @@ -35,6 +35,10 @@ #define W 64 #define C 253 +static unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; +} + void bf(int fd) { ssize_t rc; uint64_t w; @@ -44,7 +48,7 @@ void bf(int fd) { char ibuf[W], obuf[12 + 1 + W * 6 + 1 + W * (2 + 11) + 11 + 1]; o = 0; if (fstat(fd, &st) != -1 && S_ISREG(st.st_mode) && st.st_size) { - bits = _bsr(_roundup2pow(st.st_size)); + bits = _bsr(roundup2pow(st.st_size)); bits = ROUNDUP(bits, 4); } else { bits = 48; diff --git a/tool/viz/lib/dither.c b/tool/viz/lib/dither.c index 1a91f292d..afb7bd645 100644 --- a/tool/viz/lib/dither.c +++ b/tool/viz/lib/dither.c @@ -18,13 +18,12 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "dsp/tty/quant.h" #include "libc/intrin/hilbert.h" -#include "libc/intrin/morton.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.internal.h" #include "libc/math.h" -#include "libc/mem/mem.h" #include "libc/mem/gc.internal.h" +#include "libc/mem/mem.h" #include "libc/str/str.h" #include "tool/viz/lib/graphic.h" #include "tool/viz/lib/knobs.h" diff --git a/tool/viz/lib/ycbcr2rgb3.c b/tool/viz/lib/ycbcr2rgb3.c index ff1e557e3..66e013139 100644 --- a/tool/viz/lib/ycbcr2rgb3.c +++ b/tool/viz/lib/ycbcr2rgb3.c @@ -27,6 +27,7 @@ #include "dsp/scale/scale.h" #include "libc/calls/calls.h" #include "libc/calls/struct/sigset.h" +#include "libc/intrin/bsr.h" #include "libc/intrin/pmulhrsw.h" #include "libc/log/check.h" #include "libc/log/log.h" @@ -80,6 +81,14 @@ struct YCbCr { } luma, chroma; }; +static unsigned long roundup2pow(unsigned long x) { + return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0; +} + +static unsigned long rounddown2pow(unsigned long x) { + return x ? 1ul << _bsrl(x) : 0; +} + /** * Computes magnums for Y′CbCr decoding. * @@ -95,8 +104,8 @@ void YCbCrComputeCoefficients(int swing, double gamma, double x; double f1[6][3]; long longs[6][6]; - long bitlimit = _roundup2pow(swing); - long wordoffset = _rounddown2pow((bitlimit - swing) / 2); + long bitlimit = roundup2pow(swing); + long wordoffset = rounddown2pow((bitlimit - swing) / 2); long chromaswing = swing + 2 * (bitlimit / 2. - swing / 2. - wordoffset); long lumamin = wordoffset; long lumamax = wordoffset + swing; diff --git a/tool/viz/life.c b/tool/viz/life.c index 02ebf904c..346efc8cd 100644 --- a/tool/viz/life.c +++ b/tool/viz/life.c @@ -258,6 +258,12 @@ static char16_t statusline16[256]; RES = (B11 | r0) & r1 & ~r2; \ } while (0) +static void SwapBoards(void) { + uint64_t *t = board; + board = board2; + board2 = t; +} + static void Step(void) { long y, x, yn, xn; yn = byn >> 3; @@ -275,7 +281,7 @@ static void Step(void) { board[(y + 1 < yn ? y + 1 : 0) * xn + (x + 1 < xn ? x + 1 : 0)]); } } - xchg(&board, &board2); + SwapBoards(); ++generation; } @@ -593,7 +599,7 @@ static int LoadFile(const char *path) { if ((c = ReadChar(f)) == -1) goto ReadError; } if (yn > byn || xn > bxn) goto ReadError; - xchg(&board, &board2); + SwapBoards(); bzero(board, (byn * bxn) >> 3); yo = byn / 2 - yn / 2; xo = bxn / 2 - xn / 2; @@ -640,7 +646,7 @@ static int LoadFile(const char *path) { return 0; ReadError: fclose(f); - xchg(&board, &board2); + SwapBoards(); return -1; } diff --git a/tool/viz/memzoom.c b/tool/viz/memzoom.c index 879745cec..f10626e3a 100644 --- a/tool/viz/memzoom.c +++ b/tool/viz/memzoom.c @@ -31,8 +31,8 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/bits.h" #include "libc/intrin/bsf.h" +#include "libc/intrin/bsr.h" #include "libc/intrin/hilbert.h" -#include "libc/intrin/morton.h" #include "libc/intrin/safemacros.internal.h" #include "libc/log/log.h" #include "libc/macros.internal.h" @@ -188,6 +188,10 @@ static void LeaveScreen(void) { Write("\e[H\e[J"); } +static unsigned long rounddown2pow(unsigned long x) { + return x ? 1ul << _bsrl(x) : 0; +} + static void GetTtySize(void) { struct winsize wsize; wsize.ws_row = tyn + 1; @@ -195,8 +199,8 @@ static void GetTtySize(void) { tcgetwinsize(out, &wsize); tyn = MAX(2, wsize.ws_row) - 1; txn = MAX(17, wsize.ws_col) - 16; - tyn = _rounddown2pow(tyn); - txn = _rounddown2pow(txn); + tyn = rounddown2pow(tyn); + txn = rounddown2pow(txn); tyn = MIN(tyn, txn); } @@ -278,11 +282,30 @@ static void SetupCanvas(void) { } displaysize = ROUNDUP(ROUNDUP((tyn * txn) << zoom, 16), 1ul << zoom); canvassize = ROUNDUP(displaysize, FRAMESIZE); - buffersize = ROUNDUP(tyn * txn * 16 + PAGESIZE, FRAMESIZE); + buffersize = ROUNDUP(tyn * txn * 16 + 4096, FRAMESIZE); canvas = Allocate(canvassize); buffer = Allocate(buffersize); } +/** + * Interleaves bits. + * @see https://en.wikipedia.org/wiki/Z-order_curve + * @see unmorton() + */ +static unsigned long morton(unsigned long y, unsigned long x) { + x = (x | x << 020) & 0x0000FFFF0000FFFF; + x = (x | x << 010) & 0x00FF00FF00FF00FF; + x = (x | x << 004) & 0x0F0F0F0F0F0F0F0F; + x = (x | x << 002) & 0x3333333333333333; + x = (x | x << 001) & 0x5555555555555555; + y = (y | y << 020) & 0x0000FFFF0000FFFF; + y = (y | y << 010) & 0x00FF00FF00FF00FF; + y = (y | y << 004) & 0x0F0F0F0F0F0F0F0F; + y = (y | y << 002) & 0x3333333333333333; + y = (y | y << 001) & 0x5555555555555555; + return x | y << 1; +} + static long IndexSquare(long y, long x) { switch (order) { case LINEAR: diff --git a/tool/viz/printvideo.c b/tool/viz/printvideo.c index a1ffeac12..42256d7d4 100644 --- a/tool/viz/printvideo.c +++ b/tool/viz/printvideo.c @@ -371,7 +371,7 @@ static bool CloseSpeaker(void) { } static void ResizeVtFrame(struct VtFrame *f, size_t yn, size_t xn) { - BALLOC(&f->b, PAGESIZE, 64 + yn * (xn * 32 + 8), __FUNCTION__); + BALLOC(&f->b, 4096, 64 + yn * (xn * 32 + 8), __FUNCTION__); f->i = f->n = 0; } @@ -837,7 +837,8 @@ static void OnVideo(plm_t *mpeg, plm_frame_t *pf, void *user) { } else { TranscodeVideo(pf); if (!f1_->n) { - xchg(&f1_, &f2_); + struct VtFrame *t = f1_; + f1_ = f2_, f2_ = t; f1_start_ = decode_start_; } else { f2_start_ = decode_start_; @@ -872,7 +873,7 @@ static void OpenVideo(void) { static ssize_t WriteVideoCall(void) { size_t amt; ssize_t rc; - amt = min(PAGESIZE * 4, f1_->n - f1_->i); + amt = min(4096 * 4, f1_->n - f1_->i); if ((rc = write(outfd_, f1_->bytes + f1_->i, amt)) != -1) { if ((f1_->i += rc) == f1_->n) { if (plm_get_audio_enabled(plm_)) { @@ -883,7 +884,8 @@ static ssize_t WriteVideoCall(void) { } f1_start_ = f2_start_; f1_->i = f1_->n = 0; - xchg(&f1_, &f2_); + struct VtFrame *t = f1_; + f1_ = f2_, f2_ = t; RecordFactThatFrameWasFullyRendered(); } }