diff --git a/ape/ape.lds b/ape/ape.lds index 15db9913e..3225143b1 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -715,7 +715,7 @@ ASSERT(IS2POW(ape_stack_memsz), "ape_stack_memsz must be a two power"); ASSERT(ape_stack_vaddr % ape_stack_memsz == 0, - "ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 - ape_stack_memsz);"); + "ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);"); ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT, "_Thread_local _Alignof can't exceed TLS_ALIGNMENT"); diff --git a/libc/calls/clock_nanosleep.c b/libc/calls/clock_nanosleep.c index fe257f221..fb3d8e4e5 100644 --- a/libc/calls/clock_nanosleep.c +++ b/libc/calls/clock_nanosleep.c @@ -240,6 +240,8 @@ static bool ShouldUseSpinNanosleep(int clock, int flags, errno_t clock_nanosleep(int clock, int flags, const struct timespec *req, struct timespec *rem) { int rc; + LOCKTRACE("clock_nanosleep(%s, %s, %s) → ...", DescribeClockName(clock), + DescribeSleepFlags(flags), DescribeTimespec(0, req)); if (IsMetal()) { rc = ENOSYS; } else if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) || @@ -259,7 +261,7 @@ errno_t clock_nanosleep(int clock, int flags, const struct timespec *req, if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) { STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock), DescribeSleepFlags(flags), DescribeTimespec(0, req), - DescribeTimespec(rc, rem), DescribeErrnoResult(rc)); + DescribeTimespec(rc, rem), DescribeErrno(rc)); } #endif return rc; diff --git a/libc/calls/fexecve.c b/libc/calls/fexecve.c index 7d12de77d..19b30a019 100644 --- a/libc/calls/fexecve.c +++ b/libc/calls/fexecve.c @@ -26,8 +26,6 @@ #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -int sys_fexecve(int, char *const[], char *const[]); - /** * Executes binary executable at file descriptor. * diff --git a/libc/calls/pledge.c b/libc/calls/pledge.c index ed8721053..c15ace04f 100644 --- a/libc/calls/pledge.c +++ b/libc/calls/pledge.c @@ -24,6 +24,7 @@ #include "libc/errno.h" #include "libc/intrin/promises.internal.h" #include "libc/intrin/strace.internal.h" +#include "libc/nexgen32e/vendor.internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" @@ -238,8 +239,10 @@ int pledge(const char *promises, const char *execpromises) { int e, rc; unsigned long ipromises, iexecpromises; - if (!ParsePromises(promises, &ipromises) && - !ParsePromises(execpromises, &iexecpromises)) { + if (IsGenuineCosmo()) { + rc = 0; // blink doesn't support seccomp + } else if (!ParsePromises(promises, &ipromises) && + !ParsePromises(execpromises, &iexecpromises)) { if (IsLinux()) { // copy exec and execnative from promises to execpromises iexecpromises = ~(~iexecpromises | (~ipromises & (1ul << PROMISE_EXEC))); diff --git a/libc/calls/syscall-sysv.internal.h b/libc/calls/syscall-sysv.internal.h index bd4132c7b..1eaa7df53 100644 --- a/libc/calls/syscall-sysv.internal.h +++ b/libc/calls/syscall-sysv.internal.h @@ -37,6 +37,7 @@ i32 sys_dup(i32) _Hide; i32 sys_dup2(i32, i32) _Hide; i32 sys_dup3(i32, i32, i32) _Hide; i32 sys_execve(const char *, char *const[], char *const[]) _Hide; +i32 sys_execveat(i32, const char *, char *const[], char *const[], i32) _Hide; i32 sys_faccessat(i32, const char *, i32, u32) _Hide; i32 sys_faccessat2(i32, const char *, i32, u32) _Hide; i32 sys_fadvise(i32, i64, i64, i32) _Hide; @@ -47,6 +48,7 @@ i32 sys_fchown(i64, u32, u32) _Hide; i32 sys_fchownat(i32, const char *, u32, u32, u32) _Hide; i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) _Hide; i32 sys_fdatasync(i32) _Hide; +i32 sys_fexecve(i32, char *const[], char *const[]) _Hide; i32 sys_flock(i32, i32) _Hide; i32 sys_fork(void) _Hide; i32 sys_fsync(i32) _Hide; diff --git a/libc/calls/unveil.c b/libc/calls/unveil.c index 2fd55effc..3674d6ee9 100644 --- a/libc/calls/unveil.c +++ b/libc/calls/unveil.c @@ -31,6 +31,7 @@ #include "libc/fmt/conv.h" #include "libc/intrin/strace.internal.h" #include "libc/macros.internal.h" +#include "libc/nexgen32e/vendor.internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" @@ -353,7 +354,9 @@ int sys_unveil_linux(const char *path, const char *permissions) { int unveil(const char *path, const char *permissions) { int e, rc; e = errno; - if (IsLinux()) { + if (IsGenuineCosmo()) { + rc = 0; // blink doesn't support landlock + } else if (IsLinux()) { rc = sys_unveil_linux(path, permissions); } else { rc = sys_unveil(path, permissions); diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index b77cee747..037a785f3 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -159,7 +159,7 @@ static struct AsanMorgue { static bool __asan_once(void) { bool want = false; - static _Atomic(bool) once; + static atomic_int once; return atomic_compare_exchange_strong_explicit( &once, &want, true, memory_order_relaxed, memory_order_relaxed); } diff --git a/libc/intrin/describearchprctlcode.c b/libc/intrin/describearchprctlcode.c index 6ebcd76a9..e7b19fbe2 100644 --- a/libc/intrin/describearchprctlcode.c +++ b/libc/intrin/describearchprctlcode.c @@ -20,7 +20,11 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/describeflags.internal.h" -const char *(DescribeArchPrctlCode)(char buf[12], int x) { +#ifdef DescribeArchPrctlCode +#undef DescribeArchPrctlCode +#endif + +const char *DescribeArchPrctlCode(char buf[12], int x) { if (x == ARCH_SET_FS) return "ARCH_SET_FS"; if (x == ARCH_GET_FS) return "ARCH_GET_FS"; if (x == ARCH_SET_GS) return "ARCH_SET_GS"; diff --git a/libc/intrin/describebacktrace.c b/libc/intrin/describebacktrace.c index f3b3ee6b1..3edf2ea79 100644 --- a/libc/intrin/describebacktrace.c +++ b/libc/intrin/describebacktrace.c @@ -20,11 +20,15 @@ #include "libc/intrin/kprintf.h" #include "libc/nexgen32e/stackframe.h" +#ifdef DescribeBacktrace +#undef DescribeBacktrace +#endif + #define N 64 #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeBacktrace)(char buf[N], struct StackFrame *fr) { +const char *DescribeBacktrace(char buf[N], struct StackFrame *fr) { int o = 0; bool gotsome = false; while (fr) { diff --git a/libc/intrin/describecapability.c b/libc/intrin/describecapability.c index 83570565d..6bd916aa2 100644 --- a/libc/intrin/describecapability.c +++ b/libc/intrin/describecapability.c @@ -22,6 +22,10 @@ #include "libc/str/str.h" #include "libc/sysv/consts/cap.h" +#ifdef DescribeCapability +#undef DescribeCapability +#endif + static const struct thatispacked { unsigned char x; const char *s; @@ -69,7 +73,7 @@ static const struct thatispacked { {CAP_CHECKPOINT_RESTORE, "CHECKPOINT_RESTORE"}, // }; -const char *(DescribeCapability)(char buf[32], int x) { +const char *DescribeCapability(char buf[32], int x) { int i; for (i = 0; i < ARRAYLEN(kCapabilityName); ++i) { if (kCapabilityName[i].x == x) { diff --git a/libc/intrin/describeclockname.c b/libc/intrin/describeclockname.c index 817c5d92f..7f93bfa1f 100644 --- a/libc/intrin/describeclockname.c +++ b/libc/intrin/describeclockname.c @@ -19,9 +19,13 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/describeflags.internal.h" +#ifdef DescribeClockName +#undef DescribeClockName +#endif + /** * Describes clock_gettime() clock argument. */ -const char *(DescribeClockName)(char buf[32], int x) { +const char *DescribeClockName(char buf[32], int x) { return DescribeMagnum(buf, kClockNames, "CLOCK_", x); } diff --git a/libc/intrin/describedirfd.c b/libc/intrin/describedirfd.c index 04b38c371..e4d251399 100644 --- a/libc/intrin/describedirfd.c +++ b/libc/intrin/describedirfd.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/at.h" -const char *(DescribeDirfd)(char buf[12], int dirfd) { +#ifdef DescribeDirfd +#undef DescribeDirfd +#endif + +const char *DescribeDirfd(char buf[12], int dirfd) { if (dirfd == AT_FDCWD) return "AT_FDCWD"; FormatInt32(buf, dirfd); return buf; diff --git a/libc/intrin/describednotify.c b/libc/intrin/describednotify.c index 1b09369d6..9579b21f3 100644 --- a/libc/intrin/describednotify.c +++ b/libc/intrin/describednotify.c @@ -21,6 +21,10 @@ #include "libc/nt/enum/processaccess.h" #include "libc/sysv/consts/dn.h" +#ifdef DescribeDnotifyFlags +#undef DescribeDnotifyFlags +#endif + static const struct DescribeFlags kDnotifyFlags[] = { {DN_ACCESS, "ACCESS"}, // {DN_MODIFY, "MODIFY"}, // @@ -31,7 +35,7 @@ static const struct DescribeFlags kDnotifyFlags[] = { {DN_MULTISHOT, "MULTISHOT"}, // }; -const char *(DescribeDnotifyFlags)(char buf[80], int x) { +const char *DescribeDnotifyFlags(char buf[80], int x) { return DescribeFlags(buf, 80, kDnotifyFlags, ARRAYLEN(kDnotifyFlags), "DN_", x); } diff --git a/libc/intrin/describeerrnoresult.c b/libc/intrin/describeerrnoresult.c index f925ec9dc..35ce01e6e 100644 --- a/libc/intrin/describeerrnoresult.c +++ b/libc/intrin/describeerrnoresult.c @@ -20,12 +20,22 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/str/str.h" -const char *(DescribeErrnoResult)(char buf[12], int ax) { +#ifdef DescribeErrno +#undef DescribeErrno +#endif + +const char *DescribeErrno(char buf[20], int ax) { + char *p = buf; const char *s; - if (ax > -4095u && (s = _strerrno(-ax))) { + if (ax < 0) { + *p++ = '-'; + ax = -ax; + } + if ((s = _strerrno(ax))) { + stpcpy(p, s); return s; } else { - FormatInt32(buf, ax); + FormatInt32(p, ax); return buf; } } diff --git a/libc/intrin/describefcntlcmd.c b/libc/intrin/describefcntlcmd.c index da09bae67..71f9030b5 100644 --- a/libc/intrin/describefcntlcmd.c +++ b/libc/intrin/describefcntlcmd.c @@ -21,7 +21,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/str/str.h" -const char *(DescribeFcntlCmd)(char buf[20], int x) { +#ifdef DescribeFcntlCmd +#undef DescribeFcntlCmd +#endif + +const char *DescribeFcntlCmd(char buf[20], int x) { const char *s; if (x >= 0 && (s = GetMagnumStr(kFcntlCmds, x))) { buf[0] = 'F'; diff --git a/libc/intrin/describeflags.internal.h b/libc/intrin/describeflags.internal.h index c0a591829..219e1292d 100644 --- a/libc/intrin/describeflags.internal.h +++ b/libc/intrin/describeflags.internal.h @@ -17,8 +17,7 @@ const char *DescribeCapability(char[32], int); const char *DescribeClockName(char[32], int); const char *DescribeDirfd(char[12], int); const char *DescribeDnotifyFlags(char[80], int); -const char *DescribeErrno(char[12], int); -const char *DescribeErrnoResult(char[12], int); +const char *DescribeErrno(char[20], int); const char *DescribeFcntlCmd(char[20], int); const char *DescribeFlockType(char[12], int); const char *DescribeFrame(char[32], int); @@ -71,8 +70,7 @@ const char *DescribeWhichPrio(char[12], int); #define DescribeClockName(x) DescribeClockName(alloca(32), x) #define DescribeDirfd(x) DescribeDirfd(alloca(12), x) #define DescribeDnotifyFlags(x) DescribeDnotifyFlags(alloca(80), x) -#define DescribeErrno(x) DescribeErrno(alloca(12), x) -#define DescribeErrnoResult(x) DescribeErrnoResult(alloca(12), x) +#define DescribeErrno(x) DescribeErrno(alloca(20), x) #define DescribeFcntlCmd(x) DescribeFcntlCmd(alloca(20), x) #define DescribeFlockType(x) DescribeFlockType(alloca(12), x) #define DescribeFrame(x) DescribeFrame(alloca(32), x) diff --git a/libc/intrin/describeflock.c b/libc/intrin/describeflock.c index 950a68b0b..60fadcb6e 100644 --- a/libc/intrin/describeflock.c +++ b/libc/intrin/describeflock.c @@ -24,11 +24,15 @@ #include "libc/intrin/kprintf.h" #include "libc/sysv/consts/f.h" +#ifdef DescribeFlock +#undef DescribeFlock +#endif + #define N 300 #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeFlock)(char buf[N], int cmd, const struct flock *l) { +const char *DescribeFlock(char buf[N], int cmd, const struct flock *l) { int o = 0; if (!l) return "NULL"; diff --git a/libc/intrin/describeflocktype.c b/libc/intrin/describeflocktype.c index e42d4f1b8..9d58fbba0 100644 --- a/libc/intrin/describeflocktype.c +++ b/libc/intrin/describeflocktype.c @@ -19,7 +19,11 @@ #include "libc/fmt/itoa.h" #include "libc/sysv/consts/f.h" -const char *(DescribeFlockType)(char buf[12], int x) { +#ifdef DescribeFlockType +#undef DescribeFlockType +#endif + +const char *DescribeFlockType(char buf[12], int x) { if (x == F_RDLCK) return "F_RDLCK"; if (x == F_WRLCK) return "F_WRLCK"; if (x == F_UNLCK) return "F_UNLCK"; diff --git a/libc/intrin/describeframe.c b/libc/intrin/describeframe.c index c8c7fad8a..cedcd0f6c 100644 --- a/libc/intrin/describeframe.c +++ b/libc/intrin/describeframe.c @@ -26,6 +26,10 @@ #include "libc/runtime/runtime.h" #include "libc/runtime/winargs.internal.h" +#ifdef DescribeFrame +#undef DescribeFrame +#endif + #define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16) #define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3) #define FRAME(x) ((int)((x) >> 16)) @@ -74,7 +78,7 @@ static const char *GetFrameName(int x) { } } -const char *(DescribeFrame)(char buf[32], int x) { +const char *DescribeFrame(char buf[32], int x) { char *p; if (IsShadowFrame(x)) { ksnprintf(buf, 32, "%s %s %.8x", GetFrameName(x), diff --git a/libc/intrin/describefutexop.c b/libc/intrin/describefutexop.c index 80993d8d7..157bcdd19 100644 --- a/libc/intrin/describefutexop.c +++ b/libc/intrin/describefutexop.c @@ -21,7 +21,11 @@ #include "libc/str/str.h" #include "libc/sysv/consts/futex.h" -const char *(DescribeFutexOp)(char buf[64], int x) { +#ifdef DescribeFutexOp +#undef DescribeFutexOp +#endif + +const char *DescribeFutexOp(char buf[64], int x) { bool priv = false; if (x & FUTEX_PRIVATE_FLAG) { diff --git a/libc/intrin/describegidlist.c b/libc/intrin/describegidlist.c index c8408b264..7688b134c 100644 --- a/libc/intrin/describegidlist.c +++ b/libc/intrin/describegidlist.c @@ -24,10 +24,14 @@ #include "libc/macros.internal.h" #include "libc/str/str.h" +#ifdef DescribeGidList +#undef DescribeGidList +#endif + #define N 128 -const char *(DescribeGidList)(char buf[N], int rc, int size, - const uint32_t list[]) { +const char *DescribeGidList(char buf[N], int rc, int size, + const uint32_t list[]) { if ((rc == -1) || (size < 0)) return "n/a"; if (!size) return "{}"; if (!list) return "NULL"; diff --git a/libc/intrin/describehow.c b/libc/intrin/describehow.c index 87777d9d8..edbf514ec 100644 --- a/libc/intrin/describehow.c +++ b/libc/intrin/describehow.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/sig.h" -const char *(DescribeHow)(char buf[12], int how) { +#ifdef DescribeHow +#undef DescribeHow +#endif + +const char *DescribeHow(char buf[12], int how) { if (how == SIG_BLOCK) return "SIG_BLOCK"; if (how == SIG_UNBLOCK) return "SIG_UNBLOCK"; if (how == SIG_SETMASK) return "SIG_SETMASK"; diff --git a/libc/intrin/describeiovec.c b/libc/intrin/describeiovec.c index 364736a7e..bd8ae3b03 100644 --- a/libc/intrin/describeiovec.c +++ b/libc/intrin/describeiovec.c @@ -24,12 +24,16 @@ #include "libc/limits.h" #include "libc/macros.internal.h" +#ifdef DescribeIovec +#undef DescribeIovec +#endif + #define N 300 #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeIovec)(char buf[N], ssize_t rc, const struct iovec *iov, - int iovlen) { +const char *DescribeIovec(char buf[N], ssize_t rc, const struct iovec *iov, + int iovlen) { const char *d; int i, j, o = 0; diff --git a/libc/intrin/describemapflags.c b/libc/intrin/describemapflags.c index fedbf81ca..15e02f567 100644 --- a/libc/intrin/describemapflags.c +++ b/libc/intrin/describemapflags.c @@ -22,7 +22,11 @@ #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" -const char *(DescribeMapFlags)(char buf[64], int x) { +#ifdef DescribeMapFlags +#undef DescribeMapFlags +#endif + +const char *DescribeMapFlags(char buf[64], int x) { const struct DescribeFlags kMapFlags[] = { {MAP_STACK, "STACK"}, // order matters {MAP_PRIVATE, "PRIVATE"}, // diff --git a/libc/intrin/describemapping.c b/libc/intrin/describemapping.c index 5fa2a206c..6bf1dc8bb 100644 --- a/libc/intrin/describemapping.c +++ b/libc/intrin/describemapping.c @@ -21,6 +21,10 @@ #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" +#ifdef DescribeMapping +#undef DescribeMapping +#endif + static char DescribeMapType(int flags) { switch (flags & MAP_TYPE) { case MAP_FILE: @@ -44,7 +48,7 @@ char *DescribeProt(char p[4], int prot) { return p; } -const char *(DescribeMapping)(char p[8], int prot, int flags) { +const char *DescribeMapping(char p[8], int prot, int flags) { /* asan runtime depends on this function */ DescribeProt(p, prot); p[3] = DescribeMapType(flags); diff --git a/libc/intrin/describentconsolemodeinputflags.c b/libc/intrin/describentconsolemodeinputflags.c index 8c665030f..a22cf1858 100644 --- a/libc/intrin/describentconsolemodeinputflags.c +++ b/libc/intrin/describentconsolemodeinputflags.c @@ -20,6 +20,10 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/consolemodeflags.h" +#ifdef DescribeNtConsoleInFlags +#undef DescribeNtConsoleInFlags +#endif + static const struct DescribeFlags kConsoleModeInputFlags[] = { {kNtEnableProcessedInput, "ProcessedInput"}, // {kNtEnableLineInput, "LineInput"}, // @@ -33,7 +37,7 @@ static const struct DescribeFlags kConsoleModeInputFlags[] = { {kNtEnableVirtualTerminalInput, "VirtualTerminalInput"}, // }; -const char *(DescribeNtConsoleInFlags)(char buf[256], uint32_t x) { +const char *DescribeNtConsoleInFlags(char buf[256], uint32_t x) { return DescribeFlags(buf, 256, kConsoleModeInputFlags, ARRAYLEN(kConsoleModeInputFlags), "kNtEnable", x); } diff --git a/libc/intrin/describentconsolemodeoutputflags.c b/libc/intrin/describentconsolemodeoutputflags.c index 29ef54456..a69fb028c 100644 --- a/libc/intrin/describentconsolemodeoutputflags.c +++ b/libc/intrin/describentconsolemodeoutputflags.c @@ -20,6 +20,10 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/consolemodeflags.h" +#ifdef DescribeNtConsoleOutFlags +#undef DescribeNtConsoleOutFlags +#endif + static const struct DescribeFlags kConsoleModeOutputFlags[] = { {kNtEnableProcessedOutput, "EnableProcessedOutput"}, // {kNtEnableWrapAtEolOutput, "EnableWrapAtEolOutput"}, // @@ -28,7 +32,7 @@ static const struct DescribeFlags kConsoleModeOutputFlags[] = { {kNtEnableLvbGridWorldwide, "EnableLvbGridWorldwide"}, // }; -const char *(DescribeNtConsoleOutFlags)(char buf[128], uint32_t x) { +const char *DescribeNtConsoleOutFlags(char buf[128], uint32_t x) { return DescribeFlags(buf, 128, kConsoleModeOutputFlags, ARRAYLEN(kConsoleModeOutputFlags), "kNt", x); } diff --git a/libc/intrin/describentfileaccessflags.c b/libc/intrin/describentfileaccessflags.c index a29c17066..4d8c1f02e 100644 --- a/libc/intrin/describentfileaccessflags.c +++ b/libc/intrin/describentfileaccessflags.c @@ -21,6 +21,10 @@ #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/filesharemode.h" +#ifdef DescribeNtFileAccessFlags +#undef DescribeNtFileAccessFlags +#endif + static const struct DescribeFlags kFileAccessflags[] = { {kNtFileAllAccess, "FileAllAccess"}, // order matters {kNtFileGenericRead, "FileGenericRead"}, // order matters @@ -63,7 +67,7 @@ static const struct DescribeFlags kFileAccessflags[] = { {kNtTokenAdjustSessionid, "TokenAdjustSessionid"}, // }; -const char *(DescribeNtFileAccessFlags)(char buf[512], uint32_t x) { +const char *DescribeNtFileAccessFlags(char buf[512], uint32_t x) { return DescribeFlags(buf, 512, kFileAccessflags, ARRAYLEN(kFileAccessflags), "kNt", x); } diff --git a/libc/intrin/describentfileflagattr.c b/libc/intrin/describentfileflagattr.c index d86d35ac4..2bac07d1c 100644 --- a/libc/intrin/describentfileflagattr.c +++ b/libc/intrin/describentfileflagattr.c @@ -21,6 +21,10 @@ #include "libc/nt/enum/fileflagandattributes.h" #include "libc/runtime/runtime.h" +#ifdef DescribeNtFileFlagAttr +#undef DescribeNtFileFlagAttr +#endif + static const struct DescribeFlags kFileFlags[] = { {kNtFileAttributeReadonly, "AttributeReadonly"}, // {kNtFileAttributeHidden, "AttributeHidden"}, // @@ -50,7 +54,7 @@ static const struct DescribeFlags kFileFlags[] = { {kNtFileFlagFirstPipeInstance, "FlagFirstPipeInstance"}, // }; -const char *(DescribeNtFileFlagAttr)(char buf[256], uint32_t x) { +const char *DescribeNtFileFlagAttr(char buf[256], uint32_t x) { if (x == -1u) return "-1u"; return DescribeFlags(buf, 256, kFileFlags, ARRAYLEN(kFileFlags), "kNtFile", x); diff --git a/libc/intrin/describentfilemapflags.c b/libc/intrin/describentfilemapflags.c index cda7a7f5f..1e133db42 100644 --- a/libc/intrin/describentfilemapflags.c +++ b/libc/intrin/describentfilemapflags.c @@ -20,6 +20,10 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/filemapflags.h" +#ifdef DescribeNtFileMapFlags +#undef DescribeNtFileMapFlags +#endif + static const struct DescribeFlags kFileMapFlags[] = { {kNtFileMapCopy, "Copy"}, // {kNtFileMapWrite, "Write"}, // @@ -30,7 +34,7 @@ static const struct DescribeFlags kFileMapFlags[] = { {kNtFileMapLargePages, "LargePages"}, // }; -const char *(DescribeNtFileMapFlags)(char buf[64], uint32_t x) { +const char *DescribeNtFileMapFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kFileMapFlags, ARRAYLEN(kFileMapFlags), "kNtFileMap", x); } diff --git a/libc/intrin/describentfileshareflags.c b/libc/intrin/describentfileshareflags.c index a378bebe8..76c83f0bf 100644 --- a/libc/intrin/describentfileshareflags.c +++ b/libc/intrin/describentfileshareflags.c @@ -20,13 +20,17 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/filesharemode.h" +#ifdef DescribeNtFileShareFlags +#undef DescribeNtFileShareFlags +#endif + static const struct DescribeFlags kFileShareflags[] = { {kNtFileShareRead, "Read"}, // {kNtFileShareWrite, "Write"}, // {kNtFileShareDelete, "Delete"}, // }; -const char *(DescribeNtFileShareFlags)(char buf[64], uint32_t x) { +const char *DescribeNtFileShareFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kFileShareflags, ARRAYLEN(kFileShareflags), "kNtFileShare", x); } diff --git a/libc/intrin/describentfiletypeflags.c b/libc/intrin/describentfiletypeflags.c index a9160d08a..5864f7d33 100644 --- a/libc/intrin/describentfiletypeflags.c +++ b/libc/intrin/describentfiletypeflags.c @@ -21,6 +21,10 @@ #include "libc/nt/enum/filetype.h" #include "libc/sysv/consts/mremap.h" +#ifdef DescribeNtFiletypeFlags +#undef DescribeNtFiletypeFlags +#endif + static const struct DescribeFlags kFiletypeFlags[] = { {kNtFileTypeRemote, "Remote"}, // {kNtFileTypePipe, "Pipe"}, // order matters @@ -28,7 +32,7 @@ static const struct DescribeFlags kFiletypeFlags[] = { {kNtFileTypeChar, "Char"}, // }; -const char *(DescribeNtFiletypeFlags)(char buf[64], uint32_t x) { +const char *DescribeNtFiletypeFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kFiletypeFlags, ARRAYLEN(kFiletypeFlags), "kNtFileType", x); } diff --git a/libc/intrin/describentlockfileflags.c b/libc/intrin/describentlockfileflags.c index d7afc98c6..8b8461913 100644 --- a/libc/intrin/describentlockfileflags.c +++ b/libc/intrin/describentlockfileflags.c @@ -20,12 +20,16 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/filelockflags.h" +#ifdef DescribeNtLockFileFlags +#undef DescribeNtLockFileFlags +#endif + static const struct DescribeFlags kNtLockFileFlags[] = { {kNtLockfileFailImmediately, "FailImmediately"}, // {kNtLockfileExclusiveLock, "ExclusiveLock"}, // }; -const char *(DescribeNtLockFileFlags)(char buf[64], uint32_t x) { +const char *DescribeNtLockFileFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kNtLockFileFlags, ARRAYLEN(kNtLockFileFlags), "kNtLockfile", x); } diff --git a/libc/intrin/describentmovfileinpflags.c b/libc/intrin/describentmovfileinpflags.c index ea3853423..8d0ad601b 100644 --- a/libc/intrin/describentmovfileinpflags.c +++ b/libc/intrin/describentmovfileinpflags.c @@ -20,6 +20,10 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/movefileexflags.h" +#ifdef DescribeNtMovFileInpFlags +#undef DescribeNtMovFileInpFlags +#endif + static const struct DescribeFlags kMoveFileInputFlags[] = { {kNtMovefileReplaceExisting, "ReplaceExisting"}, // {kNtMovefileCopyAllowed, "CopyAllowed"}, // @@ -29,7 +33,7 @@ static const struct DescribeFlags kMoveFileInputFlags[] = { {kNtMovefileFailIfNotTrackable, "FailIfNotTrackable"}, // }; -const char *(DescribeNtMovFileInpFlags)(char buf[256], uint32_t x) { +const char *DescribeNtMovFileInpFlags(char buf[256], uint32_t x) { return DescribeFlags(buf, 256, kMoveFileInputFlags, ARRAYLEN(kMoveFileInputFlags), "kNtMovefile", x); } diff --git a/libc/intrin/describentpageflags.c b/libc/intrin/describentpageflags.c index 3333808f9..8ca82abb6 100644 --- a/libc/intrin/describentpageflags.c +++ b/libc/intrin/describentpageflags.c @@ -20,6 +20,10 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/pageflags.h" +#ifdef DescribeNtPageFlags +#undef DescribeNtPageFlags +#endif + static const struct DescribeFlags kPageFlags[] = { {kNtPageNoaccess, "PageNoaccess"}, // {kNtPageReadonly, "PageReadonly"}, // @@ -41,6 +45,6 @@ static const struct DescribeFlags kPageFlags[] = { {kNtSecWritecombine, "SecWritecombine"}, // }; -const char *(DescribeNtPageFlags)(char buf[64], uint32_t x) { +const char *DescribeNtPageFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kPageFlags, ARRAYLEN(kPageFlags), "kNt", x); } diff --git a/libc/intrin/describentpipemodeflags.c b/libc/intrin/describentpipemodeflags.c index 56d095078..0e015c063 100644 --- a/libc/intrin/describentpipemodeflags.c +++ b/libc/intrin/describentpipemodeflags.c @@ -21,6 +21,10 @@ #include "libc/nt/enum/filemapflags.h" #include "libc/nt/ipc.h" +#ifdef DescribeNtPipeModeFlags +#undef DescribeNtPipeModeFlags +#endif + static const struct DescribeFlags kPipeModeFlags[] = { {kNtPipeNowait, "Nowait"}, // 0x0000000001 {kNtPipeReadmodeMessage, "ReadmodeMessage"}, // 0x0000000002 @@ -32,7 +36,7 @@ static const struct DescribeFlags kPipeModeFlags[] = { //{kNtPipeTypeByte, "TypeByte"}, // 0x00000000 }; -const char *(DescribeNtPipeModeFlags)(char buf[64], uint32_t x) { +const char *DescribeNtPipeModeFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kPipeModeFlags, ARRAYLEN(kPipeModeFlags), "kNtPipe", x); } diff --git a/libc/intrin/describentpipeopenflags.c b/libc/intrin/describentpipeopenflags.c index ebb81c990..10b415dc9 100644 --- a/libc/intrin/describentpipeopenflags.c +++ b/libc/intrin/describentpipeopenflags.c @@ -21,13 +21,17 @@ #include "libc/nt/enum/filemapflags.h" #include "libc/nt/ipc.h" +#ifdef DescribeNtPipeOpenFlags +#undef DescribeNtPipeOpenFlags +#endif + static const struct DescribeFlags kPipeOpenFlags[] = { {kNtPipeAccessDuplex, "Duplex"}, // 0x00000003 {kNtPipeAccessOutbound, "Outbound"}, // 0x00000002 {kNtPipeAccessInbound, "Inbound"}, // 0x00000001 }; -const char *(DescribeNtPipeOpenFlags)(char buf[64], uint32_t x) { +const char *DescribeNtPipeOpenFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kPipeOpenFlags, ARRAYLEN(kPipeOpenFlags), "kNtPipeAccess", x); } diff --git a/libc/intrin/describentprocaccessflags.c b/libc/intrin/describentprocaccessflags.c index 4d2db8d9a..7abb0023d 100644 --- a/libc/intrin/describentprocaccessflags.c +++ b/libc/intrin/describentprocaccessflags.c @@ -20,6 +20,10 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/processaccess.h" +#ifdef DescribeNtProcAccessFlags +#undef DescribeNtProcAccessFlags +#endif + static const struct DescribeFlags kProcessAccessflags[] = { {kNtProcessAllAccess, "AllAccess"}, // {kNtProcessCreateProcess, "CreateProcess"}, // @@ -37,7 +41,7 @@ static const struct DescribeFlags kProcessAccessflags[] = { {kNtProcessSynchronize, "Synchronize"}, // }; -const char *(DescribeNtProcAccessFlags)(char buf[256], uint32_t x) { +const char *DescribeNtProcAccessFlags(char buf[256], uint32_t x) { return DescribeFlags(buf, 256, kProcessAccessflags, ARRAYLEN(kProcessAccessflags), "kNtProcess", x); } diff --git a/libc/intrin/describentstartflags.c b/libc/intrin/describentstartflags.c index 523f4fee2..0d5e0b8f1 100644 --- a/libc/intrin/describentstartflags.c +++ b/libc/intrin/describentstartflags.c @@ -21,6 +21,10 @@ #include "libc/nt/enum/startf.h" #include "libc/sysv/consts/prot.h" +#ifdef DescribeNtStartFlags +#undef DescribeNtStartFlags +#endif + static const struct DescribeFlags kNtStartFlags[] = { {kNtStartfUseshowwindow, "Useshowwindow"}, // {kNtStartfUsesize, "Usesize"}, // @@ -38,7 +42,7 @@ static const struct DescribeFlags kNtStartFlags[] = { {kNtStartfUntrustedsource, "Untrustedsource"}, // }; -const char *(DescribeNtStartFlags)(char buf[128], uint32_t x) { +const char *DescribeNtStartFlags(char buf[128], uint32_t x) { return DescribeFlags(buf, 128, kNtStartFlags, ARRAYLEN(kNtStartFlags), "kNtStartf", x); } diff --git a/libc/intrin/describentsymlinkflags.c b/libc/intrin/describentsymlinkflags.c index f0ed54b47..330de10f1 100644 --- a/libc/intrin/describentsymlinkflags.c +++ b/libc/intrin/describentsymlinkflags.c @@ -20,12 +20,16 @@ #include "libc/macros.internal.h" #include "libc/nt/enum/symboliclink.h" +#ifdef DescribeNtSymlinkFlags +#undef DescribeNtSymlinkFlags +#endif + static const struct DescribeFlags kSymbolicLinkflags[] = { {kNtSymbolicLinkFlagDirectory, "Directory"}, // {kNtSymbolicLinkFlagAllowUnprivilegedCreate, "AllowUnprivilegedCreate"}, // }; -const char *(DescribeNtSymlinkFlags)(char buf[64], uint32_t x) { +const char *DescribeNtSymlinkFlags(char buf[64], uint32_t x) { return DescribeFlags(buf, 64, kSymbolicLinkflags, ARRAYLEN(kSymbolicLinkflags), "kNtSymbolicLinkFlag", x); } diff --git a/libc/intrin/describeopenflags.c b/libc/intrin/describeopenflags.c index 5e80c1069..78cc7cdac 100644 --- a/libc/intrin/describeopenflags.c +++ b/libc/intrin/describeopenflags.c @@ -23,12 +23,16 @@ #include "libc/macros.internal.h" #include "libc/sysv/consts/sol.h" +#ifdef DescribeOpenFlags +#undef DescribeOpenFlags +#endif + #define N (PAGESIZE / 2 / sizeof(struct DescribeFlags)) /** * Describes clock_gettime() clock argument. */ -const char *(DescribeOpenFlags)(char buf[128], int x) { +const char *DescribeOpenFlags(char buf[128], int x) { char *s; int i, n; struct DescribeFlags d[N]; diff --git a/libc/intrin/describepersonalityflags.c b/libc/intrin/describepersonalityflags.c index 6e3a859f2..7e6cb39bf 100644 --- a/libc/intrin/describepersonalityflags.c +++ b/libc/intrin/describepersonalityflags.c @@ -22,6 +22,10 @@ #include "libc/nt/enum/filesharemode.h" #include "libc/sysv/consts/personality.h" +#ifdef DescribePersonalityFlags +#undef DescribePersonalityFlags +#endif + static const struct DescribeFlags kPersonalityFlags[] = { {ADDR_COMPAT_LAYOUT, "ADDR_COMPAT_LAYOUT"}, // {READ_IMPLIES_EXEC, "READ_IMPLIES_EXEC"}, // @@ -36,7 +40,7 @@ static const struct DescribeFlags kPersonalityFlags[] = { {UNAME26, "UNAME26"}, // }; -const char *(DescribePersonalityFlags)(char buf[128], int x) { +const char *DescribePersonalityFlags(char buf[128], int x) { return DescribeFlags(buf, 128, kPersonalityFlags, ARRAYLEN(kPersonalityFlags), "", x); } diff --git a/libc/intrin/describepollflags.c b/libc/intrin/describepollflags.c index fdff13f6d..df9514541 100644 --- a/libc/intrin/describepollflags.c +++ b/libc/intrin/describepollflags.c @@ -21,7 +21,11 @@ #include "libc/nt/enum/filemapflags.h" #include "libc/sysv/consts/poll.h" -const char *(DescribePollFlags)(char buf[64], int x) { +#ifdef DescribePollFlags +#undef DescribePollFlags +#endif + +const char *DescribePollFlags(char buf[64], int x) { const struct DescribeFlags kPollFlags[] = { {POLLIN, "IN"}, // order matters {POLLOUT, "OUT"}, // order matters diff --git a/libc/intrin/describeprotflags.c b/libc/intrin/describeprotflags.c index a2cca029f..5e62c4c95 100644 --- a/libc/intrin/describeprotflags.c +++ b/libc/intrin/describeprotflags.c @@ -20,12 +20,16 @@ #include "libc/macros.internal.h" #include "libc/sysv/consts/prot.h" +#ifdef DescribeProtFlags +#undef DescribeProtFlags +#endif + static const struct DescribeFlags kProtFlags[] = { {PROT_READ, "READ"}, // {PROT_WRITE, "WRITE"}, // {PROT_EXEC, "EXEC"}, // }; -const char *(DescribeProtFlags)(char buf[48], int x) { +const char *DescribeProtFlags(char buf[48], int x) { return DescribeFlags(buf, 48, kProtFlags, ARRAYLEN(kProtFlags), "PROT_", x); } diff --git a/libc/intrin/describeptrace.c b/libc/intrin/describeptrace.c index f266599fe..bcf72221f 100644 --- a/libc/intrin/describeptrace.c +++ b/libc/intrin/describeptrace.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/ptrace.h" -const char *(DescribePtrace)(char buf[12], int x) { +#ifdef DescribePtrace +#undef DescribePtrace +#endif + +const char *DescribePtrace(char buf[12], int x) { if (x == -1) return "-1"; if (x == PTRACE_TRACEME) return "PTRACE_TRACEME"; if (x == PTRACE_PEEKDATA) return "PTRACE_PEEKDATA"; diff --git a/libc/intrin/describeptraceevent.c b/libc/intrin/describeptraceevent.c index b9b003f03..a9dd358fd 100644 --- a/libc/intrin/describeptraceevent.c +++ b/libc/intrin/describeptraceevent.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/ptrace.h" -const char *(DescribePtraceEvent)(char buf[32], int x) { +#ifdef DescribePtraceEvent +#undef DescribePtraceEvent +#endif + +const char *DescribePtraceEvent(char buf[32], int x) { if (x == PTRACE_EVENT_FORK) return "PTRACE_EVENT_FORK"; if (x == PTRACE_EVENT_VFORK) return "PTRACE_EVENT_VFORK"; if (x == PTRACE_EVENT_CLONE) return "PTRACE_EVENT_CLONE"; diff --git a/libc/intrin/describeremapflags.c b/libc/intrin/describeremapflags.c index 9c1684a6d..1b2256ba5 100644 --- a/libc/intrin/describeremapflags.c +++ b/libc/intrin/describeremapflags.c @@ -20,12 +20,16 @@ #include "libc/macros.internal.h" #include "libc/sysv/consts/mremap.h" +#ifdef DescribeRemapFlags +#undef DescribeRemapFlags +#endif + static const struct DescribeFlags kRemapFlags[] = { {MREMAP_MAYMOVE, "MAYMOVE"}, // {MREMAP_FIXED, "FIXED"}, // }; -const char *(DescribeRemapFlags)(char buf[48], int x) { +const char *DescribeRemapFlags(char buf[48], int x) { return DescribeFlags(buf, 48, kRemapFlags, ARRAYLEN(kRemapFlags), "MREMAP_", x); } diff --git a/libc/intrin/describerlimitname.c b/libc/intrin/describerlimitname.c index 1c2d9e5ac..47589bd83 100644 --- a/libc/intrin/describerlimitname.c +++ b/libc/intrin/describerlimitname.c @@ -19,10 +19,14 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/describeflags.internal.h" +#ifdef DescribeRlimitName +#undef DescribeRlimitName +#endif + /** * Describes setrlimit() / getrlimit() argument. */ -const char *(DescribeRlimitName)(char buf[20], int x) { +const char *DescribeRlimitName(char buf[20], int x) { if (x == 127) return "n/a"; return DescribeMagnum(buf, kRlimitNames, "RLIMIT_", x); } diff --git a/libc/intrin/describeschedparam.c b/libc/intrin/describeschedparam.c index bb453a29b..ebdcc384e 100644 --- a/libc/intrin/describeschedparam.c +++ b/libc/intrin/describeschedparam.c @@ -21,10 +21,14 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/str/str.h" +#ifdef DescribeSchedParam +#undef DescribeSchedParam +#endif + /** * Describes clock_gettime() clock argument. */ -const char *(DescribeSchedParam)(char buf[32], const struct sched_param *x) { +const char *DescribeSchedParam(char buf[32], const struct sched_param *x) { char *p; if (!x) return "0"; p = buf; diff --git a/libc/intrin/describeschedpolicy.c b/libc/intrin/describeschedpolicy.c index f1348a66f..71828eff5 100644 --- a/libc/intrin/describeschedpolicy.c +++ b/libc/intrin/describeschedpolicy.c @@ -23,10 +23,14 @@ #include "libc/str/str.h" #include "libc/sysv/consts/sched.h" +#ifdef DescribeSchedPolicy +#undef DescribeSchedPolicy +#endif + /** * Describes clock_gettime() clock argument. */ -const char *(DescribeSchedPolicy)(char buf[48], int x) { +const char *DescribeSchedPolicy(char buf[48], int x) { char *p = buf; if (x == -1) { goto DoNumber; diff --git a/libc/intrin/describesicode.c b/libc/intrin/describesicode.c index d7df1ec8e..e83654ecb 100644 --- a/libc/intrin/describesicode.c +++ b/libc/intrin/describesicode.c @@ -22,6 +22,10 @@ #include "libc/sysv/consts/sicode.h" #include "libc/sysv/consts/sig.h" +#ifdef DescribeSiCode +#undef DescribeSiCode +#endif + static bool IsSiUser(int si_code) { if (!IsOpenbsd()) { return si_code == SI_USER; @@ -38,7 +42,7 @@ static void NameIt(char p[17], const char *s, int si_code) { /** * Returns symbolic name for siginfo::si_code value. */ -const char *(DescribeSiCode)(char b[17], int sig, int si_code) { +const char *DescribeSiCode(char b[17], int sig, int si_code) { NameIt(b, "SI_", si_code); if (si_code == SI_QUEUE) { strcpy(b + 3, "QUEUE"); /* sent by sigqueue(2) */ diff --git a/libc/intrin/describesigaction.c b/libc/intrin/describesigaction.c index d5ca35f19..3b0b77654 100644 --- a/libc/intrin/describesigaction.c +++ b/libc/intrin/describesigaction.c @@ -27,6 +27,10 @@ #include "libc/mem/alloca.h" #include "libc/sysv/consts/sa.h" +#ifdef DescribeSigaction +#undef DescribeSigaction +#endif + static const char *DescribeSigHandler(char buf[64], void f(int)) { if (f == SIG_ERR) return "SIG_ERR"; if (f == SIG_DFL) return "SIG_DFL"; @@ -54,8 +58,7 @@ static const char *DescribeSigFlags(char buf[64], int x) { #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeSigaction)(char buf[N], int rc, - const struct sigaction *sa) { +const char *DescribeSigaction(char buf[N], int rc, const struct sigaction *sa) { int o = 0; char b64[64]; diff --git a/libc/intrin/describesigaltstack.c b/libc/intrin/describesigaltstack.c index be8c04026..ed7d9469a 100644 --- a/libc/intrin/describesigaltstack.c +++ b/libc/intrin/describesigaltstack.c @@ -22,8 +22,12 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/kprintf.h" -const char *(DescribeSigaltstk)(char buf[128], int rc, - const struct sigaltstack *ss) { +#ifdef DescribeSigaltstk +#undef DescribeSigaltstk +#endif + +const char *DescribeSigaltstk(char buf[128], int rc, + const struct sigaltstack *ss) { if (rc == -1) return "n/a"; if (!ss) return "NULL"; if ((!IsAsan() && kisdangerous(ss)) || diff --git a/libc/intrin/describesiginfo.c b/libc/intrin/describesiginfo.c index 15ae49f13..fd09101e2 100644 --- a/libc/intrin/describesiginfo.c +++ b/libc/intrin/describesiginfo.c @@ -26,11 +26,15 @@ #include "libc/str/str.h" #include "libc/sysv/consts/sig.h" +#ifdef DescribeSiginfo +#undef DescribeSiginfo +#endif + #define N 300 #define append(...) i += ksnprintf(buf + i, N - i, __VA_ARGS__) -const char *(DescribeSiginfo)(char buf[N], int rc, const siginfo_t *si) { +const char *DescribeSiginfo(char buf[N], int rc, const siginfo_t *si) { int i = 0; if (rc == -1) return "n/a"; diff --git a/libc/intrin/describesigset.c b/libc/intrin/describesigset.c index 87e0ea04f..233e8ee01 100644 --- a/libc/intrin/describesigset.c +++ b/libc/intrin/describesigset.c @@ -26,11 +26,15 @@ #include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/sig.h" +#ifdef DescribeSigset +#undef DescribeSigset +#endif + #define N 128 #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeSigset)(char buf[N], int rc, const sigset_t *ss) { +const char *DescribeSigset(char buf[N], int rc, const sigset_t *ss) { bool gotsome; const char *s; int sig, o = 0; diff --git a/libc/intrin/describesleepflags.c b/libc/intrin/describesleepflags.c index 9bdd12f4b..3788635c2 100644 --- a/libc/intrin/describesleepflags.c +++ b/libc/intrin/describesleepflags.c @@ -21,10 +21,14 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/timer.h" +#ifdef DescribeSleepFlags +#undef DescribeSleepFlags +#endif + /** * Describes clock_nanosleep() flags argument. */ -const char *(DescribeSleepFlags)(char buf[16], int x) { +const char *DescribeSleepFlags(char buf[16], int x) { switch (x) { case 0: return "0"; diff --git a/libc/intrin/describesocketfamily.c b/libc/intrin/describesocketfamily.c index cf330facc..a3b1f200a 100644 --- a/libc/intrin/describesocketfamily.c +++ b/libc/intrin/describesocketfamily.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/af.h" -const char *(DescribeSocketFamily)(char buf[12], int family) { +#ifdef DescribeSocketFamily +#undef DescribeSocketFamily +#endif + +const char *DescribeSocketFamily(char buf[12], int family) { if (family == AF_UNIX) return "AF_UNIX"; if (family == AF_INET) return "AF_INET"; if (family == AF_INET6) return "AF_INET6"; diff --git a/libc/intrin/describesocketprotocol.c b/libc/intrin/describesocketprotocol.c index a2ae09142..04c41ccff 100644 --- a/libc/intrin/describesocketprotocol.c +++ b/libc/intrin/describesocketprotocol.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/ipproto.h" -const char *(DescribeSocketProtocol)(char buf[12], int family) { +#ifdef DescribeSocketProtocol +#undef DescribeSocketProtocol +#endif + +const char *DescribeSocketProtocol(char buf[12], int family) { if (family == IPPROTO_IP) return "IPPROTO_IP"; if (family == IPPROTO_ICMP) return "IPPROTO_ICMP"; if (family == IPPROTO_TCP) return "IPPROTO_TCP"; diff --git a/libc/intrin/describesockettype.c b/libc/intrin/describesockettype.c index 0a4a05a0d..326de5289 100644 --- a/libc/intrin/describesockettype.c +++ b/libc/intrin/describesockettype.c @@ -21,7 +21,11 @@ #include "libc/str/str.h" #include "libc/sysv/consts/sock.h" -const char *(DescribeSocketType)(char buf[64], int type) { +#ifdef DescribeSocketType +#undef DescribeSocketType +#endif + +const char *DescribeSocketType(char buf[64], int type) { int x; char *p; p = buf; diff --git a/libc/intrin/describesocklevel.c b/libc/intrin/describesocklevel.c index c009ae249..66addf989 100644 --- a/libc/intrin/describesocklevel.c +++ b/libc/intrin/describesocklevel.c @@ -20,10 +20,14 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/sol.h" +#ifdef DescribeSockLevel +#undef DescribeSockLevel +#endif + /** * Describes setsockopt() level arguments. */ -const char *(DescribeSockLevel)(char buf[12], int x) { +const char *DescribeSockLevel(char buf[12], int x) { if (x == SOL_IP) return "SOL_IP"; if (x == SOL_TCP) return "SOL_TCP"; if (x == SOL_UDP) return "SOL_UDP"; diff --git a/libc/intrin/describesockoptname.c b/libc/intrin/describesockoptname.c index 8215fb0c3..71446a0e7 100644 --- a/libc/intrin/describesockoptname.c +++ b/libc/intrin/describesockoptname.c @@ -22,10 +22,14 @@ #include "libc/str/str.h" #include "libc/sysv/consts/sol.h" +#ifdef DescribeSockOptname +#undef DescribeSockOptname +#endif + /** * Describes setsockopt() optname arguments. */ -const char *(DescribeSockOptname)(char buf[32], int l, int x) { +const char *DescribeSockOptname(char buf[32], int l, int x) { int i; char *s, *p; const struct MagnumStr *ms; diff --git a/libc/intrin/describestat.c b/libc/intrin/describestat.c index c844f2247..2f2eb16d1 100644 --- a/libc/intrin/describestat.c +++ b/libc/intrin/describestat.c @@ -22,11 +22,15 @@ #include "libc/intrin/asan.internal.h" #include "libc/intrin/kprintf.h" +#ifdef DescribeStat +#undef DescribeStat +#endif + #define N 300 #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeStat)(char buf[N], int rc, const struct stat *st) { +const char *DescribeStat(char buf[N], int rc, const struct stat *st) { int o = 0; if (rc == -1) return "n/a"; diff --git a/libc/intrin/describestatfs.c b/libc/intrin/describestatfs.c index aa0d40c97..efefe8d8f 100644 --- a/libc/intrin/describestatfs.c +++ b/libc/intrin/describestatfs.c @@ -24,11 +24,15 @@ #include "libc/intrin/kprintf.h" #include "libc/sysv/consts/st.h" +#ifdef DescribeStatfs +#undef DescribeStatfs +#endif + #define N 300 #define append(...) i += ksnprintf(buf + i, N - i, __VA_ARGS__) -const char *(DescribeStatfs)(char buf[N], int rc, const struct statfs *f) { +const char *DescribeStatfs(char buf[N], int rc, const struct statfs *f) { int i = 0; char ibuf[21]; int64_t flags; diff --git a/libc/intrin/describestdiostate.c b/libc/intrin/describestdiostate.c index 25013047a..491ebb532 100644 --- a/libc/intrin/describestdiostate.c +++ b/libc/intrin/describestdiostate.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/str/str.h" -const char *(DescribeStdioState)(char buf[12], int x) { +#ifdef DescribeStdioState +#undef DescribeStdioState +#endif + +const char *DescribeStdioState(char buf[12], int x) { if (!x) return ""; if (x == -1) return "EOF"; if (x > 0) return _strerrno(x); diff --git a/libc/intrin/describestringlist.c b/libc/intrin/describestringlist.c index 707889e53..c1a9f0fc5 100644 --- a/libc/intrin/describestringlist.c +++ b/libc/intrin/describestringlist.c @@ -21,11 +21,15 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/kprintf.h" +#ifdef DescribeStringList +#undef DescribeStringList +#endif + #define N 300 #define append(...) o += ksnprintf(buf + o, N - o, __VA_ARGS__) -const char *(DescribeStringList)(char buf[N], char *const list[]) { +const char *DescribeStringList(char buf[N], char *const list[]) { int i, o = 0; if (!list) return "NULL"; diff --git a/libc/intrin/describetimespec.c b/libc/intrin/describetimespec.c index 73cb887d0..32cee885e 100644 --- a/libc/intrin/describetimespec.c +++ b/libc/intrin/describetimespec.c @@ -23,8 +23,11 @@ #include "libc/intrin/kprintf.h" #include "libc/str/str.h" -const char *(DescribeTimespec)(char buf[45], int rc, - const struct timespec *ts) { +#ifdef DescribeTimespec +#undef DescribeTimespec +#endif + +const char *DescribeTimespec(char buf[45], int rc, const struct timespec *ts) { if (rc == -1) return "n/a"; if (!ts) return "NULL"; if ((!IsAsan() && kisdangerous(ts)) || diff --git a/libc/intrin/describewhence.c b/libc/intrin/describewhence.c index 2b105a622..a0f665641 100644 --- a/libc/intrin/describewhence.c +++ b/libc/intrin/describewhence.c @@ -20,7 +20,11 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/describeflags.internal.h" -const char *(DescribeWhence)(char buf[12], int whence) { +#ifdef DescribeWhence +#undef DescribeWhence +#endif + +const char *DescribeWhence(char buf[12], int whence) { if (whence == SEEK_SET) return "SEEK_SET"; if (whence == SEEK_CUR) return "SEEK_CUR"; if (whence == SEEK_END) return "SEEK_END"; diff --git a/libc/intrin/describewhichprio.c b/libc/intrin/describewhichprio.c index a29eacd91..f61711902 100644 --- a/libc/intrin/describewhichprio.c +++ b/libc/intrin/describewhichprio.c @@ -20,7 +20,11 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/sysv/consts/prio.h" -const char *(DescribeWhichPrio)(char buf[12], int x) { +#ifdef DescribeWhichPrio +#undef DescribeWhichPrio +#endif + +const char *DescribeWhichPrio(char buf[12], int x) { if (x == PRIO_PROCESS) return "PRIO_PROCESS"; if (x == PRIO_PGRP) return "PRIO_PGRP"; if (x == PRIO_USER) return "PRIO_USER"; diff --git a/libc/intrin/fds_lock.c b/libc/intrin/fds_lock.c index dedbabc99..580e85a3b 100644 --- a/libc/intrin/fds_lock.c +++ b/libc/intrin/fds_lock.c @@ -20,11 +20,19 @@ #include "libc/str/str.h" #include "libc/thread/thread.h" -void(__fds_lock)(void) { +#ifdef __fds_lock +#undef __fds_lock +#endif + +#ifdef __fds_unlock +#undef __fds_unlock +#endif + +void __fds_lock(void) { pthread_mutex_lock(&__fds_lock_obj); } -void(__fds_unlock)(void) { +void __fds_unlock(void) { pthread_mutex_unlock(&__fds_lock_obj); } diff --git a/libc/intrin/mmi_lock.c b/libc/intrin/mmi_lock.c index c77359bd8..5694b2252 100644 --- a/libc/intrin/mmi_lock.c +++ b/libc/intrin/mmi_lock.c @@ -20,14 +20,22 @@ #include "libc/str/str.h" #include "libc/thread/thread.h" +#ifdef __mmi_lock +#undef __mmi_lock +#endif + +#ifdef __mmi_unlock +#undef __mmi_unlock +#endif + // this lock currently needs to be (1) recursive and (2) not nsync extern pthread_mutex_t __mmi_lock_obj; -void(__mmi_lock)(void) { +void __mmi_lock(void) { pthread_mutex_lock(&__mmi_lock_obj); } -void(__mmi_unlock)(void) { +void __mmi_unlock(void) { pthread_mutex_unlock(&__mmi_lock_obj); } diff --git a/libc/intrin/psradv.c b/libc/intrin/psradv.c index 8506a4ffa..1b2b6ff1e 100644 --- a/libc/intrin/psradv.c +++ b/libc/intrin/psradv.c @@ -18,13 +18,17 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/psrad.h" +#ifdef psradv +#undef psradv +#endif + /** * Divides shorts by two powers. * * @note arithmetic shift right will sign extend negatives * @mayalias */ -void(psradv)(int32_t a[4], const int32_t b[4], const uint64_t c[2]) { +void psradv(int32_t a[4], const int32_t b[4], const uint64_t c[2]) { unsigned i; unsigned char k; k = c[0] > 31 ? 31 : c[0]; diff --git a/libc/intrin/psubusb.c b/libc/intrin/psubusb.c index 817f75c5b..6f1649ce9 100644 --- a/libc/intrin/psubusb.c +++ b/libc/intrin/psubusb.c @@ -21,6 +21,10 @@ #include "libc/macros.internal.h" #include "libc/str/str.h" +#ifdef psubusb +#undef psubusb +#endif + /** * Subtracts unsigned 8-bit integers w/ saturation. * @@ -29,7 +33,7 @@ * @param 𝑐 [r/o] supplies second input vector * @mayalias */ -void(psubusb)(uint8_t a[16], const uint8_t b[16], const uint8_t c[16]) { +void psubusb(uint8_t a[16], const uint8_t b[16], const uint8_t c[16]) { unsigned i; uint8_t r[16]; for (i = 0; i < 16; ++i) { diff --git a/libc/intrin/psubw.h b/libc/intrin/psubw.h index 52b218706..09043ea56 100644 --- a/libc/intrin/psubw.h +++ b/libc/intrin/psubw.h @@ -4,7 +4,7 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -void(psubw)(int16_t[8], const int16_t[8], const int16_t[8]); +void psubw(int16_t[8], const int16_t[8], const int16_t[8]); #define psubw(A, B, C) \ INTRIN_SSEVEX_X_X_X_(psubw, SSE2, "psubw", INTRIN_NONCOMMUTATIVE, A, B, C) diff --git a/libc/intrin/pthread_cleanup_pop.c b/libc/intrin/pthread_cleanup_pop.c index fba3b853e..6babb3ed4 100644 --- a/libc/intrin/pthread_cleanup_pop.c +++ b/libc/intrin/pthread_cleanup_pop.c @@ -21,7 +21,11 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -void _pthread_cleanup_pop(struct _pthread_cleanup_buffer *cb, int execute) { +#ifdef pthread_cleanup_pop +#undef pthread_cleanup_pop +#endif + +void pthread_cleanup_pop(struct _pthread_cleanup_buffer *cb, int execute) { struct PosixThread *pt; if (__tls_enabled && (pt = (struct PosixThread *)__get_tls()->tib_pthread)) { _unassert(cb == pt->cleanup); diff --git a/libc/intrin/pthread_cleanup_push.c b/libc/intrin/pthread_cleanup_push.c index 519345072..4e5774e8e 100644 --- a/libc/intrin/pthread_cleanup_push.c +++ b/libc/intrin/pthread_cleanup_push.c @@ -20,8 +20,12 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -void _pthread_cleanup_push(struct _pthread_cleanup_buffer *cb, - void (*routine)(void *), void *arg) { +#ifdef pthread_cleanup_push +#undef pthread_cleanup_push +#endif + +void pthread_cleanup_push(struct _pthread_cleanup_buffer *cb, + void (*routine)(void *), void *arg) { struct PosixThread *pt; cb->__routine = routine; cb->__arg = arg; diff --git a/libc/intrin/pthread_spin_lock.c b/libc/intrin/pthread_spin_lock.c index c95bc7455..45ac3ea52 100644 --- a/libc/intrin/pthread_spin_lock.c +++ b/libc/intrin/pthread_spin_lock.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/intrin/atomic.h" +#include "libc/intrin/strace.internal.h" #include "libc/thread/thread.h" #ifdef pthread_spin_lock @@ -44,10 +45,22 @@ */ errno_t pthread_spin_lock(pthread_spinlock_t *spin) { int x; +#if defined(SYSDEBUG) && _LOCKTRACE + for (;;) { + x = atomic_exchange_explicit(&spin->_lock, 1, memory_order_acquire); + if (!x) { + LOCKTRACE("pthread_spin_lock(%t)", spin); + break; + } + _unassert(x == 1); + LOCKTRACE("pthread_spin_lock(%t) trying...", spin); + } +#else for (;;) { x = atomic_exchange_explicit(&spin->_lock, 1, memory_order_acquire); if (!x) break; _unassert(x == 1); } +#endif return 0; } diff --git a/libc/intrin/pthread_spin_unlock.c b/libc/intrin/pthread_spin_unlock.c index 0ee946ed7..8da6c6ebb 100644 --- a/libc/intrin/pthread_spin_unlock.c +++ b/libc/intrin/pthread_spin_unlock.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/atomic.h" +#include "libc/intrin/strace.internal.h" #include "libc/thread/thread.h" #ifdef pthread_spin_unlock @@ -33,6 +34,7 @@ * @see pthread_spin_lock */ errno_t pthread_spin_unlock(pthread_spinlock_t *spin) { + LOCKTRACE("pthread_spin_unlock(%t)", spin); atomic_store_explicit(&spin->_lock, 0, memory_order_release); return 0; } diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index 2d4a79db3..4e1c0d73c 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -297,12 +297,12 @@ static wontreturn relegated noinstrument void __minicrash(int sig, * @vforksafe */ relegated void __oncrash(int sig, struct siginfo *si, ucontext_t *ctx) { - bool bZero; + int bZero; intptr_t rip; int me, owner; int gdbpid, err; static atomic_int once; - static atomic_bool once2; + static atomic_int once2; STRACE("__oncrash rip %x", ctx->uc_mcontext.rip); ftrace_enabled(-1); strace_enabled(-1); diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index c5497399c..93e474132 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -608,7 +608,7 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg, } STRACE("clone(%t, %p, %'zu, %#x, %p, %p, %p, %p) → %s", func, stk, stksz, - flags, arg, ptid, tls, ctid, DescribeErrnoResult(rc)); + flags, arg, ptid, tls, ctid, DescribeErrno(rc)); return rc; } diff --git a/libc/stdio/posix_spawn.c b/libc/stdio/posix_spawn.c index bb33c605d..cdb8ee70d 100644 --- a/libc/stdio/posix_spawn.c +++ b/libc/stdio/posix_spawn.c @@ -92,9 +92,9 @@ int posix_spawn(int *pid, const char *path, posix_spawnattr_getsigmask(attrp, &sigmask); sigprocmask(SIG_SETMASK, &sigmask, 0); } - if (flags & POSIX_SPAWN_RESETIDS) { - setuid(getuid()); - setgid(getgid()); + if ((flags & POSIX_SPAWN_RESETIDS) && + (setgid(getgid()) || setuid(getuid()))) { + _Exit(127); } if (flags & POSIX_SPAWN_SETSIGDEF) { for (s = 1; s < 32; s++) { diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c index 8500e679d..3a0534329 100644 --- a/libc/testlib/testmain.c +++ b/libc/testlib/testmain.c @@ -135,6 +135,7 @@ static void FixIrregularFds(void) { } if (IsGenuineCosmo()) { // TODO(jart): Fix Blinkenlights poll() / close() + free(pfds); return; } if (poll(pfds, maxfds, 0) != -1) { diff --git a/libc/thread/posixthread.internal.h b/libc/thread/posixthread.internal.h index c6034e811..778a3648a 100644 --- a/libc/thread/posixthread.internal.h +++ b/libc/thread/posixthread.internal.h @@ -78,7 +78,6 @@ struct PosixThread { nsync_dll_element_ list; // list of threads jmp_buf exiter; // for pthread_exit pthread_attr_t attr; - sigset_t sigmask; struct _pthread_cleanup_buffer *cleanup; }; diff --git a/libc/calls/clock_nanosleep_latency.c b/libc/thread/pthread_attr_getsigmask_np.c similarity index 71% rename from libc/calls/clock_nanosleep_latency.c rename to libc/thread/pthread_attr_getsigmask_np.c index be5766bf1..a3e1f64b2 100644 --- a/libc/calls/clock_nanosleep_latency.c +++ b/libc/thread/pthread_attr_getsigmask_np.c @@ -16,10 +16,22 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/blockcancel.internal.h" -#include "libc/calls/calls.h" -#include "libc/calls/clock_gettime.internal.h" -#include "libc/errno.h" -#include "libc/macros.internal.h" -#include "libc/sysv/consts/clock.h" +#include "libc/str/str.h" +#include "libc/thread/thread2.h" + +/** + * Gets signal mask on thread attributes object. + * + * @param attr is the thread attributes object + * @param sigmask will receive the output signal mask on success, or + * null if a simple presence check is desired + * @return 0 on success, errno on error, or `PTHREAD_ATTR_NO_SIGMASK_NP` + * if there wasn't any signal mask present in `attr` + */ +errno_t pthread_attr_getsigmask_np(const pthread_attr_t *attr, + sigset_t *sigmask) { + _Static_assert(sizeof(attr->__sigmask) == sizeof(*sigmask), ""); + if (!attr->__havesigmask) return PTHREAD_ATTR_NO_SIGMASK_NP; + if (sigmask) memcpy(sigmask, attr->__sigmask, sizeof(*sigmask)); + return 0; +} diff --git a/libc/thread/pthread_attr_setschedparam.c b/libc/thread/pthread_attr_setschedparam.c index f0871c481..ede54ce90 100644 --- a/libc/thread/pthread_attr_setschedparam.c +++ b/libc/thread/pthread_attr_setschedparam.c @@ -42,7 +42,6 @@ */ errno_t pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) { - if (!param) return EINVAL; attr->__schedparam = param->sched_priority; return 0; } diff --git a/libc/intrin/describeerrno.c b/libc/thread/pthread_attr_setsigmask_np.c similarity index 73% rename from libc/intrin/describeerrno.c rename to libc/thread/pthread_attr_setsigmask_np.c index b40e8ba07..8b64febbe 100644 --- a/libc/intrin/describeerrno.c +++ b/libc/thread/pthread_attr_setsigmask_np.c @@ -16,13 +16,25 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" #include "libc/str/str.h" +#include "libc/thread/thread2.h" -const char *(DescribeErrno)(char buf[12], int x) { - const char *s; - if ((s = _strerrno(x))) return s; - FormatInt32(buf, x); - return buf; +/** + * Sets signal mask on thread attributes object. + * + * @param attr is the thread attributes object + * @param sigmask will be copied into attributes, or if it's null, then + * the existing signal mask presence on the object will be cleared + * @return 0 on success, or errno on error + */ +errno_t pthread_attr_setsigmask_np(pthread_attr_t *attr, + const sigset_t *sigmask) { + _Static_assert(sizeof(attr->__sigmask) == sizeof(*sigmask), ""); + if (sigmask) { + attr->__havesigmask = true; + memcpy(attr->__sigmask, sigmask, sizeof(*sigmask)); + } else { + attr->__havesigmask = false; + } + return 0; } diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 7f46e478d..940c6f1dc 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -32,9 +32,11 @@ #include "libc/runtime/clone.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" +#include "libc/str/str.h" #include "libc/sysv/consts/clone.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/ss.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/spawn.h" @@ -84,7 +86,7 @@ static int PosixThread(void *arg, int tid) { // set long jump handler so pthread_exit can bring control back here if (!setjmp(pt->exiter)) { __get_tls()->tib_pthread = (pthread_t)pt; - _sigsetmask(pt->sigmask); + _npassert(!sigprocmask(SIG_SETMASK, (sigset_t *)pt->attr.__sigmask, 0)); rc = pt->start(pt->arg); // ensure pthread_cleanup_pop(), and pthread_exit() popped cleanup _npassert(!pt->cleanup); @@ -224,6 +226,10 @@ static errno_t pthread_create_impl(pthread_t *thread, } // set initial status + if (!pt->attr.__havesigmask) { + pt->attr.__havesigmask = true; + memcpy(pt->attr.__sigmask, &oldsigs, sizeof(oldsigs)); + } switch (pt->attr.__detachstate) { case PTHREAD_CREATE_JOINABLE: atomic_store_explicit(&pt->status, kPosixThreadJoinable, @@ -246,7 +252,6 @@ static errno_t pthread_create_impl(pthread_t *thread, pthread_spin_unlock(&_pthread_lock); // launch PosixThread(pt) in new thread - pt->sigmask = oldsigs; if ((rc = clone(PosixThread, pt->attr.__stackaddr, pt->attr.__stacksize - (IsOpenbsd() ? 16 : 0), CLONE_VM | CLONE_THREAD | CLONE_FS | CLONE_FILES | @@ -260,9 +265,7 @@ static errno_t pthread_create_impl(pthread_t *thread, return rc; } - if (thread) { - *thread = (pthread_t)pt; - } + *thread = (pthread_t)pt; return 0; } diff --git a/libc/thread/pthread_getaffinity_np.c b/libc/thread/pthread_getaffinity_np.c index 20dcdeeed..762907e66 100644 --- a/libc/thread/pthread_getaffinity_np.c +++ b/libc/thread/pthread_getaffinity_np.c @@ -71,6 +71,6 @@ errno_t pthread_getaffinity_np(pthread_t thread, size_t size, } STRACE("pthread_getaffinity_np(%d, %'zu, %p) → %s", tid, size, bitset, - DescribeErrnoResult(rc)); + DescribeErrno(rc)); return rc; } diff --git a/libc/thread/pthread_join.c b/libc/thread/pthread_join.c index e58de3690..233a4372b 100644 --- a/libc/thread/pthread_join.c +++ b/libc/thread/pthread_join.c @@ -16,13 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/errno.h" -#include "libc/intrin/atomic.h" -#include "libc/thread/posixthread.internal.h" -#include "libc/thread/thread.h" -#include "libc/thread/tls.h" -#include "libc/thread/wait0.internal.h" +#include "libc/thread/thread2.h" /** * Waits for thread to terminate. @@ -44,24 +38,5 @@ * @threadsafe */ errno_t pthread_join(pthread_t thread, void **value_ptr) { - errno_t rc; - struct PosixThread *pt; - enum PosixThreadStatus status; - pt = (struct PosixThread *)thread; - status = atomic_load_explicit(&pt->status, memory_order_acquire); - // "The behavior is undefined if the value specified by the thread - // argument to pthread_join() does not refer to a joinable thread." - // ──Quoth POSIX.1-2017 - _unassert(status == kPosixThreadJoinable || status == kPosixThreadTerminated); - if (!(rc = _wait0(&pt->tib->tib_tid))) { - pthread_spin_lock(&_pthread_lock); - _pthread_list = nsync_dll_remove_(_pthread_list, &pt->list); - pthread_spin_unlock(&_pthread_lock); - if (value_ptr) { - *value_ptr = pt->rc; - } - _pthread_free(pt); - pthread_decimate_np(); - } - return 0; + return pthread_timedjoin_np(thread, value_ptr, 0); } diff --git a/libc/thread/pthread_orphan_np.c b/libc/thread/pthread_orphan_np.c index 9d2a0832d..7c86bc0e2 100644 --- a/libc/thread/pthread_orphan_np.c +++ b/libc/thread/pthread_orphan_np.c @@ -22,7 +22,7 @@ /** * Returns true if calling thread is the only thread. */ -bool pthread_orphan_np(void) { +int pthread_orphan_np(void) { bool res; pthread_spin_lock(&_pthread_lock); res = _pthread_list == _pthread_list->prev && diff --git a/libc/thread/pthread_setaffinity_np.c b/libc/thread/pthread_setaffinity_np.c index a4ed86415..2b7b06886 100644 --- a/libc/thread/pthread_setaffinity_np.c +++ b/libc/thread/pthread_setaffinity_np.c @@ -74,6 +74,6 @@ errno_t pthread_setaffinity_np(pthread_t thread, size_t size, } } STRACE("pthread_setaffinity_np(%d, %'zu, %p) → %s", tid, size, bitset, - DescribeErrnoResult(rc)); + DescribeErrno(rc)); return rc; } diff --git a/libc/thread/pthread_setschedparam.c b/libc/thread/pthread_setschedparam.c index 7a5d36c13..88e41049f 100644 --- a/libc/thread/pthread_setschedparam.c +++ b/libc/thread/pthread_setschedparam.c @@ -44,7 +44,6 @@ errno_t pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param) { struct PosixThread *pt = (struct PosixThread *)thread; - if (!param) return EINVAL; pt->attr.__schedpolicy = policy; pt->attr.__schedparam = param->sched_priority; return _pthread_reschedule(pt); diff --git a/libc/thread/pthread_timedjoin_np.c b/libc/thread/pthread_timedjoin_np.c new file mode 100644 index 000000000..9de4d800e --- /dev/null +++ b/libc/thread/pthread_timedjoin_np.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" +#include "libc/calls/struct/timespec.h" +#include "libc/errno.h" +#include "libc/intrin/atomic.h" +#include "libc/thread/posixthread.internal.h" +#include "libc/thread/thread2.h" +#include "libc/thread/tls.h" +#include "libc/thread/wait0.internal.h" + +/** + * Waits for thread to terminate. + * + * Multiple threads joining the same thread is undefined behavior. If a + * deferred or masked cancellation happens to the calling thread either + * before or during the waiting process then the target thread will not + * be joined. Calling pthread_join() on a non-joinable thread, e.g. one + * that's been detached, is undefined behavior. If a thread attempts to + * join itself, then the behavior is undefined. + * + * @param value_ptr if non-null will receive pthread_exit() argument + * if the thread called pthread_exit(), or `PTHREAD_CANCELED` if + * pthread_cancel() destroyed the thread instead + * @param abstime specifies an absolute deadline or the timestamp of + * when we'll stop waiting; if this is null we will wait forever + * @return 0 on success, or errno on error + * @raise ECANCELED if calling thread was cancelled in masked mode + * @raise EBUSY if `abstime` deadline elapsed + * @cancellationpoint + * @returnserrno + * @threadsafe + */ +errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr, + struct timespec *abstime) { + errno_t rc; + struct PosixThread *pt; + enum PosixThreadStatus status; + pt = (struct PosixThread *)thread; + status = atomic_load_explicit(&pt->status, memory_order_acquire); + // "The behavior is undefined if the value specified by the thread + // argument to pthread_join() does not refer to a joinable thread." + // ──Quoth POSIX.1-2017 + _unassert(status == kPosixThreadJoinable || status == kPosixThreadTerminated); + if (!(rc = _wait0(&pt->tib->tib_tid, abstime))) { + pthread_spin_lock(&_pthread_lock); + _pthread_list = nsync_dll_remove_(_pthread_list, &pt->list); + pthread_spin_unlock(&_pthread_lock); + if (value_ptr) { + *value_ptr = pt->rc; + } + _pthread_free(pt); + pthread_decimate_np(); + } + return 0; +} diff --git a/libc/thread/pthread_tryjoin_np.c b/libc/thread/pthread_tryjoin_np.c new file mode 100644 index 000000000..ae5f02881 --- /dev/null +++ b/libc/thread/pthread_tryjoin_np.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/thread/thread2.h" + +/** + * Joins thread if it's already terminated. + * + * Multiple threads joining the same thread is undefined behavior. If a + * deferred or masked cancellation happens to the calling thread either + * before or during the waiting process then the target thread will not + * be joined. Calling pthread_join() on a non-joinable thread, e.g. one + * that's been detached, is undefined behavior. If a thread attempts to + * join itself, then the behavior is undefined. + * + * @param value_ptr if non-null will receive pthread_exit() argument + * if the thread called pthread_exit(), or `PTHREAD_CANCELED` if + * pthread_cancel() destroyed the thread instead + * @return 0 on success, or errno on error + * @raise ECANCELED if calling thread was cancelled in masked mode + * @cancellationpoint + * @returnserrno + * @threadsafe + */ +errno_t pthread_tryjoin_np(pthread_t thread, void **value_ptr) { + return pthread_timedjoin_np(thread, value_ptr, ×pec_zero); +} diff --git a/libc/thread/sem_post.c b/libc/thread/sem_post.c index 91532a69d..4587c9938 100644 --- a/libc/thread/sem_post.c +++ b/libc/thread/sem_post.c @@ -34,7 +34,7 @@ int sem_post(sem_t *sem) { int rc, old, wakeups; _unassert(sem->sem_pshared || sem->sem_pid == getpid()); - old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_relaxed); + old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_acq_rel); _unassert(old > INT_MIN); if (old >= 0) { wakeups = nsync_futex_wake_(&sem->sem_value, 1, sem->sem_pshared); diff --git a/libc/thread/spawn.c b/libc/thread/spawn.c index 20bedfb53..6c10ca19e 100644 --- a/libc/thread/spawn.c +++ b/libc/thread/spawn.c @@ -16,6 +16,7 @@ │ 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/errno.h" #include "libc/macros.internal.h" @@ -148,7 +149,7 @@ int _join(struct spawn *th) { int rc; if (th->tib) { // wait for ctid to become zero - _wait0(&th->tib->tib_tid); + _npassert(!_wait0(&th->tib->tib_tid, 0)); // free thread memory free(th->tls); rc = munmap(th->stk, GetStackSize()); diff --git a/libc/thread/thread.h b/libc/thread/thread.h index 25d3126b4..aac9c91c3 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -35,6 +35,8 @@ #define PTHREAD_SCOPE_SYSTEM 0 #define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_ATTR_NO_SIGMASK_NP -1 + #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -58,7 +60,7 @@ typedef struct pthread_once_s { } pthread_once_t; typedef struct pthread_spinlock_s { - _Atomic(char) _lock; + _Atomic(int) _lock; } pthread_spinlock_t; typedef struct pthread_mutex_s { @@ -91,11 +93,13 @@ typedef struct pthread_barrier_s { typedef struct pthread_attr_s { char __detachstate; char __inheritsched; + char __havesigmask; int __schedparam; int __schedpolicy; int __contentionscope; unsigned __guardsize; unsigned __stacksize; + uint32_t __sigmask[4]; char *__stackaddr; } pthread_attr_t; @@ -106,108 +110,109 @@ struct _pthread_cleanup_buffer { struct _pthread_cleanup_buffer *__prev; }; -int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), - void *); +/* clang-format off */ -int pthread_yield(void); -bool pthread_orphan_np(void); -void pthread_testcancel(void); -void pthread_decimate_np(void); -int pthread_testcancel_np(void); -void pthread_exit(void *) wontreturn; -pthread_t pthread_self(void) pureconst; -int pthread_print_np(int, const char *, ...); -pthread_id_np_t pthread_getthreadid_np(void); -int pthread_getunique_np(pthread_t, pthread_id_np_t *); -int pthread_setname_np(pthread_t, const char *); -int pthread_getname_np(pthread_t, char *, size_t); -int pthread_getattr_np(pthread_t, pthread_attr_t *); -int pthread_attr_init(pthread_attr_t *); -int pthread_attr_destroy(pthread_attr_t *); -int pthread_attr_getdetachstate(const pthread_attr_t *, int *); -int pthread_attr_setdetachstate(pthread_attr_t *, int); -int pthread_attr_getguardsize(const pthread_attr_t *, size_t *); -int pthread_attr_setguardsize(pthread_attr_t *, size_t); -int pthread_attr_getinheritsched(const pthread_attr_t *, int *); -int pthread_attr_setinheritsched(pthread_attr_t *, int); -int pthread_attr_getschedpolicy(const pthread_attr_t *, int *); -int pthread_attr_setschedpolicy(pthread_attr_t *, int); -int pthread_attr_getscope(const pthread_attr_t *, int *); -int pthread_attr_setscope(pthread_attr_t *, int); -int pthread_attr_getstack(const pthread_attr_t *, void **, size_t *); -int pthread_attr_setstack(pthread_attr_t *, void *, size_t); -int pthread_attr_getstacksize(const pthread_attr_t *, size_t *); -int pthread_attr_setstacksize(pthread_attr_t *, size_t); -int pthread_detach(pthread_t); -int pthread_kill(pthread_t, int); -int pthread_cancel(pthread_t); -int pthread_setcanceltype(int, int *); -int pthread_setcancelstate(int, int *); -int pthread_setschedprio(pthread_t, int); -int pthread_join(pthread_t, void **); -int pthread_equal(pthread_t, pthread_t); -int pthread_once(pthread_once_t *, void (*)(void)); -int pthread_spin_init(pthread_spinlock_t *, int); -int pthread_spin_destroy(pthread_spinlock_t *); -int pthread_spin_lock(pthread_spinlock_t *); -int pthread_spin_unlock(pthread_spinlock_t *); -int pthread_spin_trylock(pthread_spinlock_t *); -int pthread_mutexattr_init(pthread_mutexattr_t *); -int pthread_mutexattr_destroy(pthread_mutexattr_t *); -int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *); -int pthread_mutexattr_settype(pthread_mutexattr_t *, int); -int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); -int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *); int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)); -int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); -int pthread_mutex_lock(pthread_mutex_t *); -int pthread_mutex_unlock(pthread_mutex_t *); -int pthread_mutex_trylock(pthread_mutex_t *); -int pthread_mutex_destroy(pthread_mutex_t *); -int pthread_mutex_consistent(pthread_mutex_t *); -int pthread_condattr_init(pthread_condattr_t *); -int pthread_condattr_destroy(pthread_condattr_t *); -int pthread_condattr_setpshared(pthread_condattr_t *, int); -int pthread_condattr_getpshared(const pthread_condattr_t *, int *); -int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); -int pthread_cond_destroy(pthread_cond_t *); -int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); -int pthread_cond_broadcast(pthread_cond_t *); -int pthread_cond_signal(pthread_cond_t *); -int pthread_rwlockattr_init(pthread_rwlockattr_t *); -int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); -int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); -int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); -int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); -int pthread_rwlock_destroy(pthread_rwlock_t *); -int pthread_rwlock_rdlock(pthread_rwlock_t *); -int pthread_rwlock_tryrdlock(pthread_rwlock_t *); -int pthread_rwlock_wrlock(pthread_rwlock_t *); -int pthread_rwlock_trywrlock(pthread_rwlock_t *); -int pthread_rwlock_unlock(pthread_rwlock_t *); -int pthread_key_create(pthread_key_t *, pthread_key_dtor); +int pthread_attr_destroy(pthread_attr_t *) paramsnonnull(); +int pthread_attr_getdetachstate(const pthread_attr_t *, int *) paramsnonnull(); +int pthread_attr_getguardsize(const pthread_attr_t *, size_t *) paramsnonnull(); +int pthread_attr_getinheritsched(const pthread_attr_t *, int *) paramsnonnull(); +int pthread_attr_getschedpolicy(const pthread_attr_t *, int *) paramsnonnull(); +int pthread_attr_getscope(const pthread_attr_t *, int *) paramsnonnull(); +int pthread_attr_getstack(const pthread_attr_t *, void **, size_t *) paramsnonnull(); +int pthread_attr_getstacksize(const pthread_attr_t *, size_t *) paramsnonnull(); +int pthread_attr_init(pthread_attr_t *) paramsnonnull(); +int pthread_attr_setdetachstate(pthread_attr_t *, int) paramsnonnull(); +int pthread_attr_setguardsize(pthread_attr_t *, size_t) paramsnonnull(); +int pthread_attr_setinheritsched(pthread_attr_t *, int) paramsnonnull(); +int pthread_attr_setschedpolicy(pthread_attr_t *, int) paramsnonnull(); +int pthread_attr_setscope(pthread_attr_t *, int) paramsnonnull(); +int pthread_attr_setstack(pthread_attr_t *, void *, size_t) paramsnonnull((1)); +int pthread_attr_setstacksize(pthread_attr_t *, size_t) paramsnonnull(); +int pthread_barrier_destroy(pthread_barrier_t *) paramsnonnull(); +int pthread_barrier_init(pthread_barrier_t *, const pthread_barrierattr_t *, unsigned) paramsnonnull((1)); +int pthread_barrier_wait(pthread_barrier_t *) paramsnonnull(); +int pthread_barrierattr_destroy(pthread_barrierattr_t *) paramsnonnull(); +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *, int *) paramsnonnull(); +int pthread_barrierattr_init(pthread_barrierattr_t *) paramsnonnull(); +int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int) paramsnonnull(); +int pthread_cancel(pthread_t); +int pthread_cond_broadcast(pthread_cond_t *) paramsnonnull(); +int pthread_cond_destroy(pthread_cond_t *) paramsnonnull(); +int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *) paramsnonnull((1)); +int pthread_cond_signal(pthread_cond_t *) paramsnonnull(); +int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *) paramsnonnull(); +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_detach(pthread_t); +int pthread_equal(pthread_t, pthread_t); +int pthread_getattr_np(pthread_t, pthread_attr_t *) paramsnonnull(); +int pthread_getname_np(pthread_t, char *, size_t) paramsnonnull(); +int pthread_getunique_np(pthread_t, pthread_id_np_t *) paramsnonnull(); +int pthread_join(pthread_t, void **); +int pthread_key_create(pthread_key_t *, pthread_key_dtor) paramsnonnull((1)); int pthread_key_delete(pthread_key_t); +int pthread_kill(pthread_t, int); +int pthread_mutex_consistent(pthread_mutex_t *) paramsnonnull(); +int pthread_mutex_destroy(pthread_mutex_t *) paramsnonnull(); +int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *) paramsnonnull((1)); +int pthread_mutex_lock(pthread_mutex_t *) paramsnonnull(); +int pthread_mutex_trylock(pthread_mutex_t *) paramsnonnull(); +int pthread_mutex_unlock(pthread_mutex_t *) paramsnonnull(); +int pthread_mutexattr_destroy(pthread_mutexattr_t *) paramsnonnull(); +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *) paramsnonnull(); +int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *) paramsnonnull(); +int pthread_mutexattr_init(pthread_mutexattr_t *) paramsnonnull(); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int) paramsnonnull(); +int pthread_mutexattr_settype(pthread_mutexattr_t *, int) paramsnonnull(); +int pthread_once(pthread_once_t *, void (*)(void)) paramsnonnull(); +int pthread_orphan_np(void); +int pthread_print_np(int, const char *, ...); +int pthread_rwlock_destroy(pthread_rwlock_t *) paramsnonnull(); +int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *) paramsnonnull((1)); +int pthread_rwlock_rdlock(pthread_rwlock_t *) paramsnonnull(); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *) paramsnonnull(); +int pthread_rwlock_trywrlock(pthread_rwlock_t *) paramsnonnull(); +int pthread_rwlock_unlock(pthread_rwlock_t *) paramsnonnull(); +int pthread_rwlock_wrlock(pthread_rwlock_t *) paramsnonnull(); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *) paramsnonnull(); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *) paramsnonnull(); +int pthread_rwlockattr_init(pthread_rwlockattr_t *) paramsnonnull(); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int) paramsnonnull(); +int pthread_setcancelstate(int, int *); +int pthread_setcanceltype(int, int *); +int pthread_setname_np(pthread_t, const char *) paramsnonnull(); +int pthread_setschedprio(pthread_t, int); int pthread_setspecific(pthread_key_t, const void *); +int pthread_spin_destroy(pthread_spinlock_t *) paramsnonnull(); +int pthread_spin_init(pthread_spinlock_t *, int) paramsnonnull(); +int pthread_spin_lock(pthread_spinlock_t *) paramsnonnull(); +int pthread_spin_trylock(pthread_spinlock_t *) paramsnonnull(); +int pthread_spin_unlock(pthread_spinlock_t *) paramsnonnull(); +int pthread_testcancel_np(void); +int pthread_tryjoin_np(pthread_t, void **); +int pthread_yield(void); +pthread_id_np_t pthread_getthreadid_np(void); +pthread_t pthread_self(void) pureconst; void *pthread_getspecific(pthread_key_t); -int pthread_barrierattr_init(pthread_barrierattr_t *); -int pthread_barrierattr_destroy(pthread_barrierattr_t *); -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *, int *); -int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int); -int pthread_barrier_wait(pthread_barrier_t *); -int pthread_barrier_destroy(pthread_barrier_t *); -int pthread_barrier_init(pthread_barrier_t *, const pthread_barrierattr_t *, - unsigned); -void _pthread_cleanup_pop(struct _pthread_cleanup_buffer *, int); -void _pthread_cleanup_push(struct _pthread_cleanup_buffer *, void (*)(void *), - void *); +void pthread_cleanup_pop(struct _pthread_cleanup_buffer *, int) paramsnonnull(); +void pthread_cleanup_push(struct _pthread_cleanup_buffer *, void (*)(void *), void *) paramsnonnull((1)); +void pthread_decimate_np(void); +void pthread_exit(void *) wontreturn; +void pthread_testcancel(void); + +/* clang-format on */ #define pthread_cleanup_push(routine, arg) \ { \ struct _pthread_cleanup_buffer _buffer; \ - _pthread_cleanup_push(&_buffer, (routine), (arg)); + pthread_cleanup_push(&_buffer, (routine), (arg)); -#define pthread_cleanup_pop(execute) \ - _pthread_cleanup_pop(&_buffer, (execute)); \ +#define pthread_cleanup_pop(execute) \ + pthread_cleanup_pop(&_buffer, (execute)); \ } #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 && \ diff --git a/libc/thread/thread2.h b/libc/thread/thread2.h index ec6b4a216..8868ea73e 100644 --- a/libc/thread/thread2.h +++ b/libc/thread/thread2.h @@ -2,21 +2,26 @@ #define COSMOPOLITAN_LIBC_INTRIN_PTHREAD2_H_ #include "libc/calls/struct/cpuset.h" #include "libc/calls/struct/sched_param.h" +#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/timespec.h" #include "libc/runtime/stack.h" #include "libc/thread/thread.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +/* clang-format off */ -int pthread_attr_getschedparam(const pthread_attr_t *, struct sched_param *); -int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *); -int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, - const struct timespec *); -int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *); -int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *); -int pthread_setschedparam(pthread_t, int, const struct sched_param *); -int pthread_getschedparam(pthread_t, int *, struct sched_param *); +int pthread_attr_getschedparam(const pthread_attr_t *, struct sched_param *) paramsnonnull(); +int pthread_attr_getsigmask_np(const pthread_attr_t *, sigset_t *) paramsnonnull((1)); +int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *) paramsnonnull(); +int pthread_attr_setsigmask_np(pthread_attr_t *, const sigset_t *) paramsnonnull((1)); +int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *) paramsnonnull((1, 2)); +int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *) paramsnonnull(); +int pthread_getschedparam(pthread_t, int *, struct sched_param *) paramsnonnull(); +int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *) paramsnonnull(); +int pthread_setschedparam(pthread_t, int, const struct sched_param *) paramsnonnull(); +int pthread_timedjoin_np(pthread_t, void **, struct timespec *); +/* clang-format off */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_INTRIN_PTHREAD2_H_ */ diff --git a/libc/thread/wait0.c b/libc/thread/wait0.c index 17433e48d..198544709 100644 --- a/libc/thread/wait0.c +++ b/libc/thread/wait0.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/cp.internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" @@ -37,9 +38,10 @@ * * @return 0 on success, or errno on error * @raise ECANCELED if calling thread was cancelled in masked mode + * @raise EBUSY if `abstime` was specified and deadline expired * @cancellationpoint */ -errno_t _wait0(const atomic_int *ctid) { +errno_t _wait0(const atomic_int *ctid, struct timespec *abstime) { int x, rc = 0; // "The behavior is undefined if the value specified by the thread // argument to pthread_join() refers to the calling thread." @@ -50,9 +52,13 @@ errno_t _wait0(const atomic_int *ctid) { if (!(rc = pthread_testcancel_np())) { BEGIN_CANCELLATION_POINT; while ((x = atomic_load_explicit(ctid, memory_order_acquire))) { - if (nsync_futex_wait_(ctid, x, !IsWindows(), 0) == -ECANCELED) { + rc = nsync_futex_wait_(ctid, x, !IsWindows(), abstime); + if (rc == -ECANCELED) { rc = ECANCELED; break; + } else if (rc == -ETIMEDOUT) { + rc = EBUSY; + break; } } END_CANCELLATION_POINT; diff --git a/libc/thread/wait0.internal.h b/libc/thread/wait0.internal.h index e4f4d8af4..89e986f69 100644 --- a/libc/thread/wait0.internal.h +++ b/libc/thread/wait0.internal.h @@ -1,10 +1,11 @@ #ifndef COSMOPOLITAN_LIBC_INTRIN_WAIT0_H_ #define COSMOPOLITAN_LIBC_INTRIN_WAIT0_H_ #include "libc/atomic.h" +#include "libc/calls/struct/timespec.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -errno_t _wait0(const atomic_int *) _Hide; +errno_t _wait0(const atomic_int *, struct timespec *) _Hide; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/net/http/findcontenttype.c b/net/http/findcontenttype.c index defb2ab42..04595c986 100644 --- a/net/http/findcontenttype.c +++ b/net/http/findcontenttype.c @@ -42,6 +42,7 @@ static const struct ContentTypeExtension { {"css", "text/css"}, // {"csv", "text/csv"}, // {"diff", "text/plain"}, // + {"diff", "text/plain"}, // {"doc", "application/msword"}, // {"epub", "application/epub+zip"}, // {"gif", "image/gif"}, // @@ -71,6 +72,7 @@ static const struct ContentTypeExtension { {"ogv", "video/ogg"}, // {"ogx", "application/ogg"}, // {"otf", "font/otf"}, // + {"patch", "text/plain"}, // {"pdf", "application/pdf"}, // {"png", "image/png"}, // {"rar", "application/vnd.rar"}, // diff --git a/net/turfwar/turfwar.c b/net/turfwar/turfwar.c index 07bc972f2..e66998443 100644 --- a/net/turfwar/turfwar.c +++ b/net/turfwar/turfwar.c @@ -299,8 +299,8 @@ union TokenBucket { struct Worker { pthread_t th; atomic_int msgcount; - atomic_bool shutdown; - atomic_bool connected; + atomic_int shutdown; + atomic_int connected; struct timespec startread; } * g_worker; diff --git a/test/libc/intrin/bextra_test.c b/test/libc/intrin/bextra_test.c index 4c962296a..284ae2fd6 100644 --- a/test/libc/intrin/bextra_test.c +++ b/test/libc/intrin/bextra_test.c @@ -22,7 +22,7 @@ #include "libc/testlib/testlib.h" void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio", 0)); + ASSERT_SYS(0, 0, pledge("stdio rpath", 0)); } unsigned P[] = { diff --git a/test/libc/intrin/bitreverse_test.c b/test/libc/intrin/bitreverse_test.c index 076a296b2..4e0af4889 100644 --- a/test/libc/intrin/bitreverse_test.c +++ b/test/libc/intrin/bitreverse_test.c @@ -22,7 +22,7 @@ #include "libc/testlib/testlib.h" void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio", 0)); + ASSERT_SYS(0, 0, pledge("stdio rpath", 0)); } TEST(_bitreverse, test) { diff --git a/test/libc/intrin/lock_test.c b/test/libc/intrin/lock_test.c index d2de39a3f..aa7e75ff1 100644 --- a/test/libc/intrin/lock_test.c +++ b/test/libc/intrin/lock_test.c @@ -111,9 +111,10 @@ int Worker(void *arg) { void TestContendedLock(const char *name, int kind) { char *stk; double ns; - int tid, x, i, n = 10000; + errno_t rc; struct timespec t1, t2; pthread_mutexattr_t attr; + int tid, x, i, n = 10000; struct CosmoTib tib = {.tib_self = &tib, .tib_self2 = &tib, .tib_tid = -1}; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, kind); @@ -122,12 +123,13 @@ void TestContendedLock(const char *name, int kind) { atomic_store(&ready, 0); atomic_store(&success, 0); stk = _mapstack(); - tid = clone(Worker, stk, GetStackSize() - 16 /* openbsd:stackbound */, - CLONE_VM | CLONE_THREAD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | - CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | CLONE_SETTLS, - 0, 0, &tib, &tib.tib_tid); - if (tid == -1) { - kprintf("clone failed: %s\n", strerror(errno)); + rc = clone(Worker, stk, GetStackSize() - 16 /* openbsd:stackbound */, + CLONE_VM | CLONE_THREAD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | + CLONE_CHILD_CLEARTID | CLONE_SETTLS, + 0, &tid, &tib, &tib.tib_tid); + if (rc) { + kprintf("clone failed: %s\n", strerror(rc)); _Exit(1); } while (!atomic_load(&ready)) donothing; diff --git a/test/libc/intrin/pthread_spin_lock_test.c b/test/libc/intrin/pthread_spin_lock_test.c new file mode 100644 index 000000000..96531d897 --- /dev/null +++ b/test/libc/intrin/pthread_spin_lock_test.c @@ -0,0 +1,72 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/atomic.h" +#include "libc/calls/struct/timespec.h" +#include "libc/intrin/atomic.h" +#include "libc/intrin/intrin.h" +#include "libc/intrin/kprintf.h" +#include "libc/testlib/testlib.h" +#include "libc/thread/thread.h" +#include "third_party/zip/zip.h" + +#define THREADS 8 +#define ITERATIONS 20000 + +atomic_int number; +pthread_t th[THREADS]; +pthread_spinlock_t lock; + +void *SpinWorker(void *arg) { + for (int i = 0; i < ITERATIONS; ++i) { + ASSERT_EQ(0, pthread_spin_lock(&lock)); + atomic_store_explicit( + &number, atomic_load_explicit(&number, memory_order_relaxed) + 1, + memory_order_relaxed); + ASSERT_EQ(0, pthread_spin_unlock(&lock)); + } + return 0; +} + +TEST(pthread_spin_lock, torture) { + int i; + number = 0; + ASSERT_EQ(0, pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE)); + for (i = 0; i < THREADS; ++i) { + ASSERT_EQ(0, pthread_create(th + i, 0, SpinWorker, 0)); + } + for (i = 0; i < THREADS; ++i) { + ASSERT_EQ(0, pthread_join(th[i], 0)); + } + ASSERT_EQ(0, pthread_spin_destroy(&lock)); + ASSERT_EQ(THREADS * ITERATIONS, number); +} + +TEST(pthread_spin_lock, macros) { + ASSERT_EQ(0, pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE)); + ASSERT_EQ(0, pthread_spin_lock(&lock)); + ASSERT_EQ(0, pthread_spin_unlock(&lock)); + ASSERT_EQ(0, pthread_spin_destroy(&lock)); +} + +TEST(pthread_spin_lock, linked) { + ASSERT_EQ(0, (pthread_spin_init)(&lock, PTHREAD_PROCESS_PRIVATE)); + ASSERT_EQ(0, (pthread_spin_lock)(&lock)); + ASSERT_EQ(0, (pthread_spin_unlock)(&lock)); + ASSERT_EQ(0, (pthread_spin_destroy)(&lock)); +} diff --git a/test/libc/stdio/posix_spawn_test.c b/test/libc/stdio/posix_spawn_test.c index d3401260d..48fda6273 100644 --- a/test/libc/stdio/posix_spawn_test.c +++ b/test/libc/stdio/posix_spawn_test.c @@ -100,9 +100,8 @@ TEST(posix_spawn, torture) { // XXX: NetBSD doesn't seem to let us set the scheduler to itself ;_; ASSERT_EQ(0, posix_spawnattr_init(&attr)); ASSERT_EQ(0, posix_spawnattr_setflags( - &attr, POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETSIGDEF | - POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETPGROUP | - POSIX_SPAWN_SETSIGMASK | + &attr, POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGDEF | + POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGMASK | (IsNetbsd() ? 0 : POSIX_SPAWN_SETSCHEDULER))); ASSERT_EQ(0, posix_spawnattr_setsigmask(&attr, &allsig)); ASSERT_EQ(0, posix_spawnattr_setsigdefault(&attr, &allsig)); diff --git a/test/libc/thread/pthread_cancel_test.c b/test/libc/thread/pthread_cancel_test.c index 3d9db4891..c21ec8393 100644 --- a/test/libc/thread/pthread_cancel_test.c +++ b/test/libc/thread/pthread_cancel_test.c @@ -32,7 +32,7 @@ int pfds[2]; pthread_cond_t cv; pthread_mutex_t mu; -atomic_bool gotcleanup; +atomic_int gotcleanup; char testlib_enable_tmp_setup_teardown; void SetUp(void) { @@ -198,7 +198,7 @@ TEST(pthread_cancel, condDeferredWaitDelayed) { char *wouldleak; pthread_key_t key; bool key_destructor_was_run; -atomic_bool is_in_infinite_loop; +atomic_int is_in_infinite_loop; void KeyDestructor(void *arg) { CheckStackIsAligned(); diff --git a/test/libc/thread/pthread_create_test.c b/test/libc/thread/pthread_create_test.c index 8f9f8718a..7e72f70ec 100644 --- a/test/libc/thread/pthread_create_test.c +++ b/test/libc/thread/pthread_create_test.c @@ -201,11 +201,11 @@ TEST(pthread_exit, fromMainThread_whenNoThreadsWereCreated) { EXITS(0); } -atomic_bool g_cleanup1; -atomic_bool g_cleanup2; +atomic_int g_cleanup1; +atomic_int g_cleanup2; void OnCleanup(void *arg) { - *(atomic_bool *)arg = true; + *(atomic_int *)arg = true; } void *CleanupExit(void *arg) { @@ -263,10 +263,11 @@ static void CreateDetach(void) { // this is really fast static void CreateDetached(void) { + pthread_t th; pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); - ASSERT_EQ(0, pthread_create(0, &attr, Increment, 0)); + ASSERT_EQ(0, pthread_create(&th, &attr, Increment, 0)); ASSERT_EQ(0, pthread_attr_destroy(&attr)); } diff --git a/test/libc/thread/pthread_detach_test.c b/test/libc/thread/pthread_detach_test.c index 9972f31cd..baba21df9 100644 --- a/test/libc/thread/pthread_detach_test.c +++ b/test/libc/thread/pthread_detach_test.c @@ -58,10 +58,11 @@ TEST(pthread_detach, testCreateReturn) { } TEST(pthread_detach, testDetachUponCreation) { + pthread_t th; pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); - ASSERT_EQ(0, pthread_create(0, &attr, Increment, 0)); + ASSERT_EQ(0, pthread_create(&th, &attr, Increment, 0)); ASSERT_EQ(0, pthread_attr_destroy(&attr)); while (!pthread_orphan_np()) { pthread_decimate_np(); diff --git a/test/libc/thread/pthread_exit_test.c b/test/libc/thread/pthread_exit_test.c index 457b99e8a..786a2c588 100644 --- a/test/libc/thread/pthread_exit_test.c +++ b/test/libc/thread/pthread_exit_test.c @@ -38,6 +38,7 @@ void *Worker(void *arg) { } TEST(pthread_exit, joinableOrphanedChild_runsAtexitHandlers) { + pthread_t th; pthread_attr_t attr; SPAWN(fork); atexit(OnExit); @@ -45,13 +46,14 @@ TEST(pthread_exit, joinableOrphanedChild_runsAtexitHandlers) { main_thread = pthread_self(); ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); - ASSERT_EQ(0, pthread_create(0, &attr, Worker, 0)); + ASSERT_EQ(0, pthread_create(&th, &attr, Worker, 0)); ASSERT_EQ(0, pthread_attr_destroy(&attr)); pthread_exit(0); EXITS(CHILD); } TEST(pthread_exit, detachedOrphanedChild_runsAtexitHandlers) { + pthread_t th; pthread_attr_t attr; SPAWN(fork); atexit(OnExit); @@ -59,7 +61,7 @@ TEST(pthread_exit, detachedOrphanedChild_runsAtexitHandlers) { main_thread = pthread_self(); ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); - ASSERT_EQ(0, pthread_create(0, &attr, Worker, 0)); + ASSERT_EQ(0, pthread_create(&th, &attr, Worker, 0)); ASSERT_EQ(0, pthread_attr_destroy(&attr)); pthread_exit(0); EXITS(CHILD); diff --git a/third_party/nsync/futex.c b/third_party/nsync/futex.c index f630a3a35..deb3a63e0 100644 --- a/third_party/nsync/futex.c +++ b/third_party/nsync/futex.c @@ -32,6 +32,7 @@ #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" +#include "libc/nexgen32e/vendor.internal.h" #include "libc/nt/runtime.h" #include "libc/nt/synchronization.h" #include "libc/sysv/consts/clock.h" @@ -60,10 +61,15 @@ static bool futex_is_supported; static bool futex_timeout_is_relative; __attribute__((__constructor__)) static void nsync_futex_init_ (void) { + int e; atomic_int x; FUTEX_WAIT_ = FUTEX_WAIT; + if (IsGenuineCosmo ()) { + return; + } + if (IsWindows ()) { futex_is_supported = true; return; @@ -89,6 +95,7 @@ __attribute__((__constructor__)) static void nsync_futex_init_ (void) { // configuring any time synchronization mechanism (like ntp) to // adjust for leap seconds by adjusting the rate, rather than // with a backwards step. + e = errno; atomic_store_explicit (&x, 0, memory_order_relaxed); if (IsLinux () && _futex (&x, FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, @@ -110,6 +117,7 @@ __attribute__((__constructor__)) static void nsync_futex_init_ (void) { FUTEX_WAIT_ = FUTEX_WAIT; futex_timeout_is_relative = true; } + errno = e; } static int nsync_futex_polyfill_ (atomic_int *w, int expect, struct timespec *abstime) { @@ -212,15 +220,21 @@ int nsync_futex_wait_ (atomic_int *w, int expect, char pshare, struct timespec * struct PosixThread *pt = 0; struct timespec tsmem, *timeout; - if (atomic_load_explicit (w, memory_order_acquire) != expect) { - return -EAGAIN; - } - op = FUTEX_WAIT_; if (pshare == PTHREAD_PROCESS_PRIVATE) { op |= FUTEX_PRIVATE_FLAG_; } + if (abstime && timespec_cmp (*abstime, timespec_zero) <= 0) { + rc = -ETIMEDOUT; + goto Finished; + } + + if (atomic_load_explicit (w, memory_order_acquire) != expect) { + rc = -EAGAIN; + goto Finished; + } + timeout = nsync_futex_timeout_ (&tsmem, abstime); LOCKTRACE ("futex(%t [%d], %s, %#x, %s) → ...", @@ -275,11 +289,12 @@ int nsync_futex_wait_ (atomic_int *w, int expect, char pshare, struct timespec * __get_tls()->tib_flags &= ~TIB_FLAG_TIME_CRITICAL; } +Finished: STRACE ("futex(%t [%d], %s, %#x, %s) → %s", w, atomic_load_explicit (w, memory_order_relaxed), DescribeFutexOp (op), expect, - DescribeTimespec (0, timeout), - DescribeErrnoResult (rc)); + DescribeTimespec (0, abstime), + DescribeErrno (rc)); return rc; } @@ -323,7 +338,7 @@ int nsync_futex_wake_ (atomic_int *w, int count, char pshare) { STRACE ("futex(%t [%d], %s, %d) → %s", w, atomic_load_explicit (w, memory_order_relaxed), - DescribeFutexOp(op), count, DescribeErrnoResult(rc)); + DescribeFutexOp (op), count, DescribeErrno (rc)); return rc; } diff --git a/third_party/nsync/panic.c b/third_party/nsync/panic.c index 6606ab06e..bb7354e42 100644 --- a/third_party/nsync/panic.c +++ b/third_party/nsync/panic.c @@ -17,14 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/str/str.h" #include "third_party/nsync/common.internal.h" // clang-format off /* Aborts after printing the nul-terminated string s[]. */ void nsync_panic_ (const char *s) { - size_t n = 0; - while (s[n]) ++n; - write (2, "panic: ", 7); - write (2, s, n); + char b[256], *p = b; + p = stpcpy (p, "panic: "); + p = stpcpy (p, s); + write (2, b, p - b); notpossible; } diff --git a/tool/emacs/cosmo-cpp-constants.el b/tool/emacs/cosmo-cpp-constants.el index 73abc1bd6..3e67cf206 100644 --- a/tool/emacs/cosmo-cpp-constants.el +++ b/tool/emacs/cosmo-cpp-constants.el @@ -63,81 +63,92 @@ "FLT_ROUNDS")) (defconst cosmo-cpp-constants-gcc-92 - '("__x86_64__" - "__amd64__" - "__WINT_MAX__" - "__BIGGEST_ALIGNMENT__" - "__SIZE_MAX__" - "__PTRDIFF_MAX__" - "__UINTMAX_MAX__" - "__SIG_ATOMIC_MAX__" - "__INT8_MAX__" - "__INT16_MAX__" - "__INT32_MAX__" - "__INT64_MAX__" - "__UINT8_MAX__" - "__UINT16_MAX__" - "__UINT32_MAX__" - "__UINT64_MAX__" - "__INT_LEAST8_MAX__" - "__INT_LEAST16_MAX__" - "__INT_LEAST32_MAX__" - "__INT_LEAST64_MAX__" - "__UINT_LEAST8_MAX__" - "__UINT_LEAST16_MAX__" - "__UINT_LEAST32_MAX__" - "__UINT_LEAST64_MAX__" - "__INT_FAST8_MAX__" - "__INT_FAST16_MAX__" - "__INT_FAST32_MAX__" - "__INT_FAST64_MAX__" - "__UINT_FAST8_MAX__" - "__UINT_FAST16_MAX__" - "__UINT_FAST32_MAX__" - "__UINT_FAST64_MAX__" - "__INTPTR_MAX__" - "__UINTPTR_MAX__" - "__WCHAR_MIN__" - "__WINT_MIN__" - "__SIG_ATOMIC_MIN__" - "__SCHAR_WIDTH__" - "__SHRT_WIDTH__" - "__INT_WIDTH__" - "__LONG_WIDTH__" - "__LONG_LONG_WIDTH__" - "__PTRDIFF_WIDTH__" - "__SIG_ATOMIC_WIDTH__" - "__SIZE_WIDTH__" - "__WCHAR_WIDTH__" - "__WINT_WIDTH__" - "__INT_LEAST8_WIDTH__" - "__INT_LEAST16_WIDTH__" - "__INT_LEAST32_WIDTH__" - "__INT_LEAST64_WIDTH__" - "__INT_FAST8_WIDTH__" - "__INT_FAST16_WIDTH__" - "__INT_FAST32_WIDTH__" - "__INT_FAST64_WIDTH__" - "__INTPTR_WIDTH__" - "__INTMAX_WIDTH__" - "__SIZEOF_INT__" - "__SIZEOF_INTMAX__" - "__SIZEOF_UINTMAX__" - "__SIZEOF_LONG__" - "__SIZEOF_LONG_LONG__" - "__SIZEOF_SHORT__" - "__SIZEOF_POINTER__" - "__SIZEOF_FLOAT__" - "__SIZEOF_DOUBLE__" - "__SIZEOF_LONG_DOUBLE__" - "__SIZEOF_SIZE_T__" - "__SIZEOF_WCHAR_T__" - "__SIZEOF_WINT_T__" - "__SIZEOF_PTRDIFF_T__" - "__TIMESTAMP__" - "_GNU_SOURCE" - "_BSD_SOURCE" - "_XOPEN_SOURCE")) + '("__x86_64__" + "__arm__" + "__aarch64__" + "__powerpc__" + "__powerpc64__" + "__mips__" + "__s390__" + "__s390x__" + "__mips64" + "__m68k__" + "__riscv" + "__MICROBLAZE__" + "__amd64__" + "__WINT_MAX__" + "__BIGGEST_ALIGNMENT__" + "__SIZE_MAX__" + "__PTRDIFF_MAX__" + "__UINTMAX_MAX__" + "__SIG_ATOMIC_MAX__" + "__INT8_MAX__" + "__INT16_MAX__" + "__INT32_MAX__" + "__INT64_MAX__" + "__UINT8_MAX__" + "__UINT16_MAX__" + "__UINT32_MAX__" + "__UINT64_MAX__" + "__INT_LEAST8_MAX__" + "__INT_LEAST16_MAX__" + "__INT_LEAST32_MAX__" + "__INT_LEAST64_MAX__" + "__UINT_LEAST8_MAX__" + "__UINT_LEAST16_MAX__" + "__UINT_LEAST32_MAX__" + "__UINT_LEAST64_MAX__" + "__INT_FAST8_MAX__" + "__INT_FAST16_MAX__" + "__INT_FAST32_MAX__" + "__INT_FAST64_MAX__" + "__UINT_FAST8_MAX__" + "__UINT_FAST16_MAX__" + "__UINT_FAST32_MAX__" + "__UINT_FAST64_MAX__" + "__INTPTR_MAX__" + "__UINTPTR_MAX__" + "__WCHAR_MIN__" + "__WINT_MIN__" + "__SIG_ATOMIC_MIN__" + "__SCHAR_WIDTH__" + "__SHRT_WIDTH__" + "__INT_WIDTH__" + "__LONG_WIDTH__" + "__LONG_LONG_WIDTH__" + "__PTRDIFF_WIDTH__" + "__SIG_ATOMIC_WIDTH__" + "__SIZE_WIDTH__" + "__WCHAR_WIDTH__" + "__WINT_WIDTH__" + "__INT_LEAST8_WIDTH__" + "__INT_LEAST16_WIDTH__" + "__INT_LEAST32_WIDTH__" + "__INT_LEAST64_WIDTH__" + "__INT_FAST8_WIDTH__" + "__INT_FAST16_WIDTH__" + "__INT_FAST32_WIDTH__" + "__INT_FAST64_WIDTH__" + "__INTPTR_WIDTH__" + "__INTMAX_WIDTH__" + "__SIZEOF_INT__" + "__SIZEOF_INTMAX__" + "__SIZEOF_UINTMAX__" + "__SIZEOF_LONG__" + "__SIZEOF_LONG_LONG__" + "__SIZEOF_SHORT__" + "__SIZEOF_POINTER__" + "__SIZEOF_FLOAT__" + "__SIZEOF_DOUBLE__" + "__SIZEOF_LONG_DOUBLE__" + "__SIZEOF_SIZE_T__" + "__SIZEOF_WCHAR_T__" + "__SIZEOF_WINT_T__" + "__SIZEOF_PTRDIFF_T__" + "__TIMESTAMP__" + "_GNU_SOURCE" + "_BSD_SOURCE" + "_XOPEN_SOURCE")) (defconst cosmo-cpp-constants-cosmopolitan '("__SAUCE__" @@ -155,10 +166,14 @@ "CHILD_MAX" "OPEN_MAX" "ATEXIT_MAX" + "LONG_BIT" "IM_FEELING_NAUGHTY" "__REAL_MODE__" "__x86__" "__i386__" + "__i486__" + "__i586__" + "__i686__" "__W__" "__PG__" "__MFENTRY__" diff --git a/tool/net/redbean.c b/tool/net/redbean.c index f0c5bf49c..906c53ede 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -456,7 +456,6 @@ static bool hasonprocessdestroy; static bool loggednetworkorigin; static bool ishandlingconnection; static bool hasonclientconnection; -static atomic_bool terminatemonitor; static bool evadedragnetsurveillance; static int zfd; @@ -473,6 +472,7 @@ static int oldloglevel; static int messageshandled; static int sslticketlifetime; static uint32_t clientaddrsize; +static atomic_int terminatemonitor; static size_t zsize; static lua_State *GL;