diff --git a/ape/ape-m1.c b/ape/ape-m1.c index 6db098e53..d77cefd51 100644 --- a/ape/ape-m1.c +++ b/ape/ape-m1.c @@ -76,7 +76,8 @@ struct Syslib { long (*write)(int, const void *, size_t); long (*read)(int, void *, size_t); long (*sigaction)(int, const struct sigaction *, struct sigaction *); - long (*pselect)(int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *); + long (*pselect)(int, fd_set *, fd_set *, fd_set *, const struct timespec *, + const sigset_t *); long (*mprotect)(void *, size_t, int); }; @@ -187,10 +188,6 @@ struct ApeLoader { char rando[16]; }; -static int ToLower(int c) { - return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c; -} - static unsigned long StrLen(const char *s) { unsigned long n = 0; while (*s++) ++n; @@ -349,38 +346,14 @@ __attribute__((__noreturn__)) static void Pexit(const char *c, int failed, _exit(127); } -static char EndsWithIgnoreCase(const char *p, unsigned long n, const char *s) { - unsigned long i, m; - if (n >= (m = StrLen(s))) { - for (i = n - m; i < n; ++i) { - if (ToLower(p[i]) != *s++) { - return 0; - } - } - return 1; - } else { - return 0; - } -} - -static char IsComPath(struct PathSearcher *ps) { - return EndsWithIgnoreCase(ps->name, ps->namelen, ".com") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".exe") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".com.dbg"); -} - -static char AccessCommand(struct PathSearcher *ps, const char *suffix, - unsigned long pathlen) { - unsigned long suffixlen; - suffixlen = StrLen(suffix); - if (pathlen + 1 + ps->namelen + suffixlen + 1 > sizeof(ps->path)) return 0; +static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) { + if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) return 0; if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/'; MemMove(ps->path + pathlen, ps->name, ps->namelen); - MemMove(ps->path + pathlen + ps->namelen, suffix, suffixlen + 1); return !access(ps->path, X_OK); } -static char SearchPath(struct PathSearcher *ps, const char *suffix) { +static char SearchPath(struct PathSearcher *ps) { const char *p; unsigned long i; for (p = ps->syspath;;) { @@ -389,7 +362,7 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { ps->path[i] = p[i]; } } - if (AccessCommand(ps, suffix, i)) { + if (AccessCommand(ps, i)) { return 1; } else if (p[i] == ':') { p += i + 1; @@ -399,13 +372,13 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { } } -static char FindCommand(struct PathSearcher *ps, const char *suffix) { +static char FindCommand(struct PathSearcher *ps) { ps->path[0] = 0; /* paths are always 100% taken literally when a slash exists $ ape foo/bar.com arg1 arg2 */ if (MemChr(ps->name, '/', ps->namelen)) { - return AccessCommand(ps, suffix, 0); + return AccessCommand(ps, 0); } /* we don't run files in the current directory @@ -416,12 +389,12 @@ static char FindCommand(struct PathSearcher *ps, const char *suffix) { however we will execute this $ ape - foo.com foo.com arg1 arg2 because cosmo's execve needs it */ - if (ps->literally && AccessCommand(ps, suffix, 0)) { + if (ps->literally && AccessCommand(ps, 0)) { return 1; } /* otherwise search for name on $PATH */ - return SearchPath(ps, suffix); + return SearchPath(ps); } static char *Commandv(struct PathSearcher *ps, const char *name, @@ -429,7 +402,7 @@ static char *Commandv(struct PathSearcher *ps, const char *name, ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin"; if (!(ps->namelen = StrLen((ps->name = name)))) return 0; if (ps->namelen + 1 > sizeof(ps->path)) return 0; - if (FindCommand(ps, "") || (!IsComPath(ps) && FindCommand(ps, ".com"))) { + if (FindCommand(ps)) { return ps->path; } else { return 0; @@ -843,12 +816,14 @@ static long sys_mmap(void *addr, size_t size, int prot, int flags, int fd, return sysret((long)mmap(addr, size, prot, flags, fd, off)); } -static long sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { +static long sys_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) { return sysret(sigaction(sig, act, oact)); } -static long sys_pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, - const struct timespec *timeout, const sigset_t *sigmask) { +static long sys_pselect(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *errorfds, const struct timespec *timeout, + const sigset_t *sigmask) { return sysret(pselect(nfds, readfds, writefds, errorfds, timeout, sigmask)); } diff --git a/ape/loader.c b/ape/loader.c index d848e1b31..74b2cf6f4 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -227,10 +227,6 @@ EXTERN_C void Launch(void *, long, void *, int) __attribute__((__noreturn__)); extern char __executable_start[]; extern char _end[]; -static int ToLower(int c) { - return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c; -} - static unsigned long StrLen(const char *s) { unsigned long n = 0; while (*s++) ++n; @@ -538,38 +534,14 @@ __attribute__((__noreturn__)) static void Pexit(int os, const char *c, int rc, Exit(127, os); } -static char EndsWithIgnoreCase(const char *p, unsigned long n, const char *s) { - unsigned long i, m; - if (n >= (m = StrLen(s))) { - for (i = n - m; i < n; ++i) { - if (ToLower(p[i]) != *s++) { - return 0; - } - } - return 1; - } else { - return 0; - } -} - -static char IsComPath(struct PathSearcher *ps) { - return EndsWithIgnoreCase(ps->name, ps->namelen, ".com") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".exe") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".com.dbg"); -} - -static char AccessCommand(struct PathSearcher *ps, const char *suffix, - unsigned long pathlen) { - unsigned long suffixlen; - suffixlen = StrLen(suffix); - if (pathlen + 1 + ps->namelen + suffixlen + 1 > sizeof(ps->path)) return 0; +static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) { + if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) return 0; if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/'; MemMove(ps->path + pathlen, ps->name, ps->namelen); - MemMove(ps->path + pathlen + ps->namelen, suffix, suffixlen + 1); return !Access(ps->path, X_OK, ps->os); } -static char SearchPath(struct PathSearcher *ps, const char *suffix) { +static char SearchPath(struct PathSearcher *ps) { const char *p; unsigned long i; for (p = ps->syspath;;) { @@ -578,7 +550,7 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { ps->path[i] = p[i]; } } - if (AccessCommand(ps, suffix, i)) { + if (AccessCommand(ps, i)) { return 1; } else if (p[i] == ':') { p += i + 1; @@ -588,13 +560,13 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { } } -static char FindCommand(struct PathSearcher *ps, const char *suffix) { +static char FindCommand(struct PathSearcher *ps) { ps->path[0] = 0; /* paths are always 100% taken literally when a slash exists $ ape foo/bar.com arg1 arg2 */ if (MemChr(ps->name, '/', ps->namelen)) { - return AccessCommand(ps, suffix, 0); + return AccessCommand(ps, 0); } /* we don't run files in the current directory @@ -605,12 +577,12 @@ static char FindCommand(struct PathSearcher *ps, const char *suffix) { however we will execute this $ ape - foo.com foo.com arg1 arg2 because cosmo's execve needs it */ - if (ps->literally && AccessCommand(ps, suffix, 0)) { + if (ps->literally && AccessCommand(ps, 0)) { return 1; } /* otherwise search for name on $PATH */ - return SearchPath(ps, suffix); + return SearchPath(ps); } static char *Commandv(struct PathSearcher *ps, int os, const char *name, @@ -619,7 +591,7 @@ static char *Commandv(struct PathSearcher *ps, int os, const char *name, ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin"; if (!(ps->namelen = StrLen((ps->name = name)))) return 0; if (ps->namelen + 1 > sizeof(ps->path)) return 0; - if (FindCommand(ps, "") || (!IsComPath(ps) && FindCommand(ps, ".com"))) { + if (FindCommand(ps)) { return ps->path; } else { return 0; diff --git a/dsp/mpeg/mpeg1.c b/dsp/mpeg/mpeg1.c index ff874c42c..6804255f7 100644 --- a/dsp/mpeg/mpeg1.c +++ b/dsp/mpeg/mpeg1.c @@ -32,6 +32,7 @@ #include "dsp/mpeg/idct.h" #include "dsp/mpeg/mpeg.h" #include "dsp/mpeg/video.h" +#include "libc/calls/struct/timespec.h" #include "libc/fmt/conv.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index 23b558af2..9e15f4abb 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -107,6 +107,8 @@ o//libc/calls/statfs2cosmo.o: private \ # we always want -O2 because: # division is expensive if not optimized o/$(MODE)/libc/calls/clock.o \ +o/$(MODE)/libc/calls/gettimeofday.o \ +o/$(MODE)/libc/calls/clock_gettime-mono.o \ o/$(MODE)/libc/calls/timespec_tomillis.o \ o/$(MODE)/libc/calls/timespec_tomicros.o \ o/$(MODE)/libc/calls/timespec_totimeval.o \ diff --git a/libc/calls/clock.c b/libc/calls/clock.c index 884f74c86..2338a3a10 100644 --- a/libc/calls/clock.c +++ b/libc/calls/clock.c @@ -52,7 +52,7 @@ int64_t clock(void) { struct rusage ru; struct timespec ts; e = errno; - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) { + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts)) { errno = e; if (getrusage(RUSAGE_SELF, &ru) != -1) { ts = timeval_totimespec(timeval_add(ru.ru_utime, ru.ru_stime)); diff --git a/libc/calls/clock_getres.c b/libc/calls/clock_getres.c index 18fcdfd53..a54bfdb05 100644 --- a/libc/calls/clock_getres.c +++ b/libc/calls/clock_getres.c @@ -54,7 +54,6 @@ static int sys_clock_getres_xnu(int clock, struct timespec *ts) { * @error EPERM if pledge() is in play without stdio promise * @error EINVAL if `clock` isn't supported on this system * @error EFAULT if `ts` points to bad memory - * @threadsafe */ int clock_getres(int clock, struct timespec *ts) { int rc; diff --git a/libc/calls/clock_gettime-mono.c b/libc/calls/clock_gettime-mono.c index b90116387..46474b7dd 100644 --- a/libc/calls/clock_gettime-mono.c +++ b/libc/calls/clock_gettime-mono.c @@ -16,15 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/atomic.h" #include "libc/calls/struct/timespec.h" #include "libc/cosmo.h" +#include "libc/errno.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/nexgen32e/x86feature.h" -#include "libc/sysv/consts/clock.h" -#include "libc/sysv/errfuns.h" + +/** + * @fileoverview Fast Monotonic Clock Polyfill for XNU/NT. + */ static struct { - _Atomic(uint32_t) once; + atomic_uint once; struct timespec base_wall; uint64_t base_tick; } g_mono; @@ -37,13 +41,18 @@ static void sys_clock_gettime_mono_init(void) { int sys_clock_gettime_mono(struct timespec *time) { uint64_t nanos; uint64_t cycles; - if (X86_HAVE(INVTSC)) { - cosmo_once(&g_mono.once, sys_clock_gettime_mono_init); - cycles = rdtsc() - g_mono.base_tick; - nanos = cycles / 3; - *time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos)); - return 0; - } else { - return einval(); - } +#ifdef __x86_64__ + // intel architecture guarantees that a mapping exists between rdtsc & + // nanoseconds only if the cpu advertises invariant timestamps support + if (!X86_HAVE(INVTSC)) return -EINVAL; +#endif + cosmo_once(&g_mono.once, sys_clock_gettime_mono_init); + cycles = rdtsc() - g_mono.base_tick; + // this is a crude approximation, that's worked reasonably well so far + // only the kernel knows the actual mapping between rdtsc and nanosecs + // which we could attempt to measure ourselves using clock_gettime but + // we'd need to impose 100 ms of startup latency for a guess this good + nanos = cycles / 3; + *time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos)); + return 0; } diff --git a/libc/calls/clock_gettime-nt.c b/libc/calls/clock_gettime-nt.c index 3b6891286..ba334e732 100644 --- a/libc/calls/clock_gettime-nt.c +++ b/libc/calls/clock_gettime-nt.c @@ -16,12 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" -#include "libc/fmt/conv.h" +#include "libc/calls/struct/timespec.internal.h" +#include "libc/errno.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/struct/filetime.h" #include "libc/nt/synchronization.h" #include "libc/sysv/consts/clock.h" -#include "libc/sysv/errfuns.h" textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { struct NtFileTime ft; @@ -32,6 +32,6 @@ textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { } else if (clock == CLOCK_MONOTONIC) { return sys_clock_gettime_mono(ts); } else { - return einval(); + return -EINVAL; } } diff --git a/libc/calls/clock_gettime-m1.c b/libc/calls/clock_gettime-sysv.c similarity index 85% rename from libc/calls/clock_gettime-m1.c rename to libc/calls/clock_gettime-sysv.c index 11b0e6568..ae5779a25 100644 --- a/libc/calls/clock_gettime-m1.c +++ b/libc/calls/clock_gettime-sysv.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -16,11 +16,10 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/runtime/syslib.internal.h" +#include "libc/calls/syscall_support-sysv.internal.h" +#include "libc/sysv/consts/nr.h" -int sys_clock_gettime_m1(int clock, struct timespec *ts) { - return _sysret(__syslib->__clock_gettime(clock, ts)); +int sys_clock_gettime(int clock, struct timespec *ts) { + return __syscall2i(clock, (long)ts, __NR_clock_gettime); } diff --git a/libc/calls/clock_gettime-xnu.c b/libc/calls/clock_gettime-xnu.c index 774fd9382..94726e1a8 100644 --- a/libc/calls/clock_gettime-xnu.c +++ b/libc/calls/clock_gettime-xnu.c @@ -16,28 +16,46 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" +#include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.internal.h" +#include "libc/errno.h" #include "libc/sysv/consts/clock.h" -#include "libc/sysv/errfuns.h" +#ifdef __x86_64__ int sys_clock_gettime_xnu(int clock, struct timespec *ts) { - axdx_t ad; + long ax, dx; if (clock == CLOCK_REALTIME) { - ad = sys_gettimeofday((struct timeval *)ts, 0, 0); - if (ad.ax != -1) { - if (ad.ax) { - ts->tv_sec = ad.ax; - ts->tv_nsec = ad.dx; - } - ts->tv_nsec *= 1000; - return 0; - } else { - return -1; + // invoke the system call + // + // int gettimeofday(struct timeval *tp, + // struct timezone *tzp, + // uint64_t *mach_absolute_time); + // + // as follows + // + // ax, dx = gettimeofday(&ts, 0, 0); + // + // to support multiple calling conventions + // + // 1. new xnu returns *ts in memory via rdi + // 2. old xnu returns *ts in rax:rdx regs + // + // we assume this system call always succeeds + asm volatile("syscall" + : "=a"(ax), "=d"(dx) + : "0"(0x2000000 | 116), "D"(ts), "S"(0), "1"(0) + : "rcx", "r8", "r9", "r10", "r11", "memory"); + if (ax) { + ts->tv_sec = ax; + ts->tv_nsec = dx; } + ts->tv_nsec *= 1000; + return 0; } else if (clock == CLOCK_MONOTONIC) { return sys_clock_gettime_mono(ts); } else { - return einval(); + return -EINVAL; } } + +#endif /* __x86_64__ */ diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index 5716e7ec8..d28ed5e59 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -16,82 +16,14 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/asan.internal.h" -#include "libc/calls/clock_gettime.internal.h" -#include "libc/calls/state.internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/calls/struct/timeval.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/asan.internal.h" -#include "libc/intrin/asmflag.h" -#include "libc/intrin/bits.h" +#include "libc/errno.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" -#include "libc/mem/alloca.h" -#include "libc/nt/synchronization.h" -#include "libc/sysv/errfuns.h" -#include "libc/thread/tls.h" - -/** - * Returns nanosecond time. - * - * This is a high-precision timer that supports multiple definitions of - * time. Among the more popular is CLOCK_MONOTONIC. This function has a - * zero syscall implementation of that on modern x86. - * - * rdtsc l: 13𝑐 4𝑛𝑠 - * gettimeofday l: 44𝑐 14𝑛𝑠 - * clock_gettime l: 40𝑐 13𝑛𝑠 - * __clock_gettime l: 35𝑐 11𝑛𝑠 - * sys_clock_gettime l: 220𝑐 71𝑛𝑠 - * - * @param clock can be one of: - * - `CLOCK_REALTIME`: universally supported - * - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd - * - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd - * - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+ - * - `CLOCK_MONOTONIC`: universally supported - * - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd - * - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd - * - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+ - * - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+ - * - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd - * - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd - * - `CLOCK_MONOTONIC_COARSE`: linux, freebsd - * - `CLOCK_PROF`: linux and netbsd - * - `CLOCK_BOOTTIME`: linux and openbsd - * - `CLOCK_REALTIME_ALARM`: linux-only - * - `CLOCK_BOOTTIME_ALARM`: linux-only - * - `CLOCK_TAI`: linux-only - * @param ts is where the result is stored - * @return 0 on success, or -1 w/ errno - * @error EPERM if pledge() is in play without stdio promise - * @error EINVAL if `clock` isn't supported on this system - * @error EFAULT if `ts` points to bad memory - * @see strftime(), gettimeofday() - * @asyncsignalsafe - * @threadsafe - * @vforksafe - */ -int clock_gettime(int clock, struct timespec *ts) { - // threads on win32 stacks call this so we can't asan check *ts - int rc; - if (clock == 127) { - rc = einval(); // 127 is used by consts.sh to mean unsupported - } else { - rc = __clock_gettime(clock, ts); - } -#if SYSDEBUG - if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) { - POLLTRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock), - DescribeTimespec(rc, ts), rc); - } -#endif - return rc; -} +#include "libc/runtime/syslib.internal.h" #ifdef __aarch64__ #define CGT_VDSO __vdsosym("LINUX_2.6.39", "__kernel_clock_gettime") @@ -99,39 +31,72 @@ int clock_gettime(int clock, struct timespec *ts) { #define CGT_VDSO __vdsosym("LINUX_2.6", "__vdso_clock_gettime") #endif -/** - * Returns pointer to fastest clock_gettime(). - */ -clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) { - bool isfast; - clock_gettime_f *res; - if (IsLinux() && (res = CGT_VDSO)) { - isfast = true; - } else if (IsXnu()) { -#ifdef __x86_64__ - res = sys_clock_gettime_xnu; - isfast = false; -#elif defined(__aarch64__) - res = sys_clock_gettime_m1; - isfast = true; -#else -#error "unsupported architecture" -#endif +typedef int clock_gettime_f(int, struct timespec *); + +static clock_gettime_f *__clock_gettime_get(void) { + clock_gettime_f *cgt; + if (IsLinux() && (cgt = CGT_VDSO)) { + return cgt; + } else if (__syslib) { + return (void *)__syslib->__clock_gettime; } else if (IsWindows()) { - isfast = true; - res = sys_clock_gettime_nt; + return sys_clock_gettime_nt; +#ifdef __x86_64__ + } else if (IsXnu()) { + return sys_clock_gettime_xnu; +#endif } else { - isfast = false; - res = sys_clock_gettime; + return sys_clock_gettime; } - if (opt_out_isfast) { - *opt_out_isfast = isfast; - } - return res; } -int __clock_gettime_init(int clockid, struct timespec *ts) { - clock_gettime_f *gettime; - __clock_gettime = gettime = __clock_gettime_get(0); - return gettime(clockid, ts); +static int __clock_gettime_init(int, struct timespec *); +static clock_gettime_f *__clock_gettime = __clock_gettime_init; +static int __clock_gettime_init(int clockid, struct timespec *ts) { + clock_gettime_f *cgt; + __clock_gettime = cgt = __clock_gettime_get(); + return cgt(clockid, ts); +} + +/** + * Returns nanosecond time. + * + * @param clock can be one of: + * - `CLOCK_REALTIME`: universally supported + * - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd + * - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd + * - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+ + * - `CLOCK_MONOTONIC`: universally supported (except on XNU/NT w/o INVTSC) + * - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd + * - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd + * - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+ + * - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+ + * - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd PID) + * - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd TID) + * - `CLOCK_MONOTONIC_COARSE`: linux, freebsd + * - `CLOCK_PROF`: linux and netbsd + * - `CLOCK_BOOTTIME`: linux and openbsd + * - `CLOCK_REALTIME_ALARM`: linux-only + * - `CLOCK_BOOTTIME_ALARM`: linux-only + * - `CLOCK_TAI`: linux-only + * @param ts is where the result is stored (or null to do clock check) + * @return 0 on success, or -1 w/ errno + * @raise EFAULT if `ts` points to invalid memory + * @error EINVAL if `clock` isn't supported on this system + * @error EPERM if pledge() is in play without stdio promise + * @error ESRCH on NetBSD if PID/TID OR'd into `clock` wasn't found + * @see strftime(), gettimeofday() + * @asyncsignalsafe + * @vforksafe + */ +int clock_gettime(int clock, struct timespec *ts) { + // threads on win32 stacks call this so we can't asan check *ts + int rc = __clock_gettime(clock, ts); + if (rc) { + errno = -rc; + rc = -1; + } + TIMETRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock), + DescribeTimespec(rc, ts), rc); + return rc; } diff --git a/libc/calls/clock_gettime.internal.h b/libc/calls/clock_gettime.internal.h deleted file mode 100644 index a260257fc..000000000 --- a/libc/calls/clock_gettime.internal.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_CLOCK_GETTIME_H_ -#define COSMOPOLITAN_LIBC_CALLS_CLOCK_GETTIME_H_ -#include "libc/calls/struct/timespec.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -typedef int clock_gettime_f(int, struct timespec *); - -extern clock_gettime_f *__clock_gettime; -clock_gettime_f *__clock_gettime_get(bool *); -int __clock_gettime_init(int, struct timespec *); -int sys_clock_gettime_mono(struct timespec *); - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_CLOCK_GETTIME_H_ */ diff --git a/libc/calls/clock_nanosleep-xnu.c b/libc/calls/clock_nanosleep-xnu.c index d72adf207..f0502ac00 100644 --- a/libc/calls/clock_nanosleep-xnu.c +++ b/libc/calls/clock_nanosleep-xnu.c @@ -19,40 +19,40 @@ #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/runtime/syslib.internal.h" #include "libc/sock/internal.h" #include "libc/sysv/consts/clock.h" #include "libc/sysv/consts/timer.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" -#include "libc/thread/tls.h" int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req, struct timespec *rem) { #ifdef __x86_64__ - struct timeval abs, now, rel; - if (clock == CLOCK_REALTIME) { - if (flags & TIMER_ABSTIME) { - abs = timespec_totimeval(*req); - sys_gettimeofday_xnu(&now, 0, 0); - if (timeval_cmp(abs, now) > 0) { - rel = timeval_sub(abs, now); - return sys_select(0, 0, 0, 0, &rel); - } else { - return 0; - } + if (flags & TIMER_ABSTIME) { + struct timespec now; + sys_clock_gettime_xnu(clock, &now); + if (timespec_cmp(*req, now) > 0) { + struct timeval rel = timespec_totimeval(timespec_sub(*req, now)); + return sys_select(0, 0, 0, 0, &rel); } else { - return sys_nanosleep_xnu(req, rem); + return 0; } } else { - return enotsup(); + int rc; + struct timespec beg; + if (rem) sys_clock_gettime_xnu(CLOCK_REALTIME, &beg); + struct timeval rel = timespec_totimeval(*req); // rounds up + rc = sys_select(0, 0, 0, 0, &rel); + if (rc == -1 && rem && errno == EINTR) { + struct timespec end; + sys_clock_gettime_xnu(CLOCK_REALTIME, &end); + *rem = timespec_subz(*req, timespec_sub(end, beg)); + } + return rc; } #else long res; diff --git a/libc/calls/clock_nanosleep.c b/libc/calls/clock_nanosleep.c index d18bf7695..cf4900e8c 100644 --- a/libc/calls/clock_nanosleep.c +++ b/libc/calls/clock_nanosleep.c @@ -21,7 +21,6 @@ #include "libc/calls/blockcancel.internal.h" #include "libc/calls/blocksigs.internal.h" #include "libc/calls/calls.h" -#include "libc/calls/clock_gettime.internal.h" #include "libc/calls/cp.internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/timespec.h" @@ -76,16 +75,15 @@ static errno_t sys_clock_nanosleep(int clock, int flags, static struct timespec GetNanosleepLatency(void) { errno_t rc; int64_t nanos; - clock_gettime_f *cgt; struct timespec x, y, w = {0, 1}; if (!(nanos = g_nanosleep_latency)) { BLOCK_SIGNALS; - for (cgt = __clock_gettime_get(0);;) { - npassert(!cgt(CLOCK_REALTIME_PRECISE, &x)); + for (;;) { + unassert(!clock_gettime(CLOCK_REALTIME_PRECISE, &x)); rc = sys_clock_nanosleep(CLOCK_REALTIME, 0, &w, 0); - npassert(!rc || rc == EINTR); + unassert(!rc || rc == EINTR); if (!rc) { - npassert(!cgt(CLOCK_REALTIME_PRECISE, &y)); + unassert(!clock_gettime(CLOCK_REALTIME_PRECISE, &y)); nanos = timespec_tonanos(timespec_sub(y, x)); g_nanosleep_latency = nanos; break; @@ -107,7 +105,6 @@ static errno_t CheckCancel(void) { static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req, struct timespec *rem) { errno_t rc; - clock_gettime_f *cgt; struct timespec now, start, elapsed; if ((rc = CheckCancel())) { if (rc == EINTR && !flags && rem) { @@ -115,11 +112,10 @@ static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req, } return rc; } - cgt = __clock_gettime_get(0); - npassert(!cgt(CLOCK_REALTIME, &start)); + unassert(!clock_gettime(CLOCK_REALTIME, &start)); for (;;) { pthread_yield(); - npassert(!cgt(CLOCK_REALTIME, &now)); + unassert(!clock_gettime(CLOCK_REALTIME, &now)); if (flags & TIMER_ABSTIME) { if (timespec_cmp(now, *req) >= 0) { return 0; @@ -177,7 +173,7 @@ static bool ShouldUseSpinNanosleep(int clock, int flags, return false; } e = errno; - if (__clock_gettime_get(0)(clock, &now)) { + if (clock_gettime(clock, &now)) { // punt to the nanosleep system call errno = e; return false; @@ -258,12 +254,8 @@ errno_t clock_nanosleep(int clock, int flags, const struct timespec *req, } else { rc = sys_clock_nanosleep(clock, flags, req, rem); } -#if SYSDEBUG - 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), DescribeErrno(rc)); - } -#endif + TIMETRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock), + DescribeSleepFlags(flags), DescribeTimespec(0, req), + DescribeTimespec(rc, rem), DescribeErrno(rc)); return rc; } diff --git a/libc/calls/creat.c b/libc/calls/creat.c index 1c1dfe73e..821ae059f 100644 --- a/libc/calls/creat.c +++ b/libc/calls/creat.c @@ -34,7 +34,6 @@ * @cancellationpoint * @asyncsignalsafe * @restartable - * @threadsafe * @vforksafe */ int creat(const char *file, uint32_t mode) { diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c index 7edac781d..bf563c988 100644 --- a/libc/calls/fstat-nt.c +++ b/libc/calls/fstat-nt.c @@ -21,7 +21,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/stat.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bsr.h" #include "libc/intrin/strace.internal.h" diff --git a/libc/calls/fstatvfs.c b/libc/calls/fstatvfs.c index 91503ab2a..7e1b98091 100644 --- a/libc/calls/fstatvfs.c +++ b/libc/calls/fstatvfs.c @@ -35,3 +35,5 @@ int fstatvfs(int fd, struct statvfs *sv) { return -1; } } + +__weak_reference(fstatvfs, fstatvfs64); diff --git a/libc/calls/ftruncate.c b/libc/calls/ftruncate.c index 4f7ef83c7..2e8725073 100644 --- a/libc/calls/ftruncate.c +++ b/libc/calls/ftruncate.c @@ -60,7 +60,6 @@ * @raise ENOSYS on bare metal * @cancellationpoint * @asyncsignalsafe - * @threadsafe */ int ftruncate(int fd, int64_t length) { int rc; diff --git a/libc/calls/futimens.c b/libc/calls/futimens.c index 15d7c22df..081bfe96b 100644 --- a/libc/calls/futimens.c +++ b/libc/calls/futimens.c @@ -40,7 +40,6 @@ * @raise EFAULT if `ts` memory was invalid * @raise ENOSYS on RHEL5 or bare metal * @asyncsignalsafe - * @threadsafe */ int futimens(int fd, const struct timespec ts[2]) { int rc; diff --git a/libc/calls/futimes.c b/libc/calls/futimes.c index c8777f3a6..e5bdd0423 100644 --- a/libc/calls/futimes.c +++ b/libc/calls/futimes.c @@ -37,7 +37,6 @@ * @raise ENOSYS on RHEL5 or bare metal * @see futimens() for modern version * @asyncsignalsafe - * @threadsafe */ int futimes(int fd, const struct timeval tv[2]) { int rc; diff --git a/libc/calls/getcontext.S b/libc/calls/getcontext.S index f1f8cc135..cbd7ff9f6 100644 --- a/libc/calls/getcontext.S +++ b/libc/calls/getcontext.S @@ -30,7 +30,6 @@ // @see makecontext() // @see swapcontext() // @see setcontext() -// @threadsafe .ftrace1 getcontext: .ftrace2 diff --git a/libc/calls/getppid.c b/libc/calls/getppid.c index 52df29760..069c69ad1 100644 --- a/libc/calls/getppid.c +++ b/libc/calls/getppid.c @@ -28,7 +28,6 @@ * @return parent process id (always successful) * @note slow on Windows; needs to iterate process tree * @asyncsignalsafe - * @threadsafe * @vforksafe */ int getppid(void) { diff --git a/libc/calls/getrusage-nt.c b/libc/calls/getrusage-nt.c index 563a79b96..a1afb1ae3 100644 --- a/libc/calls/getrusage-nt.c +++ b/libc/calls/getrusage-nt.c @@ -19,7 +19,7 @@ #include "libc/calls/sig.internal.h" #include "libc/calls/struct/rusage.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/accounting.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" diff --git a/libc/calls/gettimeofday-m1.c b/libc/calls/gettimeofday-m1.c deleted file mode 100644 index 68f1d9122..000000000 --- a/libc/calls/gettimeofday-m1.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timespec.h" -#include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/runtime/syslib.internal.h" -#include "libc/sysv/consts/clock.h" - -axdx_t sys_gettimeofday_m1(struct timeval *tv, struct timezone *tz, void *wut) { - axdx_t ad; - struct timespec ts; - ad.ax = _sysret(__syslib->__clock_gettime(CLOCK_REALTIME, &ts)); - ad.dx = 0; - if (!ad.ax && tv) { - *tv = timespec_totimeval(ts); - } - return ad; -} diff --git a/libc/calls/gettimeofday-metal.c b/libc/calls/gettimeofday-metal.c deleted file mode 100644 index f733f0e70..000000000 --- a/libc/calls/gettimeofday-metal.c +++ /dev/null @@ -1,25 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timeval.internal.h" -#include "libc/time/struct/timezone.h" - -axdx_t sys_gettimeofday_metal(struct timeval *tv, struct timezone *tz, - void *wut) { - return (axdx_t){-1, 0}; -} diff --git a/libc/calls/gettimeofday-nt.c b/libc/calls/gettimeofday-nt.c deleted file mode 100644 index 6432e2ba7..000000000 --- a/libc/calls/gettimeofday-nt.c +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" -#include "libc/nt/struct/filetime.h" -#include "libc/nt/synchronization.h" -#include "libc/str/str.h" - -textwindows axdx_t sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz, - void *wut) { - struct NtFileTime ft; - GetSystemTimeAsFileTime(&ft); - if (tv) *tv = FileTimeToTimeVal(ft); - if (tz) bzero(tz, sizeof(*tz)); - return (axdx_t){0, 0}; -} diff --git a/libc/calls/gettimeofday-xnu.c b/libc/calls/gettimeofday-xnu.c deleted file mode 100644 index 4a6c138bd..000000000 --- a/libc/calls/gettimeofday-xnu.c +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timeval.internal.h" - -axdx_t sys_gettimeofday_xnu(struct timeval *tv, struct timezone *tz, - void *wut) { - axdx_t ad; - ad = sys_gettimeofday(tv, tz, wut); - if (ad.ax > 0 && tv) { - tv->tv_sec = ad.ax; - tv->tv_usec = ad.dx; - ad.ax = 0; - } - return ad; -} diff --git a/libc/calls/gettimeofday.c b/libc/calls/gettimeofday.c index 12f932d1e..cb1f4763f 100644 --- a/libc/calls/gettimeofday.c +++ b/libc/calls/gettimeofday.c @@ -16,24 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/state.internal.h" -#include "libc/calls/struct/itimerval.internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" -#include "libc/calls/syscall_support-sysv.internal.h" -#include "libc/dce.h" -#include "libc/intrin/asan.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" -#include "libc/sysv/errfuns.h" -#include "libc/thread/tls.h" +#include "libc/sysv/consts/clock.h" #include "libc/time/struct/timezone.h" -typedef axdx_t gettimeofday_f(struct timeval *, struct timezone *, void *); -static gettimeofday_f __gettimeofday_init; -static gettimeofday_f *__gettimeofday = __gettimeofday_init; - /** * Returns system wall time in microseconds, e.g. * @@ -47,60 +34,26 @@ static gettimeofday_f *__gettimeofday = __gettimeofday_init; * iso8601(p, &tm); * printf("%s\n", p); * - * @param tv points to timeval that receives result if non-NULL - * @param tz receives UTC timezone if non-NULL + * @param tv points to timeval that receives result if non-null + * @param tz is completely ignored + * @return 0 on success, or -1 w/ errno + * @raise EFAULT if `tv` points to invalid memory * @see clock_gettime() for nanosecond precision * @see strftime() for string formatting + * @asyncsignalsafe + * @vforksafe */ int gettimeofday(struct timeval *tv, struct timezone *tz) { - int rc = __gettimeofday(tv, tz, 0).ax; -#if SYSDEBUG - if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) { - POLLTRACE("gettimeofday([%s], %p) → %d% m", DescribeTimeval(rc, tv), tz, - rc); - } -#endif - return rc; -} - -/** - * Returns pointer to fastest gettimeofday(). - */ -gettimeofday_f *__gettimeofday_get(bool *opt_out_isfast) { - bool isfast; - gettimeofday_f *res; - if (IsLinux() && (res = __vdsosym("LINUX_2.6", "__vdso_gettimeofday"))) { - isfast = true; - } else if (IsWindows()) { - isfast = true; - res = sys_gettimeofday_nt; - } else if (IsXnu()) { -#ifdef __x86_64__ - res = sys_gettimeofday_xnu; - isfast = false; -#elif defined(__aarch64__) - res = sys_gettimeofday_m1; - isfast = true; -#else -#error "unsupported architecture" -#endif - } else if (IsMetal()) { - isfast = false; - res = sys_gettimeofday_metal; + if (tv) { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) != -1) { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = (ts.tv_nsec + 999) / 1000; + return 0; + } else { + return -1; + } } else { - isfast = false; - res = sys_gettimeofday; + return 0; } - if (opt_out_isfast) { - *opt_out_isfast = isfast; - } - return res; -} - -static axdx_t __gettimeofday_init(struct timeval *tv, // - struct timezone *tz, // - void *arg) { - gettimeofday_f *gettime; - __gettimeofday = gettime = __gettimeofday_get(0); - return gettime(tv, tz, 0); } diff --git a/libc/calls/getuid.c b/libc/calls/getuid.c index e63eebd25..fa91a180d 100644 --- a/libc/calls/getuid.c +++ b/libc/calls/getuid.c @@ -37,7 +37,6 @@ * * @return user id (always successful) * @asyncsignalsafe - * @threadsafe * @vforksafe */ uint32_t getuid(void) { @@ -62,7 +61,6 @@ uint32_t getuid(void) { * * @return group id (always successful) * @asyncsignalsafe - * @threadsafe * @vforksafe */ uint32_t getgid(void) { diff --git a/libc/calls/lseek.c b/libc/calls/lseek.c index fff3b7efe..d84b0d948 100644 --- a/libc/calls/lseek.c +++ b/libc/calls/lseek.c @@ -72,7 +72,6 @@ * @raise EINVAL if resulting offset would be negative * @raise EINVAL if `whence` isn't valid * @asyncsignalsafe - * @threadsafe * @vforksafe */ int64_t lseek(int fd, int64_t offset, int whence) { diff --git a/libc/calls/makedirs.c b/libc/calls/makedirs.c index 989e2a42e..e2bf68d6b 100644 --- a/libc/calls/makedirs.c +++ b/libc/calls/makedirs.c @@ -44,7 +44,6 @@ * @raise ENOENT if `path` is an empty string * @raise ELOOP if loop was detected resolving components of `path` * @asyncsignalsafe - * @threadsafe */ int makedirs(const char *path, unsigned mode) { int c, e, i, n; diff --git a/libc/calls/mkdir.c b/libc/calls/mkdir.c index ef25c689e..2ba501cc3 100644 --- a/libc/calls/mkdir.c +++ b/libc/calls/mkdir.c @@ -45,7 +45,6 @@ * @see makedirs() which is higher-level * @see mkdirat() for modern call * @asyncsignalsafe - * @threadsafe */ int mkdir(const char *path, unsigned mode) { return mkdirat(AT_FDCWD, path, mode); diff --git a/libc/calls/munmap-sysv.c b/libc/calls/munmap-sysv.c index 8d847ec52..eeaa8f1da 100644 --- a/libc/calls/munmap-sysv.c +++ b/libc/calls/munmap-sysv.c @@ -29,7 +29,6 @@ * but it works on everything else including bare metal. * * @asyncsignalsafe - * @threadsafe */ int sys_munmap(void *p, size_t n) { int rc; diff --git a/libc/calls/nanosleep-xnu.c b/libc/calls/nanosleep-xnu.c deleted file mode 100644 index 21dad75c5..000000000 --- a/libc/calls/nanosleep-xnu.c +++ /dev/null @@ -1,51 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timespec.h" -#include "libc/calls/struct/timespec.internal.h" -#include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/errno.h" -#include "libc/runtime/syslib.internal.h" -#include "libc/sock/internal.h" - -// nanosleep() on xnu: a bloodbath of a polyfill -// consider using clock_nanosleep(TIMER_ABSTIME) -int sys_nanosleep_xnu(const struct timespec *req, struct timespec *rem) { -#ifdef __x86_64__ - int rc; - struct timeval wt, t1, t2, td; - if (rem) sys_gettimeofday_xnu(&t1, 0, 0); - wt = timespec_totimeval(*req); // rounds up - rc = sys_select(0, 0, 0, 0, &wt); - if (rem && rc == -1 && errno == EINTR) { - sys_gettimeofday_xnu(&t2, 0, 0); - td = timeval_sub(t2, t1); - if (timeval_cmp(td, wt) >= 0) { - rem->tv_sec = 0; - rem->tv_nsec = 0; - } else { - *rem = timeval_totimespec(timeval_sub(wt, td)); - } - } - return rc; -#else - return _sysret(__syslib->__nanosleep(req, rem)); -#endif -} diff --git a/libc/calls/nanosleep.c b/libc/calls/nanosleep.c index 00bce7e1a..22a13fe47 100644 --- a/libc/calls/nanosleep.c +++ b/libc/calls/nanosleep.c @@ -37,11 +37,11 @@ * @norestart */ int nanosleep(const struct timespec *req, struct timespec *rem) { - int rc; - if (!(rc = clock_nanosleep(CLOCK_REALTIME, 0, req, rem))) { + errno_t err; + if (!(err = clock_nanosleep(CLOCK_REALTIME, 0, req, rem))) { return 0; } else { - errno = rc; + errno = err; return -1; } } diff --git a/libc/calls/ntaccesscheck.c b/libc/calls/ntaccesscheck.c index 47d63870f..203bdbad9 100644 --- a/libc/calls/ntaccesscheck.c +++ b/libc/calls/ntaccesscheck.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/calls/internal.h" #include "libc/calls/syscall_support-nt.internal.h" @@ -35,6 +36,7 @@ #include "libc/nt/errors.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/nt/struct/byhandlefileinformation.h" #include "libc/nt/struct/genericmapping.h" #include "libc/nt/struct/privilegeset.h" #include "libc/nt/struct/securitydescriptor.h" @@ -62,6 +64,7 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) { struct NtGenericMapping mapping; struct NtPrivilegeSet privileges; uint32_t secsize, granted, privsize; + struct NtByHandleFileInformation wst; int64_t hToken, hImpersonatedToken, hFile; intptr_t buffer[1024 / sizeof(intptr_t)]; if (flags & X_OK) flags |= R_OK; @@ -100,7 +103,9 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) { 0, kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics, 0)) != -1) { - if (IsWindowsExecutable(hFile)) { + unassert(GetFileInformationByHandle(hFile, &wst)); + if ((wst.dwFileAttributes & kNtFileAttributeDirectory) || + IsWindowsExecutable(hFile)) { rc = 0; } else { rc = eacces(); diff --git a/libc/calls/open.c b/libc/calls/open.c index 98889d3ab..883e2d250 100644 --- a/libc/calls/open.c +++ b/libc/calls/open.c @@ -32,7 +32,6 @@ * @cancellationpoint * @asyncsignalsafe * @restartable - * @threadsafe * @vforksafe */ int open(const char *file, int flags, ...) { diff --git a/libc/calls/openat.c b/libc/calls/openat.c index df330efc8..3478a14c0 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -168,7 +168,6 @@ * @cancellationpoint * @asyncsignalsafe * @restartable - * @threadsafe * @vforksafe */ int openat(int dirfd, const char *path, int flags, ...) { diff --git a/libc/calls/pledge-linux.c b/libc/calls/pledge-linux.c index c8987f639..2a36e362d 100644 --- a/libc/calls/pledge-linux.c +++ b/libc/calls/pledge-linux.c @@ -2297,7 +2297,6 @@ static privileged void AppendPledge(struct Filter *f, // * @param ipromises is inverted integer bitmask of pledge() promises * @return 0 on success, or negative error number on error * @asyncsignalsafe - * @threadsafe * @vforksafe */ privileged int sys_pledge_linux(unsigned long ipromises, int mode) { diff --git a/libc/calls/pledge.c b/libc/calls/pledge.c index bcfd10f8f..3c423c670 100644 --- a/libc/calls/pledge.c +++ b/libc/calls/pledge.c @@ -234,7 +234,6 @@ * @raise ENOSYS if `pledge(0, 0)` was used and security is not possible * @raise EINVAL if `execpromises` on Linux isn't a subset of `promises` * @raise EINVAL if `promises` allows exec and `execpromises` is null - * @threadsafe * @vforksafe */ int pledge(const char *promises, const char *execpromises) { diff --git a/libc/calls/poll.c b/libc/calls/poll.c index c84a40aea..076ba4de6 100644 --- a/libc/calls/poll.c +++ b/libc/calls/poll.c @@ -62,7 +62,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) { diff --git a/libc/calls/posix_fadvise.c b/libc/calls/posix_fadvise.c index 1582e4280..4955921c6 100644 --- a/libc/calls/posix_fadvise.c +++ b/libc/calls/posix_fadvise.c @@ -46,7 +46,6 @@ int sys_fadvise_netbsd(int, int, int64_t, int64_t, int) asm("sys_fadvise"); * @raise ENOTSUP if `fd` is a /zip file * @raise ENOSYS on XNU and OpenBSD * @returnserrno - * @threadsafe */ errno_t posix_fadvise(int fd, int64_t offset, int64_t len, int advice) { int rc, e = errno; diff --git a/libc/calls/posix_madvise.c b/libc/calls/posix_madvise.c index a4a18b4eb..5c2e2e779 100644 --- a/libc/calls/posix_madvise.c +++ b/libc/calls/posix_madvise.c @@ -24,7 +24,6 @@ * * @return 0 on success, or errno on error * @returnserrno - * @threadsafe */ errno_t posix_madvise(void *addr, uint64_t len, int advice) { int rc, e = errno; diff --git a/libc/calls/ppoll.c b/libc/calls/ppoll.c index b5cebed28..b419b089b 100644 --- a/libc/calls/ppoll.c +++ b/libc/calls/ppoll.c @@ -57,7 +57,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout, diff --git a/libc/calls/pread.c b/libc/calls/pread.c index c72c222ea..27bc76f58 100644 --- a/libc/calls/pread.c +++ b/libc/calls/pread.c @@ -52,7 +52,6 @@ * @see pwrite(), write() * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c index b9e5005cd..ac06d28ad 100644 --- a/libc/calls/pwrite.c +++ b/libc/calls/pwrite.c @@ -46,7 +46,6 @@ * @see pread(), write() * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 4560cee22..c683cd498 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -53,8 +53,6 @@ #include "libc/thread/tls.h" #ifdef __x86_64__ -__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; - static const struct { int vk; int normal_str; @@ -578,7 +576,7 @@ textwindows ssize_t sys_read_nt_impl(int fd, void *data, size_t size, goto BlockingOperation; } } - __imp_CloseHandle(overlap.hEvent); // __imp_ to avoid log noise + CloseHandle(overlap.hEvent); if (!pwriting && seekable) { if (ok) f->pointer = offset + got; diff --git a/libc/calls/reservefd.c b/libc/calls/reservefd.c index 1821dceed..4d3d6bd3c 100644 --- a/libc/calls/reservefd.c +++ b/libc/calls/reservefd.c @@ -51,7 +51,6 @@ int __ensurefds_unlocked(int fd) { /** * Grows file descriptor array memory if needed. * @asyncsignalsafe - * @threadsafe */ int __ensurefds(int fd) { __fds_lock(); @@ -89,7 +88,6 @@ int __reservefd_unlocked(int start) { /** * Finds open file descriptor slot. * @asyncsignalsafe - * @threadsafe */ int __reservefd(int start) { int fd; diff --git a/libc/calls/siginfo2cosmo.c b/libc/calls/siginfo2cosmo.c index 6ca045844..08ec12ce6 100644 --- a/libc/calls/siginfo2cosmo.c +++ b/libc/calls/siginfo2cosmo.c @@ -85,6 +85,14 @@ privileged void __siginfo2cosmo(struct siginfo *si, notpossible; } + // Turn BUS_OBJERR into BUS_ADRERR for consistency with Linux. + // See test/libc/calls/sigbus_test.c + if (IsFreebsd() || IsOpenbsd()) { + if (si_signo == 10 && si_code == 3) { + si_code = 2; + } + } + *si = (struct siginfo){0}; si->si_signo = si_signo; si->si_errno = si_errno; diff --git a/libc/calls/state.internal.h b/libc/calls/state.internal.h index be72f6afb..8c3e266d5 100644 --- a/libc/calls/state.internal.h +++ b/libc/calls/state.internal.h @@ -6,7 +6,6 @@ COSMOPOLITAN_C_START_ extern int __vforked; -extern bool __time_critical; extern pthread_mutex_t __fds_lock_obj; extern unsigned __sighandrvas[NSIG + 1]; extern unsigned __sighandflags[NSIG + 1]; diff --git a/libc/calls/statvfs.c b/libc/calls/statvfs.c index 98f2ea7d5..8f38a8246 100644 --- a/libc/calls/statvfs.c +++ b/libc/calls/statvfs.c @@ -35,3 +35,5 @@ int statvfs(const char *path, struct statvfs *sv) { return -1; } } + +__strong_reference(statvfs, statvfs64); diff --git a/libc/calls/__clock_gettime.c b/libc/calls/stime.c similarity index 90% rename from libc/calls/__clock_gettime.c rename to libc/calls/stime.c index c3b46a6e5..7ab0ef23f 100644 --- a/libc/calls/__clock_gettime.c +++ b/libc/calls/stime.c @@ -16,6 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" +#include "libc/calls/struct/timeval.h" +#include "libc/time/time.h" -clock_gettime_f *__clock_gettime = __clock_gettime_init; +/** + * Changes time, the old fashioned way. + */ +int stime(const int64_t *t) { + return settimeofday(&(struct timeval){*t}, 0); +} diff --git a/libc/calls/struct/timespec.internal.h b/libc/calls/struct/timespec.internal.h index 6b2e11b78..3628fff8e 100644 --- a/libc/calls/struct/timespec.internal.h +++ b/libc/calls/struct/timespec.internal.h @@ -10,18 +10,18 @@ int __sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *); int __sys_utimensat(int, const char *, const struct timespec[2], int); int __utimens(int, const char *, const struct timespec[2], int); int sys_clock_getres(int, struct timespec *); -int sys_clock_settime(int, const struct timespec *); int sys_clock_gettime(int, struct timespec *); -int sys_clock_gettime_nt(int, struct timespec *); int sys_clock_gettime_m1(int, struct timespec *); +int sys_clock_gettime_mono(struct timespec *); +int sys_clock_gettime_nt(int, struct timespec *); int sys_clock_gettime_xnu(int, struct timespec *); int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *); int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *); int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *); +int sys_clock_settime(int, const struct timespec *); int sys_futimens(int, const struct timespec[2]); int sys_nanosleep(const struct timespec *, struct timespec *); int sys_nanosleep_nt(const struct timespec *, struct timespec *); -int sys_nanosleep_xnu(const struct timespec *, struct timespec *); int sys_sem_timedwait(int64_t, const struct timespec *); int sys_utimensat(int, const char *, const struct timespec[2], int); int sys_utimensat_nt(int, const char *, const struct timespec[2], int); diff --git a/libc/calls/struct/timeval.internal.h b/libc/calls/struct/timeval.internal.h index aaa2e5fa0..c68b65283 100644 --- a/libc/calls/struct/timeval.internal.h +++ b/libc/calls/struct/timeval.internal.h @@ -6,16 +6,11 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *); int sys_settimeofday(const struct timeval *, const struct timezone *); int sys_futimes(int, const struct timeval *); int sys_lutimes(const char *, const struct timeval *); int sys_utimes(const char *, const struct timeval *); -axdx_t sys_gettimeofday_m1(struct timeval *, struct timezone *, void *); -axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *); -axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *); int sys_utimes_nt(const char *, const struct timeval[2]); -axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *); const char *DescribeTimeval(char[45], int, const struct timeval *); #define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts) diff --git a/libc/calls/swapcontext.S b/libc/calls/swapcontext.S index 0fbd1b9c8..8853c2e95 100644 --- a/libc/calls/swapcontext.S +++ b/libc/calls/swapcontext.S @@ -35,7 +35,6 @@ // // @return 0 on success, or -1 w/ errno // @returnstwice -// @threadsafe .ftrace1 swapcontext: .ftrace2 diff --git a/libc/calls/syscall_support-sysv.internal.h b/libc/calls/syscall_support-sysv.internal.h index 3543933ce..1f6be424a 100644 --- a/libc/calls/syscall_support-sysv.internal.h +++ b/libc/calls/syscall_support-sysv.internal.h @@ -6,6 +6,11 @@ COSMOPOLITAN_C_START_ │ cosmopolitan § syscalls » system five » structless support ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +long __syscall2(long, long, int); +int __syscall2i(long, long, int) asm("__syscall2"); +long __syscall3(long, long, long, int); +int __syscall3i(long, long, long, int) asm("__syscall3"); + bool __is_linux_2_6_23(void); bool32 sys_isatty_metal(int); int __fixupnewfd(int, int); diff --git a/libc/calls/timespec_real.c b/libc/calls/timespec_real.c index 37034dcc9..a8a477a1b 100644 --- a/libc/calls/timespec_real.c +++ b/libc/calls/timespec_real.c @@ -31,6 +31,6 @@ */ struct timespec timespec_real(void) { struct timespec ts; - npassert(!clock_gettime(CLOCK_REALTIME, &ts)); + unassert(!clock_gettime(CLOCK_REALTIME, &ts)); return ts; } diff --git a/libc/calls/tmpfd.c b/libc/calls/tmpfd.c index dc7b8620a..7e93b66db 100644 --- a/libc/calls/tmpfd.c +++ b/libc/calls/tmpfd.c @@ -71,7 +71,6 @@ int _mkstemp(char *, int); * @see tmpfile() for stdio version * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ int tmpfd(void) { diff --git a/libc/calls/truncate.c b/libc/calls/truncate.c index ebd252c2c..cc9772e3b 100644 --- a/libc/calls/truncate.c +++ b/libc/calls/truncate.c @@ -61,7 +61,6 @@ * @raise ENOSYS on bare metal * @cancellationpoint * @see ftruncate() - * @threadsafe */ int truncate(const char *path, int64_t length) { int rc; diff --git a/libc/calls/ttyname.c b/libc/calls/ttyname.c index 5df6e696e..908ccbbde 100644 --- a/libc/calls/ttyname.c +++ b/libc/calls/ttyname.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/errno.h" #include "libc/log/log.h" #include "libc/paths.h" diff --git a/libc/calls/ttyname_r.c b/libc/calls/ttyname_r.c index 554255b12..21fbefb72 100644 --- a/libc/calls/ttyname_r.c +++ b/libc/calls/ttyname_r.c @@ -85,7 +85,6 @@ static errno_t ttyname_linux(int fd, char *buf, size_t size) { * @return 0 on success, or error number on error * @raise ERANGE if `size` was too small * @returnserrno - * @threadsafe */ errno_t ttyname_r(int fd, char *buf, size_t size) { errno_t e, res; diff --git a/libc/calls/ucontext.c b/libc/calls/ucontext.c index a5fc2be32..5ff2ceeac 100644 --- a/libc/calls/ucontext.c +++ b/libc/calls/ucontext.c @@ -43,7 +43,6 @@ static int __contextmask(const sigset_t *opt_set, sigset_t *opt_out_oldset) { * @see swapcontext() * @see makecontext() * @see getcontext() - * @threadsafe */ int setcontext(const ucontext_t *uc) { if (__contextmask(&uc->uc_sigmask, 0)) return -1; diff --git a/libc/calls/unveil.c b/libc/calls/unveil.c index 2dd0209d1..00fd47c43 100644 --- a/libc/calls/unveil.c +++ b/libc/calls/unveil.c @@ -460,7 +460,6 @@ int sys_unveil_linux(const char *path, const char *permissions) { * @note on Linux this function requires Linux Kernel 5.13+ and version 6.2+ * to properly support truncation operations * @see [1] https://docs.kernel.org/userspace-api/landlock.html - * @threadsafe */ int unveil(const char *path, const char *permissions) { int e, rc; diff --git a/libc/calls/utime.c b/libc/calls/utime.c index 363f6eff7..f9417ed25 100644 --- a/libc/calls/utime.c +++ b/libc/calls/utime.c @@ -26,7 +26,6 @@ * @return 0 on success, or -1 w/ errno * @see utimensat() for modern version * @asyncsignalsafe - * @threadsafe */ int utime(const char *path, const struct utimbuf *times) { struct timeval tv[2]; diff --git a/libc/calls/utimensat-nt.c b/libc/calls/utimensat-nt.c index e4711a167..46776b3a8 100644 --- a/libc/calls/utimensat-nt.c +++ b/libc/calls/utimensat-nt.c @@ -17,8 +17,9 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" diff --git a/libc/calls/utimensat.c b/libc/calls/utimensat.c index 011950b3f..aa19cf6a2 100644 --- a/libc/calls/utimensat.c +++ b/libc/calls/utimensat.c @@ -51,7 +51,6 @@ * @raise ENOTSUP on XNU or RHEL5 when `dirfd` isn't `AT_FDCWD` * @raise ENOSYS on bare metal * @asyncsignalsafe - * @threadsafe */ int utimensat(int dirfd, const char *path, const struct timespec ts[2], int flags) { diff --git a/libc/calls/utimes.c b/libc/calls/utimes.c index 7297a0663..5e2d3651d 100644 --- a/libc/calls/utimes.c +++ b/libc/calls/utimes.c @@ -32,7 +32,6 @@ * @note truncates to second precision on rhel5 * @see utimensat() for modern version * @asyncsignalsafe - * @threadsafe */ int utimes(const char *path, const struct timeval tv[2]) { int rc; diff --git a/libc/calls/vdsofunc.greg.c b/libc/calls/vdsofunc.greg.c index 861514bab..7f669a962 100644 --- a/libc/calls/vdsofunc.greg.c +++ b/libc/calls/vdsofunc.greg.c @@ -27,6 +27,7 @@ #include "libc/elf/struct/verdaux.h" #include "libc/elf/struct/verdef.h" #include "libc/intrin/bits.h" +#include "libc/intrin/getauxval.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" @@ -55,7 +56,7 @@ static inline int CheckDsoSymbolVersion(Elf64_Verdef *vd, int sym, } /** - * Returns address of vDSO function. + * Returns address of "Virtual Dynamic Shared Object" function on Linux. */ void *__vdsosym(const char *version, const char *name) { void *p; @@ -64,23 +65,19 @@ void *__vdsosym(const char *version, const char *name) { Elf64_Phdr *phdr; char *strtab = 0; size_t *dyn, base; - unsigned long *ap; Elf64_Sym *symtab = 0; uint16_t *versym = 0; Elf_Symndx *hashtab = 0; Elf64_Verdef *verdef = 0; + struct AuxiliaryValue av; - for (ehdr = 0, ap = __auxv; ap[0]; ap += 2) { - if (ap[0] == AT_SYSINFO_EHDR) { - ehdr = (void *)ap[1]; - break; - } - } - if (!ehdr || READ32LE(ehdr->e_ident) != READ32LE("\177ELF")) { - KERNTRACE("__vdsosym() → AT_SYSINFO_EHDR ELF not found"); + av = __getauxval(AT_SYSINFO_EHDR); + if (!av.isfound) { + KERNTRACE("__vdsosym() → missing AT_SYSINFO_EHDR"); return 0; } + ehdr = (void *)av.value; phdr = (void *)((char *)ehdr + ehdr->e_phoff); for (base = -1, dyn = 0, i = 0; i < ehdr->e_phnum; i++, phdr = (void *)((char *)phdr + ehdr->e_phentsize)) { diff --git a/libc/calls/weirdtypes.h b/libc/calls/weirdtypes.h index 072735dcb..997475a4e 100644 --- a/libc/calls/weirdtypes.h +++ b/libc/calls/weirdtypes.h @@ -64,6 +64,7 @@ typedef uint32_t nlink_t; /* uint16_t on xnu */ #define fstat64 fstat #define fstatat64 fstatat #define fstatfs64 fstatfs +#define fstatvfs64 fstatvfs #define getrlimit64 getrlimit #define ino64_t ino_t #define lockf64 lockf @@ -83,6 +84,7 @@ typedef uint32_t nlink_t; /* uint16_t on xnu */ #define setrlimit64 setrlimit #define stat64 stat #define statfs64 statfs +#define statvfs64 statvfs #define versionsort64 versionsort #endif diff --git a/libc/calls/winexec.c b/libc/calls/winexec.c index 4b5ac6bde..a3daed48e 100644 --- a/libc/calls/winexec.c +++ b/libc/calls/winexec.c @@ -17,12 +17,27 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/nt/errors.h" +#include "libc/nt/events.h" +#include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/nt/struct/overlapped.h" +// checks if file should be considered an executable on windows textwindows int IsWindowsExecutable(int64_t handle) { + + // read first two bytes of file + // access() and stat() aren't cancelation points char buf[2]; uint32_t got; - return ReadFile(handle, buf, 2, &got, 0) && got == 2 && + struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)}; + bool ok = (ReadFile(handle, buf, 2, 0, &overlap) || + GetLastError() == kNtErrorIoPending) && + GetOverlappedResult(handle, &overlap, &got, true); + CloseHandle(overlap.hEvent); + + // it's an executable if it starts with `MZ` or `#!` + return ok && got == 2 && // ((buf[0] == 'M' && buf[1] == 'Z') || // (buf[0] == '#' && buf[1] == '!')); } diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c index 83ac291eb..426a2036c 100644 --- a/libc/calls/write-nt.c +++ b/libc/calls/write-nt.c @@ -47,8 +47,6 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; - static bool IsMouseModeCommand(int x) { return x == 1000 || // SET_VT200_MOUSE x == 1002 || // SET_BTN_EVENT_MOUSE @@ -202,7 +200,7 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size, goto BlockingOperation; } } - __imp_CloseHandle(overlap.hEvent); // __imp_ to avoid log noise + CloseHandle(overlap.hEvent); if (seekable && !pwriting) { if (ok) f->pointer = offset + sent; diff --git a/libc/dns/freeaddrinfo.c b/libc/dns/freeaddrinfo.c index aaa0b67ce..bce7c4933 100644 --- a/libc/dns/freeaddrinfo.c +++ b/libc/dns/freeaddrinfo.c @@ -21,7 +21,6 @@ /** * Frees addresses returned by getaddrinfo(). - * @threadsafe */ void freeaddrinfo(struct addrinfo *ai) { struct addrinfo *next; diff --git a/libc/dns/getaddrinfo.c b/libc/dns/getaddrinfo.c index a799ca4bf..8a03a8089 100644 --- a/libc/dns/getaddrinfo.c +++ b/libc/dns/getaddrinfo.c @@ -41,7 +41,6 @@ * @param res receives a pointer that must be freed with freeaddrinfo(), * and won't be modified if non-zero is returned * @return 0 on success or EAI_xxx value - * @threadsafe */ int getaddrinfo(const char *name, const char *service, const struct addrinfo *hints, struct addrinfo **res) { diff --git a/libc/dns/gethoststxt.c b/libc/dns/gethoststxt.c index dd172d36b..ab63fb370 100644 --- a/libc/dns/gethoststxt.c +++ b/libc/dns/gethoststxt.c @@ -51,7 +51,6 @@ static const char *GetHostsTxtPath(char *path, size_t size) { * Returns hosts.txt map. * * @note yoinking realloc() ensures there's no size limits - * @threadsafe */ const struct HostsTxt *GetHostsTxt(void) { FILE *f; diff --git a/libc/dns/getresolvconf.c b/libc/dns/getresolvconf.c index 09a61be08..f71e97345 100644 --- a/libc/dns/getresolvconf.c +++ b/libc/dns/getresolvconf.c @@ -37,7 +37,6 @@ static struct ResolvConfInitialStaticMemory { /** * Returns singleton with DNS server address. - * @threadsafe */ const struct ResolvConf *GetResolvConf(void) { int rc; diff --git a/libc/dns/lookupservicesbyname.c b/libc/dns/lookupservicesbyname.c index 25924faa0..8a1464923 100644 --- a/libc/dns/lookupservicesbyname.c +++ b/libc/dns/lookupservicesbyname.c @@ -50,7 +50,6 @@ * @return -1 on error, or positive port number * @note aliases are read from file for comparison, but not returned. * @see LookupServicesByPort - * @threadsafe */ int LookupServicesByName(const char *servname, char *servproto, size_t servprotolen, char *buf, size_t bufsize, diff --git a/libc/fmt/conv.h b/libc/fmt/conv.h index 75b0c2a5b..49c4526aa 100644 --- a/libc/fmt/conv.h +++ b/libc/fmt/conv.h @@ -1,16 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_FMT_CONV_H_ #define COSMOPOLITAN_LIBC_FMT_CONV_H_ -#include "libc/calls/struct/timespec.h" -#include "libc/calls/struct/timeval.h" -#include "libc/nt/struct/filetime.h" - -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - -#define MODERNITYSECONDS 11644473600ull -#define HECTONANOSECONDS 10000000ull - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -48,52 +37,10 @@ float wcstof(const wchar_t *, wchar_t **); double wcstod(const wchar_t *, wchar_t **); long double wcstold(const wchar_t *, wchar_t **); -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » time ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - -int64_t DosDateTimeToUnix(unsigned, unsigned) libcesque nosideeffect; -struct timeval WindowsTimeToTimeVal(int64_t) -libcesque nosideeffect; -struct timespec WindowsTimeToTimeSpec(int64_t) -libcesque nosideeffect; -int64_t TimeSpecToWindowsTime(struct timespec) libcesque nosideeffect; -int64_t TimeValToWindowsTime(struct timeval) libcesque nosideeffect; -struct timeval WindowsDurationToTimeVal(int64_t) -libcesque nosideeffect; -struct timespec WindowsDurationToTimeSpec(int64_t) -libcesque nosideeffect; - -#define MakeFileTime(x) \ - ({ \ - int64_t __x = x; \ - (struct NtFileTime){(uint32_t)__x, (uint32_t)(__x >> 32)}; \ - }) - -#define ReadFileTime(t) \ - ({ \ - struct NtFileTime __t = t; \ - uint64_t x = __t.dwHighDateTime; \ - (int64_t)(x << 32 | __t.dwLowDateTime); \ - }) - -#define FileTimeToTimeSpec(x) WindowsTimeToTimeSpec(ReadFileTime(x)) -#define FileTimeToTimeVal(x) WindowsTimeToTimeVal(ReadFileTime(x)) -#define TimeSpecToFileTime(x) MakeFileTime(TimeSpecToWindowsTime(x)) -#define TimeValToFileTime(x) MakeFileTime(TimeValToWindowsTime(x)) - -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » manipulation ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - #ifdef _COSMO_SOURCE char *stripext(char *); char *stripexts(char *); -#endif - -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » computation ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ +#endif /* _COSMO_SOURCE */ typedef struct { int quot; @@ -120,10 +67,6 @@ ldiv_t ldiv(long, long) pureconst; lldiv_t lldiv(long long, long long) pureconst; imaxdiv_t imaxdiv(intmax_t, intmax_t) pureconst; -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » optimizations ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - #if __STDC_VERSION__ + 0 >= 199901L #define div(num, den) ((div_t){(num) / (den), (num) % (den)}) #define ldiv(num, den) ((ldiv_t){(num) / (den), (num) % (den)}) diff --git a/libc/fmt/wintime.internal.h b/libc/fmt/wintime.internal.h new file mode 100644 index 000000000..97d9fce57 --- /dev/null +++ b/libc/fmt/wintime.internal.h @@ -0,0 +1,41 @@ +#ifndef COSMOPOLITAN_LIBC_FMT_WINTIME_H_ +#define COSMOPOLITAN_LIBC_FMT_WINTIME_H_ +#include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timeval.h" +#include "libc/nt/struct/filetime.h" + +#define MODERNITYSECONDS 11644473600ull +#define HECTONANOSECONDS 10000000ull + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int64_t DosDateTimeToUnix(uint32_t, uint32_t) pureconst; +int64_t TimeSpecToWindowsTime(struct timespec) pureconst; +int64_t TimeValToWindowsTime(struct timeval) pureconst; +struct timespec WindowsDurationToTimeSpec(int64_t) pureconst; +struct timespec WindowsTimeToTimeSpec(int64_t) pureconst; +struct timeval WindowsDurationToTimeVal(int64_t) pureconst; +struct timeval WindowsTimeToTimeVal(int64_t) pureconst; + +#define MakeFileTime(x) \ + ({ \ + int64_t __x = x; \ + (struct NtFileTime){(uint32_t)__x, (uint32_t)(__x >> 32)}; \ + }) + +#define ReadFileTime(t) \ + ({ \ + struct NtFileTime __t = t; \ + uint64_t x = __t.dwHighDateTime; \ + (int64_t)(x << 32 | __t.dwLowDateTime); \ + }) + +#define FileTimeToTimeSpec(x) WindowsTimeToTimeSpec(ReadFileTime(x)) +#define FileTimeToTimeVal(x) WindowsTimeToTimeVal(ReadFileTime(x)) +#define TimeSpecToFileTime(x) MakeFileTime(TimeSpecToWindowsTime(x)) +#define TimeValToFileTime(x) MakeFileTime(TimeValToWindowsTime(x)) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_FMT_WINTIME_H_ */ diff --git a/libc/intrin/bt.c b/libc/intrin/bt.c deleted file mode 100644 index 6d61f0177..000000000 --- a/libc/intrin/bt.c +++ /dev/null @@ -1,68 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 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/errno.h" -#include "libc/intrin/kprintf.h" -#include "libc/intrin/weaken.h" -#include "libc/log/backtrace.internal.h" -#include "libc/runtime/symbols.internal.h" - -static _Thread_local bool noreentry; - -/** - * Shows backtrace if crash reporting facilities are linked. - */ -void _bt(const char *fmt, ...) { - int e; - va_list va; - - if (!noreentry) { - noreentry = true; - } else { - return; - } - - if (fmt) { - va_start(va, fmt); - kvprintf(fmt, va); - va_end(va); - } - - if (_weaken(ShowBacktrace) && _weaken(GetSymbolTable)) { - e = errno; - _weaken(ShowBacktrace)(2, __builtin_frame_address(0)); - errno = e; - } else { - kprintf("_bt() can't show backtrace because you need:\n" - "\t__static_yoink(\"ShowBacktrace\");\n" - "to be linked.\n"); - if (_weaken(PrintBacktraceUsingSymbols) && _weaken(GetSymbolTable)) { - e = errno; - _weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0), - _weaken(GetSymbolTable)()); - errno = e; - } else { - kprintf("_bt() can't show backtrace because you need:\n" - "\t__static_yoink(\"PrintBacktraceUsingSymbols\");\n" - "\t__static_yoink(\"GetSymbolTable\");\n" - "to be linked.\n"); - } - } - - noreentry = false; -} diff --git a/libc/intrin/closehandle.c b/libc/intrin/closehandle.c deleted file mode 100644 index f09b53c03..000000000 --- a/libc/intrin/closehandle.c +++ /dev/null @@ -1,37 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 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/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" -#include "libc/log/log.h" -#include "libc/nt/runtime.h" -#include "libc/nt/thunk/msabi.h" - -__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; - -/** - * Closes an open object handle. - * @note this wrapper takes care of ABI, STRACE(), and __winerr() - */ -textwindows bool32 CloseHandle(int64_t hObject) { - bool32 ok; - ok = __imp_CloseHandle(hObject); - if (!ok) __winerr(); - NTTRACE("CloseHandle(%ld) → %hhhd% m", hObject, ok); - return ok; -} diff --git a/libc/intrin/cp.c b/libc/intrin/cp.c index 7d34f347b..4a9d092db 100644 --- a/libc/intrin/cp.c +++ b/libc/intrin/cp.c @@ -51,9 +51,7 @@ void end_cancellation_point(int state) { } void report_cancellation_point(void) { - BLOCK_CANCELLATIONS; - _bt("error: need BEGIN/END_CANCELLATION_POINT\n"); - ALLOW_CANCELLATIONS; + __builtin_trap(); } #endif /* MODE_DBG */ diff --git a/libc/intrin/directmap.c b/libc/intrin/directmap.c index e224379d9..497b9ba84 100644 --- a/libc/intrin/directmap.c +++ b/libc/intrin/directmap.c @@ -33,7 +33,6 @@ * for passing the magic memory handle on Windows NT to CloseHandle(). * * @asyncsignalsafe - * @threadsafe */ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { diff --git a/libc/intrin/exit.c b/libc/intrin/exit.c index bc5a3c79f..255174771 100644 --- a/libc/intrin/exit.c +++ b/libc/intrin/exit.c @@ -40,7 +40,6 @@ * by hosing the interrupt descriptors and triple faulting the system. * * @asyncsignalsafe - * @threadsafe * @vforksafe * @noreturn */ diff --git a/libc/intrin/exit1.greg.c b/libc/intrin/exit1.greg.c index 8c5d300c0..cb90fbbfd 100644 --- a/libc/intrin/exit1.greg.c +++ b/libc/intrin/exit1.greg.c @@ -40,7 +40,6 @@ __msabi extern typeof(ExitThread) *const __imp_ExitThread; * * @param rc only works on Linux and Windows * @see cthread_exit() - * @threadsafe * @noreturn */ privileged wontreturn void _Exit1(int rc) { diff --git a/libc/intrin/getmainstack.c b/libc/intrin/getmainstack.c index 0c955bfb7..498ce2add 100644 --- a/libc/intrin/getmainstack.c +++ b/libc/intrin/getmainstack.c @@ -28,6 +28,8 @@ #include "libc/sysv/consts/rlim.h" #include "libc/sysv/consts/rlimit.h" +// Hack for guessing boundaries of _start()'s stack +// // Every UNIX system in our support vector creates arg blocks like: // // @@ -53,6 +55,11 @@ // up to the microprocessor page size (this computes the top addr) // and the bottom is computed by subtracting RLIMIT_STACK rlim_cur // It's simple but gets tricky if we consider environ can be empty +// +// This code always guesses correctly on Windows because WinMain() +// is written to allocate a stack ourself. Local testing on Linux, +// XNU, FreeBSD, OpenBSD, and NetBSD says that accuracy is ±1 page +// and that error rate applies to both beginning and end addresses static char *__get_last(char **list) { char *res = 0; diff --git a/libc/intrin/getpid.c b/libc/intrin/getpid.c index 94b0fb4f1..fb0860996 100644 --- a/libc/intrin/getpid.c +++ b/libc/intrin/getpid.c @@ -38,7 +38,6 @@ * * @return process id (always successful) * @asyncsignalsafe - * @threadsafe * @vforksafe */ int getpid(void) { diff --git a/libc/intrin/gettid.c b/libc/intrin/gettid.c index f8be087ce..67cb0bfa4 100644 --- a/libc/intrin/gettid.c +++ b/libc/intrin/gettid.c @@ -34,7 +34,6 @@ * * @return thread id greater than zero or -1 w/ errno * @asyncsignalsafe - * @threadsafe * @vforksafe */ int gettid(void) { diff --git a/libc/intrin/rand64.c b/libc/intrin/rand64.c index 88fda8987..aa8e8b5d7 100644 --- a/libc/intrin/rand64.c +++ b/libc/intrin/rand64.c @@ -43,7 +43,6 @@ static struct { * @note this function is not intended for cryptography * @note this function passes bigcrush and practrand * @asyncsignalsafe - * @threadsafe * @vforksafe */ uint64_t _rand64(void) { diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.internal.h index 1dce6394d..60b17b3ad 100644 --- a/libc/intrin/strace.internal.h +++ b/libc/intrin/strace.internal.h @@ -3,12 +3,13 @@ #include "libc/intrin/likely.h" #include "libc/runtime/runtime.h" -#define _KERNTRACE 0 /* not configurable w/ flag yet */ +#define _NTTRACE 1 /* not configurable w/ flag yet */ #define _POLLTRACE 0 /* not configurable w/ flag yet */ #define _DATATRACE 1 /* not configurable w/ flag yet */ -#define _STDIOTRACE 0 /* not configurable w/ flag yet */ #define _LOCKTRACE 0 /* not configurable w/ flag yet */ -#define _NTTRACE 0 /* not configurable w/ flag yet */ +#define _STDIOTRACE 0 /* not configurable w/ flag yet */ +#define _KERNTRACE 0 /* not configurable w/ flag yet */ +#define _TIMETRACE 0 /* not configurable w/ flag yet */ #define STRACE_PROLOGUE "%rSYS %6P %'18T " @@ -63,6 +64,12 @@ COSMOPOLITAN_C_START_ #define LOCKTRACE(FMT, ...) (void)0 #endif +#if defined(SYSDEBUG) && _TIMETRACE +#define TIMETRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define TIMETRACE(FMT, ...) (void)0 +#endif + void __stracef(const char *, ...); COSMOPOLITAN_C_END_ diff --git a/libc/intrin/strsignal.c b/libc/intrin/strsignal.c index ab70a1c5a..c4d34f21f 100644 --- a/libc/intrin/strsignal.c +++ b/libc/intrin/strsignal.c @@ -33,8 +33,9 @@ static char g_strsignal[21]; * * @param sig is signal number which should be in range 1 through 128 * @return string which is valid code describing signal - * @see strsignal_r() for better thread safety + * @see strsignal_r() * @see sigaction() + * @threadunsafe */ char *strsignal(int sig) { return strsignal_r(sig, g_strsignal); diff --git a/libc/intrin/strsignal_r.c b/libc/intrin/strsignal_r.c index d83206f60..9d8c3ae5f 100644 --- a/libc/intrin/strsignal_r.c +++ b/libc/intrin/strsignal_r.c @@ -34,7 +34,6 @@ * @return pointer to .rodata string, or to `buf` after mutating * @see sigaction() * @asyncsignalsafe - * @threadsafe */ privileged char *strsignal_r(int sig, char buf[21]) { const char *s; diff --git a/libc/intrin/unsetenv.c b/libc/intrin/unsetenv.c index 893d8c577..7499d3c2c 100644 --- a/libc/intrin/unsetenv.c +++ b/libc/intrin/unsetenv.c @@ -19,6 +19,7 @@ #include "libc/dce.h" #include "libc/intrin/getenv.internal.h" #include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/sysv/errfuns.h" /** @@ -27,15 +28,12 @@ * @param s is non-empty environment key which can't contain `'='` * @return 0 on success, or -1 w/ errno and environment is unchanged * @raise EINVAL if `s` is an empty string or has a `'='` character + * @threadunsafe */ int unsetenv(const char *s) { char **p; struct Env e; - const char *t; - if (!s || !*s) return einval(); - for (t = s; *t; ++t) { - if (*t == '=') return einval(); - } + if (!s || !*s || strchr(s, '=')) return einval(); if ((p = environ)) { e = __getenv(p, s); while (p[e.i]) { diff --git a/libc/isystem/sys/param.h b/libc/isystem/sys/param.h index b23ef87a0..8fbbcc0b8 100644 --- a/libc/isystem/sys/param.h +++ b/libc/isystem/sys/param.h @@ -4,7 +4,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/libc/isystem/windows.h b/libc/isystem/windows.h deleted file mode 100644 index ee92e29f4..000000000 --- a/libc/isystem/windows.h +++ /dev/null @@ -1,1507 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ -#define COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ -#include "libc/nt/accounting.h" -#include "libc/nt/automation.h" -#include "libc/nt/console.h" -#include "libc/nt/debug.h" -#include "libc/nt/dll.h" -#include "libc/nt/enum/keyaccess.h" -#include "libc/nt/enum/regtype.h" -#include "libc/nt/errors.h" -#include "libc/nt/events.h" -#include "libc/nt/files.h" -#include "libc/nt/ipc.h" -#include "libc/nt/memory.h" -#include "libc/nt/paint.h" -#include "libc/nt/process.h" -#include "libc/nt/registry.h" -#include "libc/nt/synchronization.h" -#include "libc/nt/thread.h" -#include "libc/nt/windows.h" -#include "libc/nt/winsock.h" - -/* #if defined(__GNUC__) */ -/* #pragma GCC diagnostic ignored "-Wint-conversion" */ -/* #endif */ -#undef NULL -#define NULL 0 - -#define ERROR_SUCCESS kNtErrorSuccess - -#define FARPROC wambda -#define NEARPROC wambda -#define PROC wambda - -#define LONG int32_t /* [sic] */ -#define WCHAR char16_t /* [sic] */ -#define BOOL bool32 /* [sic] */ - -#define TRUE true -#define FALSE false - -#define PVOID void* -#define PVOID64 void* -#define LPCVOID const void* -#define CHAR char -#define SHORT short -#define CONST const -#define VOID void -#define INT8 signed char -#define PINT8 signed char* -#define INT16 int16_t -#define PINT16 int16_t* -#define INT32 int32_t -#define PINT32 int32_t* -#define INT64 int64_t -#define PINT64 int64_t* -#define UINT8 unsigned char -#define PUINT8 unsigned char* -#define UINT16 uint16_t -#define PUINT16 uint16_t* -#define UINT32 uint32_t -#define PUINT32 uint32_t* -#define UINT64 uint64_t -#define PUINT64 uint64_t* -#define LONG32 int32_t -#define PLONG32 int32_t* -#define ULONG32 uint32_t -#define PULONG32 uint32_t* -#define DWORD32 uint32_t -#define PDWORD32 uint32_t* - -#define INT_PTR intptr_t -#define PINT_PTR intptr_t* -#define UINT_PTR uintptr_t -#define PUINT_PTR uintptr_t* -#define LONG_PTR intptr_t -#define PLONG_PTR int32_t** -#define ULONG_PTR uintptr_t -#define PULONG_PTR uint32_t** -#define POINTER_64_INT int64_t* -#define __int3264 int64_t - -#define SHANDLE_PTR int64_t -#define HANDLE_PTR uint64_t - -#define UHALF_PTR uint32_t -#define PUHALF_PTR uint32_t* -#define HALF_PTR int32_t -#define PHALF_PTR int32_t* - -#define SIZE_T size_t -#define PSIZE_T size_t* -#define SSIZE_T ssize_t -#define PSSIZE_T ssize_t* -#define DWORD_PTR ULONG_PTR -#define PDWORD_PTR ULONG_PTR* -#define LONG64 int64_t -#define PLONG64 int64_t* -#define ULONG64 uint64_t -#define PULONG64 uint64_t* -#define DWORD64 uint64_t -#define PDWORD64 uint64_t* -#define KAFFINITY ULONG_PTR -#define PKAFFINITY KAFFINITY* -#define KPRIORITY LONG - -#define PWCHAR WCHAR* -#define LPWCH WCHAR* -#define PWCH WCHAR* -#define LPCWCH CONST WCHAR* -#define PCWCH CONST WCHAR* -#define NWPSTR WCHAR* -#define LPWSTR WCHAR* -#define PWSTR WCHAR* -#define PZPWSTR PWSTR* -#define PCZPWSTR CONST PWSTR* -#define LPUWSTR WCHAR forcealign(1)* -#define PUWSTR WCHAR forcealign(1)* -#define LPCWSTR CONST WCHAR* -#define PCWSTR CONST WCHAR* -#define PZPCWSTR PCWSTR* -#define LPCUWSTR CONST WCHAR forcealign(1)* -#define PCUWSTR CONST WCHAR forcealign(1)* -#define PCHAR CHAR* -#define LPCH CHAR* -#define PCH CHAR* -#define LPCCH CONST CHAR* -#define PCCH CONST CHAR* -#define NPSTR CHAR* -#define LPSTR CHAR* -#define PSTR CHAR* -#define PZPSTR PSTR* -#define PCZPSTR CONST PSTR* -#define LPCSTR CONST CHAR* -#define PCSTR CONST CHAR* -#define PZPCSTR PCSTR* -#define TCHAR WCHAR -#define PTCHAR WCHAR* -#define TBYTE WCHAR -#define PTBYTE WCHAR* -#define LPTCH LPWSTR -#define PTCH LPWSTR -#define PTSTR LPWSTR -#define LPTSTR LPWSTR -#define PCTSTR LPCWSTR -#define LPCTSTR LPCWSTR -#define PUTSTR LPUWSTR -#define LPUTSTR LPUWSTR -#define PCUTSTR LPCUWSTR -#define LPCUTSTR LPCUWSTR -#define LP LPWSTR -#define PSHORT int16_t* -#define PLONG int32_t* -#define HANDLE int64_t -#define PHANDLE HANDLE* -#define FCHAR BYTE -#define FSHORT WORD -#define FLONG DWORD -#define HRESULT LONG -#define CCHAR char -#define LCID DWORD -#define PLCID PDWORD -#define LANGID WORD -#define LONGLONG int64_t -#define ULONGLONG uint64_t -#define USN LONGLONG -#define PLONGLONG LONGLONG* -#define PULONGLONG ULONGLONG* -#define DWORDLONG ULONGLONG -#define PDWORDLONG DWORDLONG* -#define LARGE_INTEGER int64_t -#define PLARGE_INTEGER int64_t* - -#define ULONG uint32_t -#define PULONG ULONG* -#define USHORT unsigned short -#define PUSHORT USHORT* -#define UCHAR unsigned char -#define PUCHAR UCHAR* -#define PSZ char* -#define DWORD uint32_t -#define WINBOOL BOOL -#define BOOLEAN BOOL -#define BYTE unsigned char -#define WORD unsigned short -#define FLOAT float -#define PFLOAT FLOAT* -#define PBOOL WINBOOL* -#define PBOOLEAN WINBOOL* -#define LPBOOL WINBOOL* -#define PBYTE BYTE* -#define LPBYTE BYTE* -#define PINT int* -#define LPINT int* -#define PWORD WORD* -#define LPWORD WORD* -#define LPLONG int32_t* -#define PDWORD DWORD* -#define LPDWORD DWORD* -#define LPVOID void* -#define LPCVOID const void* -#define INT int -#define UINT unsigned int -#define PUINT unsigned int* -#define WPARAM UINT_PTR -#define LPARAM LONG_PTR -#define LRESULT LONG_PTR -#define ATOM WORD -#define SPHANDLE HANDLE* -#define LPHANDLE HANDLE* -#define HGLOBAL HANDLE -#define HLOCAL HANDLE -#define GLOBALHANDLE HANDLE -#define LOCALHANDLE HANDLE -#define HGDIOBJ void* -#define PHKEY HKEY* -#define HMODULE HINSTANCE -#define HFILE int -#define HCURSOR HICON -#define COLORREF DWORD -#define LPCOLORREF DWORD* -#define ACCESS_MASK ULONG -#define REGSAM ACCESS_MASK -#define HKEY int64_t - -#define NTSTATUS LONG -#define HACCEL int64_t -#define HBITMAP int64_t -#define HBRUSH int64_t -#define HCOLORSPACE int64_t -#define HDC int64_t -#define HGLRC int64_t -#define HDESK int64_t -#define HENHMETAFILE int64_t -#define HFONT int64_t -#define HICON int64_t -#define HMENU int64_t -#define HMETAFILE int64_t -#define HINSTANCE int64_t -#define HPALETTE int64_t -#define HPEN int64_t -#define HRGN int64_t -#define HRSRC int64_t -#define HSTR int64_t -#define HTASK int64_t -#define HWINSTA int64_t -#define HKL int64_t -#define HMONITOR int64_t -#define HWINEVENTHOOK int64_t -#define HUMPD int64_t -#define HWND int64_t - -#define PDH_FUNCTION LONG - -#define PDH_HCOUNTER HANDLE -#define PDH_HQUERY HANDLE -#define PDH_HLOG HANDLE - -#define ADDRESS_FAMILY uint16_t -#define TUNNEL_TYPE uint32_t -#define NET_IF_CONNECTION_TYPE uint32_t -#define NET_IF_COMPARTMENT_ID uint32_t -#define IFTYPE uint32_t -#define NL_PREFIX_ORIGIN uint32_t -#define NL_SUFFIX_ORIGIN uint32_t -#define NL_DAD_STATE uint32_t -#define NET_IF_NETWORK_GUID struct NtGuid -#define IP_PREFIX_ORIGIN NL_PREFIX_ORIGIN -#define IP_SUFFIX_ORIGIN NL_SUFFIX_ORIGIN -#define IP_DAD_STATE NL_DAD_STATE -#define IP_ADAPTER_ADDRESSES struct NtIpAdapterAddresses -#define PIP_ADAPTER_ADDRESSES struct NtIpAdapterAddresses* -#define IP_ADAPTER_UNICAST_ADDRESS struct NtIpAdapterUnicastAddressLh -#define PIP_ADAPTER_UNICAST_ADDRESS struct NtIpAdapterUnicastAddressLh* -#define IP_ADAPTER_ANYCAST_ADDRESS struct NtIpAdapterAnycastAddressXp -#define PIP_ADAPTER_ANYCAST_ADDRESS struct NtIpAdapterAnycastAddressXp* -#define IP_ADAPTER_MULTICAST_ADDRESS struct NtIpAdapterMulticastAddressXp -#define PIP_ADAPTER_MULTICAST_ADDRESS struct NtIpAdapterMulticastAddressXp* -#define IP_ADAPTER_DNS_SERVER_ADDRESS struct NtIpAdapterDnsServerAddressXp -#define IP_ADAPTER_PREFIX struct NtIpAdapterPrefixXp -#define PIP_ADAPTER_PREFIX struct NtIpAdapterPrefixXp* - -#define _GENERIC_MAPPING NtGenericMapping -#define GENERIC_MAPPING struct NtGenericMapping -#define PGENERIC_MAPPING struct NtGenericMapping* -#define _UNICODE_STRING NtUnicodeString -#define UNICODE_STRING struct NtUnicodeString -#define PUNICODE_STRING struct NtUnicodeString* -#define _IO_COUNTERS NtIoCounters -#define IO_COUNTERS struct NtIoCounters -#define PIO_COUNTERS struct NtIoCounters* -#define _FILE_TIME NtFileTime -#define FILE_TIME struct NtFileTime -#define PFILE_TIME struct NtFileTime* -#define _FILETIME NtFileTime -#define FILETIME struct NtFileTime -#define PFILETIME struct NtFileTime* -#define _CLIENT_ID NtClientId -#define CLIENT_ID struct NtClientId -#define PCLIENT_ID struct NtClientId* -#define _SYSTEM_THREADS NtSystemThreads -#define SYSTEM_THREADS struct NtSystemThreads -#define PSYSTEM_THREADS struct NtSystemThreads* -#define _VM_COUNTERS NtVmCounters -#define VM_COUNTERS struct NtVmCounters -#define PVM_COUNTERS struct NtVmCounters* -#define _SECURITY_DESCRIPTOR NtSecurityDescriptor -#define SECURITY_DESCRIPTOR struct NtSecurityDescriptor -#define PSECURITY_DESCRIPTOR struct NtSecurityDescriptor* - -#define _OBJECT_ALL_INFORMATION NtObjectAllInformation -#define OBJECT_ALL_INFORMATION struct NtObjectAllinformation -#define POBJECT_ALL_INFORMATION struct NtObjectAllInformation* -#define _OBJECT_TYPE_INFORMATION NtObjectTypeInformation -#define OBJECT_TYPE_INFORMATION struct NtObjectTypeInformation -#define POBJECT_TYPE_INFORMATION struct NtObjectTypeInformation* -#define _OBJECT_NAME_INFORMATION NtObjectNameInformation -#define OBJECT_NAME_INFORMATION struct NtObjectNameInformation -#define POBJECT_NAME_INFORMATION struct NtObjectNameInformation* -#define _OBJECT_BASIC_INFORMATION NtObjectBasicInformation -#define OBJECT_BASIC_INFORMATION struct NtObjectBasicInformation -#define POBJECT_BASIC_INFORMATION struct NtObjectBasicInformation* -#define _FILE_ACCESS_INFORMATION NtFileAccessInformation -#define FILE_ACCESS_INFORMATION struct NtFileAccessInformation -#define PFILE_ACCESS_INFORMATION struct NtFileAccessInformation* -#define _FILE_ALIGNMENT_INFORMATION NtFileAlignmentInformation -#define FILE_ALIGNMENT_INFORMATION struct NtFileAlignmentInformation -#define PFILE_ALIGNMENT_INFORMATION struct NtFileAlignmentInformation* -#define _FILE_ALL_INFORMATION NtFileAllInformation -#define FILE_ALL_INFORMATION struct NtFileAllInformation -#define PFILE_ALL_INFORMATION struct NtFileAllInformation* -#define _FILE_ALLOCATION_INFORMATION NtFileAllocationInformation -#define FILE_ALLOCATION_INFORMATION struct NtFileAllocationInformation -#define PFILE_ALLOCATION_INFORMATION struct NtFileAllocationInformation* -#define _FILE_BASIC_INFORMATION NtFileBasicInformation -#define FILE_BASIC_INFORMATION struct NtFileBasicInformation -#define PFILE_BASIC_INFORMATION struct NtFileBasicInformation* -#define _FILE_BOTH_DIR_INFORMATION NtFileBothDirectoryInformation -#define FILE_BOTH_DIR_INFORMATION struct NtFileBothDirectoryInformation -#define PFILE_BOTH_DIR_INFORMATION struct NtFileBothDirectoryInformation* -#define _FILE_BOTH_DIRECTORY_INFORMATION NtFileBothDirectoryInformation -#define FILE_BOTH_DIRECTORY_INFORMATION struct NtFileBothDirectoryInformation -#define PFILE_BOTH_DIRECTORY_INFORMATION struct NtFileBothDirectoryInformation* -#define _FILE_DIRECTORY_INFORMATION NtFileDirectoryInformation -#define FILE_DIRECTORY_INFORMATION struct NtFileDirectoryInformation -#define PFILE_DIRECTORY_INFORMATION struct NtFileDirectoryInformation* -#define _FILE_DISPOSITION_INFORMATION NtFileDispositionInformation -#define FILE_DISPOSITION_INFORMATION struct NtFileDispositionInformation -#define PFILE_DISPOSITION_INFORMATION struct NtFileDispositionInformation* -#define _FILE_EA_INFORMATION NtFileEaInformation -#define FILE_EA_INFORMATION struct NtFileEaInformation -#define PFILE_EA_INFORMATION struct NtFileEaInformation* -#define _FILE_INTERNAL_INFORMATION NtFileInternalInformation -#define FILE_INTERNAL_INFORMATION struct NtFileInternalInformation -#define PFILE_INTERNAL_INFORMATION struct NtFileInternalInformation* -#define _FILE_MODE_INFORMATION NtFileModeInformation -#define FILE_MODE_INFORMATION struct NtFileModeInformation -#define PFILE_MODE_INFORMATION struct NtFileModeInformation* -#define _FILE_NAME_INFORMATION NtFileNameInformation -#define FILE_NAME_INFORMATION struct NtFileNameInformation -#define PFILE_NAME_INFORMATION struct NtFileNameInformation* -#define _FILE_NAMES_INFORMATION NtFileNamesInformation -#define FILE_NAMES_INFORMATION struct NtFileNamesInformation -#define PFILE_NAMES_INFORMATION struct NtFileNamesInformation* -#define _FILE_POSITION_INFORMATION NtFilePositionInformation -#define FILE_POSITION_INFORMATION struct NtFilePositionInformation -#define PFILE_POSITION_INFORMATION struct NtFilePositionInformation* -#define _FILE_RENAME_INFORMATION NtFileRenameInformation -#define FILE_RENAME_INFORMATION struct NtFileRenameInformation -#define PFILE_RENAME_INFORMATION struct NtFileRenameInformation* -#define _FILE_STANDARD_INFORMATION NtFileStandardInformation -#define FILE_STANDARD_INFORMATION struct NtFileStandardInformation -#define PFILE_STANDARD_INFORMATION struct NtFileStandardInformation* -#define _FILE_STREAM_INFORMATION NtFileStreamInformation -#define FILE_STREAM_INFORMATION struct NtFileStreamInformation -#define PFILE_STREAM_INFORMATION struct NtFileStreamInformation* -#define _KERNEL_USER_TIMES NtKernelUserTimes -#define KERNEL_USER_TIMES struct NtKernelUserTimes -#define PKERNEL_USER_TIMES struct NtKernelUserTimes* -#define _PROCESS_BASIC_INFORMATION NtProcessBasicInformation -#define PROCESS_BASIC_INFORMATION struct NtProcessBasicInformation -#define PPROCESS_BASIC_INFORMATION struct NtProcessBasicInformation* -#define _SYSTEM_BASIC_INFORMATION NtSystemBasicInformation -#define SYSTEM_BASIC_INFORMATION struct NtSystemBasicInformation -#define PSYSTEM_BASIC_INFORMATION struct NtSystemBasicInformation* -#define _SYSTEM_EXCEPTION_INFORMATION NtSystemExceptionInformation -#define SYSTEM_EXCEPTION_INFORMATION struct NtSystemExceptionInformation -#define PSYSTEM_EXCEPTION_INFORMATION struct NtSystemExceptionInformation* -#define _SYSTEM_HANDLE_ENTRY NtSystemHandleEntry -#define SYSTEM_HANDLE_ENTRY struct NtSystemHandleEntry -#define PSYSTEM_HANDLE_ENTRY struct NtSystemHandleEntry* -#define _SYSTEM_HANDLE_INFORMATION NtSystemHandleInformation -#define SYSTEM_HANDLE_INFORMATION struct NtSystemHandleInformation -#define PSYSTEM_HANDLE_INFORMATION struct NtSystemHandleInformation* -#define _SYSTEM_INTERRUPT_INFORMATION NtSystemInterruptInformation -#define SYSTEM_INTERRUPT_INFORMATION struct NtSystemInterruptInformation -#define PSYSTEM_INTERRUPT_INFORMATION struct NtSystemInterruptInformation* -#define _SYSTEM_LOOKASIDE_INFORMATION NtSystemLookasideInformation -#define SYSTEM_LOOKASIDE_INFORMATION struct NtSystemLookasideInformation -#define PSYSTEM_LOOKASIDE_INFORMATION struct NtSystemLookasideInformation* -#define _SYSTEM_PERFORMANCE_INFORMATION NtSystemPerformanceInformation -#define SYSTEM_PERFORMANCE_INFORMATION struct NtSystemPerformanceInformation -#define PSYSTEM_PERFORMANCE_INFORMATION struct NtSystemPerformanceInformation* -#define _SYSTEM_PROCESS_INFORMATION NtSystemProcessInformation -#define SYSTEM_PROCESS_INFORMATION struct NtSystemProcessInformation -#define PSYSTEM_PROCESS_INFORMATION struct NtSystemProcessInformation* -#define _SYSTEM_PROCESSOR_INFORMATION NtSystemProcessorInformation -#define SYSTEM_PROCESSOR_INFORMATION struct NtSystemProcessorInformation -#define PSYSTEM_PROCESSOR_INFORMATION struct NtSystemProcessorInformation* -#define _SYSTEM_TIMEOFDAY_INFORMATION NtSystemTimeofdayInformation -#define SYSTEM_TIMEOFDAY_INFORMATION struct NtSystemTimeofdayInformation -#define PSYSTEM_TIMEOFDAY_INFORMATION struct NtSystemTimeofdayInformation* - -#define _SYSTEM_REGISTRY_QUOTA_INFORMATION NtSystemRegistryQuotaInformation -#define SYSTEM_REGISTRY_QUOTA_INFORMATION \ - struct NtSystemRegistryQuotaInformation -#define PSYSTEM_REGISTRY_QUOTA_INFORMATION \ - struct NtSystemRegistryQuotaInformation* -#define _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION \ - NtSystemProcessorPerformanceInformation -#define SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION \ - struct NtSystemProcessorPerformanceInformation -#define PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION \ - struct NtSystemProcessorPerformanceInformation* -#define _FILE_FULL_DIR_INFORMATION NtFileFullDirectoryInformation -#define FILE_FULL_DIR_INFORMATION struct NtFileFullDirectoryInformation -#define PFILE_FULL_DIR_INFORMATION struct NtFileFullDirectoryInformation* -#define _FILE_FULL_DIRECTORY_INFORMATION NtFileFullDirectoryInformation -#define FILE_FULL_DIRECTORY_INFORMATION struct NtFileFullDirectoryInformation -#define PFILE_FULL_DIRECTORY_INFORMATION struct NtFileFullDirectoryInformation* -#define _FILE_ATTRIBUTE_TAG_INFORMATION NtFileAttributeTagInformation -#define FILE_ATTRIBUTE_TAG_INFORMATION struct NtFileAttributeTagInformation -#define PFILE_ATTRIBUTE_TAG_INFORMATION struct NtFileAttributeTagInformation* -#define _FILE_PIPE_LOCAL_INFORMATION NtFilePipeLocalInformation -#define FILE_PIPE_LOCAL_INFORMATION struct NtFilePipeLocalInformation -#define PFILE_PIPE_LOCAL_INFORMATION struct NtFilePipeLocalInformation* -#define _FILE_NETWORK_OPEN_INFORMATION NtFileNetworkOpenInformation -#define FILE_NETWORK_OPEN_INFORMATION struct NtFileNetworkOpenInformation -#define PFILE_NETWORK_OPEN_INFORMATION struct NtFileNetworkOpenInformation* -#define _FILE_MAILSLOT_QUERY_INFORMATION NtFileMailslotQueryInformation -#define FILE_MAILSLOT_QUERY_INFORMATION struct NtFileMailslotQueryInformation -#define PFILE_MAILSLOT_QUERY_INFORMATION struct NtFileMailslotQueryInformation* -#define _FILE_MAILSLOT_SET_INFORMATION NtFileMailslotSetInformation -#define FILE_MAILSLOT_SET_INFORMATION struct NtFileMailslotSetInformation -#define PFILE_MAILSLOT_SET_INFORMATION struct NtFileMailslotSetInformation* -#define _FILE_FULL_EA_INFORMATION NtFileFullEaInformation -#define FILE_FULL_EA_INFORMATION struct NtFileFullEaInformation -#define PFILE_FULL_EA_INFORMATION struct NtFileFullEaInformation* -#define _PDH_FMT_COUNTERVALUE NtPdhFmtCountervalue -#define PDH_FMT_COUNTERVALUE struct NtPdhFmtCountervalue -#define PPDH_FMT_COUNTERVALUE struct NtPdhFmtCountervalue* - -#define _LUID NtLuid -#define LUID struct NtLuid -#define PLUID struct NtLuid* - -#define _LUID_AND_ATTRIBUTES NtLuidAndAttributes -#define LUID_AND_ATTRIBUTES struct NtLuidAndAttributes -#define PLUID_AND_ATTRIBUTES struct NtLuidAndAttributes* - -#define _PRIVILEGE_SET NtPrivilegeSet -#define PRIVILEGE_SET struct NtPrivilegeSet -#define PPRIVILEGE_SET struct NtPrivilegeSet* - -#define _IMAGE_FILE_HEADER NtImageFileHeader -#define IMAGE_FILE_HEADER struct NtImageFileHeader -#define PIMAGE_FILE_HEADER struct NtImageFileHeader* - -#define _IMAGE_DOS_HEADER NtImageDosHeader -#define IMAGE_DOS_HEADER struct NtImageDosHeader -#define PIMAGE_DOS_HEADER struct NtImageDosHeader* - -#define _BY_HANDLE_FILE_INFORMATION NtByHandleFileInformation -#define BY_HANDLE_FILE_INFORMATION struct NtByHandleFileInformation -#define PBY_HANDLE_FILE_INFORMATION struct NtByHandleFileInformation* -#define LPBY_HANDLE_FILE_INFORMATION struct NtByHandleFileInformation* - -#define _WIN32_FILE_ATTRIBUTE_DATA NtWin32FileAttributeData -#define WIN32_FILE_ATTRIBUTE_DATA struct NtWin32FileAttributeData -#define LPWIN32_FILE_ATTRIBUTE_DATA struct NtWin32FileAttributeData* - -#define _FILE_END_OF_FILE_INFORMATION FileEndOfFileInformation -#define FILE_END_OF_FILE_INFORMATION struct FileEndOfFileInformation -#define PFILE_END_OF_FILE_INFORMATION struct FileEndOfFileInformation* - -#define _GET_FILEEX_INFO_LEVELS NtGetFileexInfoLevels -#define GET_FILEEX_INFO_LEVELS int -#define LPGET_FILEEX_INFO_LEVELS int* - -#define _WIN32_FIND_DATA NtWin32FindData -#define WIN32_FIND_DATA struct NtWin32FindData -#define LPWIN32_FIND_DATA struct NtWin32FindData* - -#define _FINDEX_INFO_LEVELS NtFindexInfoLevels -#define FINDEX_INFO_LEVELS int -#define FindExInfoStandard kNtFindExInfoStandard -#define FindExInfoBasic kNtFindExInfoBasic -#define FindExInfoMaxInfoLevel kNtFindExInfoMaxInfoLevel -#define FIND_FIRST_EX_CASE_SENSITIVE kNtFindFirstExCaseSensitive -#define FIND_FIRST_EX_LARGE_FETCH kNtFindFirstExLargeFetch -#define _FINDEX_SEARCH_OPS NtFindexSearchOps -#define FINDEX_SEARCH_OPS int -#define FindExSearchNameMatch kNtFindExSearchNameMatch -#define FindExSearchLimitToDirectories kNtFindExSearchLimitToDirectories -#define FindExSearchLimitToDevices kNtFindExSearchLimitToDevices -#define FindExSearchMaxSearchOp kNtFindExSearchMaxSearchOp - -#define GetFileExInfoStandard kNtGetFileExInfoStandard -#define GetFileExMaxInfoLevel kNtGetFile_MAX - -#define MOVEFILE_REPLACE_EXISTING kNtMovefileReplaceExisting -#define MOVEFILE_COPY_ALLOWED kNtMovefileCopyAllowed -#define MOVEFILE_DELAY_UNTIL_REBOOT kNtMovefileDelayUntilReboot -#define MOVEFILE_CREATE_HARDLINK kNtMovefileCreateHardlink -#define MOVEFILE_FAIL_IF_NOT_TRACKABLE kNtMovefileFailIfNotTrackable -#define MOVEFILE_WRITE_THROUGH kNtMovefileWriteThrough - -#define OFFER_PRIORITY int -#define VmOfferPriorityVeryLow kNtVmOfferPriorityVeryLow -#define VmOfferPriorityLow kNtVmOfferPriorityLow -#define VmOfferPriorityBelowNormal kNtVmOfferPriorityBelowNormal -#define VmOfferPriorityNormal kNtVmOfferPriorityNormal - -#define _KWAIT_REASON uint32_t -#define KWAIT_REASON uint32_t -#define _OBJECT_INFORMATION_CLASS NtObjectInformationClass -#define OBJECT_INFORMATION_CLASS int -#define _PROCESSINFOCLASS NtProcessinfoclass -#define PROCESSINFOCLASS int -#define _THREAD_STATE NtThreadState -#define THREAD_STATE int -#define _TOKEN_TYPE NtTokenType -#define TOKEN_TYPE int - -#define _THREADINFOCLASS Nthreadinfoclass -#define THREADINFOCLASS int - -#define _THREAD_INFORMATION_CLASS NtThreadInformationClass -#define THREAD_INFORMATION_CLASS int -#define PTHREAD_INFORMATION_CLASS int* - -#define OWNER_SECURITY_INFORMATION kNtOwnerSecurityInformation -#define GROUP_SECURITY_INFORMATION kNtGroupSecurityInformation -#define DACL_SECURITY_INFORMATION kNtDaclSecurityInformation -#define SACL_SECURITY_INFORMATION kNtSaclSecurityInformation -#define LABEL_SECURITY_INFORMATION kNtLabelSecurityInformation -#define ATTRIBUTE_SECURITY_INFORMATION kNtAttributeSecurityInformation -#define SCOPE_SECURITY_INFORMATION kNtScopeSecurityInformation -#define PROCESS_TRUST_LABEL_SECURITY_INFORMATION \ - kNtProcessTrustLabelSecurityInformation -#define ACCESS_FILTER_SECURITY_INFORMATION kNtAccessFilterSecurityInformation -#define BACKUP_SECURITY_INFORMATION kNtBackupSecurityInformation -#define PROTECTED_DACL_SECURITY_INFORMATION kNtProtectedDaclSecurityInformation -#define PROTECTED_SACL_SECURITY_INFORMATION kNtProtectedSaclSecurityInformation -#define UNPROTECTED_DACL_SECURITY_INFORMATION \ - kNtUnprotectedDaclSecurityInformation -#define UNPROTECTED_SACL_SECURITY_INFORMATION \ - kNtUnprotectedSaclSecurityInformation - -#define STARTF_USESHOWWINDOW kNtNtStartfUseshowwindow -#define STARTF_USESIZE kNtNtStartfUsesize -#define STARTF_USEPOSITION kNtNtStartfUseposition -#define STARTF_USECOUNTCHARS kNtNtStartfUsecountchars -#define STARTF_USEFILLATTRIBUTE kNtNtStartfUsefillattribute -#define STARTF_RUNFULLSCREEN kNtNtStartfRunfullscreen -#define STARTF_FORCEONFEEDBACK kNtNtStartfForceonfeedback -#define STARTF_FORCEOFFFEEDBACK kNtNtStartfForceofffeedback -#define STARTF_USESTDHANDLES kNtNtStartfUsestdhandles -#define STARTF_USEHOTKEY kNtNtStartfUsehotkey -#define STARTF_TITLEISLINKNAME kNtNtStartfTitleislinkname -#define STARTF_TITLEISAPPID kNtNtStartfTitleisappid -#define STARTF_PREVENTPINNING kNtNtStartfPreventpinning -#define STARTF_UNTRUSTEDSOURCE kNtNtStartfUntrustedsource - -#define MEM_COMMIT kNtMemCommit -#define MEM_RESERVE kNtMemReserve -#define MEM_DECOMMIT kNtMemDecommit -#define MEM_RELEASE kNtMemRelease -#define MEM_FREE kNtMemFree -#define MEM_PRIVATE kNtMemPrivate -#define MEM_MAPPED kNtMemMapped -#define MEM_RESET kNtMemReset -#define MEM_TOP_DOWN kNtMemTopDown -#define MEM_WRITE_WATCH kNtMemWriteWatch -#define MEM_PHYSICAL kNtMemPhysical -#define MEM_LARGE_PAGES kNtMemLargePages -#define MEM_4MB_PAGES kNtMem4mbPages -#define PAGE_NOACCESS kNtPageNoaccess -#define PAGE_READONLY kNtPageReadonly -#define PAGE_READWRITE kNtPageReadwrite -#define PAGE_WRITECOPY kNtPageWritecopy -#define PAGE_EXECUTE kNtPageExecute -#define PAGE_EXECUTE_READ kNtPageExecuteRead -#define PAGE_EXECUTE_READWRITE kNtPageExecuteReadwrite -#define PAGE_EXECUTE_WRITECOPY kNtPageExecuteWritecopy -#define PAGE_GUARD kNtPageGuard -#define PAGE_NOCACHE kNtPageNocache -#define PAGE_WRITECOMBINE kNtPageWritecombine -#define FILE_MAP_COPY kNtFileMapCopy -#define FILE_MAP_WRITE kNtFileMapWrite -#define FILE_MAP_READ kNtFileMapRead -#define FILE_MAP_EXECUTE kNtFileMapExecute -#define FILE_MAP_RESERVE kNtFileMapReserve -#define FILE_MAP_TARGETS_INVALID kNtFileMapTargetsInvalid -#define FILE_MAP_LARGE_PAGES kNtFileMapLargePages - -#define SECTION_QUERY kNtSectionQuery -#define SECTION_MAP_WRITE kNtSectionMapWrite -#define SECTION_MAP_READ kNtSectionMapRead -#define SECTION_MAP_EXECUTE kNtSectionMapExecute -#define SECTION_EXTEND_SIZE kNtSectionExtendSize -#define SECTION_MAP_EXECUTE_EXPLICIT kNtSectionMapExecuteExplicit - -#define CTRL_CEVENT kNtCtrlCEvent -#define CTRL_BREAK_EVENT kNtCtrlBreakEvent -#define CTRL_CLOSE_EVENT kNtCtrlCloseEvent -#define CTRL_LOGOFF_EVENT kNtCtrlLogoffEvent -#define CTRL_SHUTDOWN_EVENT kNtCtrlShutdownEvent - -#define FILE_ATTRIBUTE_NORMAL kNtFileAttributeNormal -#define FILE_ATTRIBUTE_HIDDEN kNtFileAttributeHidden -#define FILE_FLAG_WRITE_THROUGH kNtFileFlagWriteThrough -#define FILE_FLAG_OVERLAPPED kNtFileFlagOverlapped -#define FILE_FLAG_NO_BUFFERING kNtFileFlagNoBuffering -#define FILE_FLAG_RANDOM_ACCESS kNtFileFlagRandomAccess -#define FILE_FLAG_SEQUENTIAL_SCAN kNtFileFlagSequentialScan -#define FILE_FLAG_DELETE_ON_CLOSE kNtFileFlagDeleteOnClose -#define FILE_FLAG_BACKUP_SEMANTICS kNtFileFlagBackupSemantics -#define FILE_FLAG_POSIX_SEMANTICS kNtFileFlagPosixSemantics -#define FILE_FLAG_OPEN_REPARSE_POINT kNtFileFlagOpenReparsePoint -#define FILE_FLAG_OPEN_NO_RECALL kNtFileFlagOpenNoRecall -#define FILE_FLAG_FIRST_PIPE_INSTANCE kNtFileFlagFirstPipeInstance -#define FILE_LIST_DIRECTORY kNtFileListDirectory -#define FILE_ATTRIBUTE_ARCHIVE kNtFileAttributeArchive -#define FILE_ATTRIBUTE_COMPRESSED kNtFileAttributeCompressed -#define FILE_ATTRIBUTE_DEVICE kNtFileAttributeDevice -#define FILE_ATTRIBUTE_DIRECTORY kNtFileAttributeDirectory -#define FILE_ATTRIBUTE_ENCRYPTED kNtFileAttributeEncrypted -#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED kNtFileAttributeNotContentIndexed -#define FILE_ATTRIBUTE_OFFLINE kNtFileAttributeOffline -#define FILE_ATTRIBUTE_READONLY kNtFileAttributeReadonly -#define FILE_ATTRIBUTE_REPARSE_POINT kNtFileAttributeReparsePoint -#define FILE_ATTRIBUTE_SPARSE_FILE kNtFileAttributeSparseFile -#define FILE_ATTRIBUTE_SYSTEM kNtFileAttributeSystem -#define FILE_ATTRIBUTE_TEMPORARY kNtFileAttributeTemporary - -#define CREATE_NEW kNtCreateNew -#define CREATE_ALWAYS kNtCreateAlways -#define OPEN_EXISTING kNtOpenExisting -#define OPEN_ALWAYS kNtOpenAlways -#define TRUNCATE_EXISTING kNtTruncateExisting -#define FILE_SHARE_EXCLUSIVE kNtFileShareExclusive -#define FILE_SHARE_READ kNtFileShareRead -#define FILE_SHARE_WRITE kNtFileShareWrite -#define FILE_SHARE_DELETE kNtFileShareDelete - -#define INVALID_HANDLE_VALUE kNtInvalidHandleValue -#define STD_INPUT_HANDLE kNtStdInputHandle -#define STD_OUTPUT_HANDLE kNtStdOutputHandle -#define STD_ERROR_HANDLE kNtStdErrorHandle - -#define CONSOLE_NO_SELECTION kNtConsoleNoSelection -#define CONSOLE_SELECTION_IN_PROGRESS kNtConsoleSelectionInProgress -#define CONSOLE_SELECTION_NOT_EMPTY kNtConsoleSelectionNotEmpty -#define CONSOLE_MOUSE_SELECTION kNtConsoleMouseSelection -#define CONSOLE_MOUSE_DOWN kNtConsoleMouseDown - -#define MB_OK kNtMbOk -#define MB_OKCANCEL kNtMbOkcancel -#define MB_ABORTRETRYIGNORE kNtMbAbortretryignore -#define MB_YESNOCANCEL kNtMbYesnocancel -#define MB_YESNO kNtMbYesno -#define MB_RETRYCANCEL kNtMbRetrycancel -#define MB_CANCELTRYCONTINUE kNtMbCanceltrycontinue -#define MB_ICONHAND kNtMbIconhand -#define MB_ICONQUESTION kNtMbIconquestion -#define MB_ICONEXCLAMATION kNtMbIconexclamation -#define MB_ICONASTERISK kNtMbIconasterisk -#define MB_USERICON kNtMbUsericon -#define MB_ICONWARNING kNtMbIconwarning -#define MB_ICONERROR kNtMbIconerror -#define MB_ICONINFORMATION kNtMbIconinformation -#define MB_ICONSTOP kNtMbIconstop -#define MB_DEFBUTTON1 kNtMbDefbutton1 -#define MB_DEFBUTTON2 kNtMbDefbutton2 -#define MB_DEFBUTTON3 kNtMbDefbutton3 -#define MB_DEFBUTTON4 kNtMbDefbutton4 -#define MB_APPLMODAL kNtMbApplmodal -#define MB_SYSTEMMODAL kNtMbSystemmodal -#define MB_TASKMODAL kNtMbTaskmodal -#define MB_HELP kNtMbHelp -#define MB_NOFOCUS kNtMbNofocus -#define MB_SETFOREGROUND kNtMbSetforeground -#define MB_DEFAULT_DESKTOP_ONLY kNtMbDefaultDesktopOnly -#define MB_TOPMOST kNtMbTopmost -#define MB_RIGHT kNtMbRight -#define MB_RTLREADING kNtMbRtlreading -#define MB_SERVICE_NOTIFICATION kNtMbServiceNotification -#define MB_SERVICE_NOTIFICATION_NT3X kNtMbServiceNotificationNt3x -#define MB_TYPEMASK kNtMbTypemask -#define MB_ICONMASK kNtMbIconmask -#define MB_DEFMASK kNtMbDefmask -#define MB_MODEMASK kNtMbModemask -#define MB_MISCMASK kNtMbMiscmask - -#define IDOK kNtIdok -#define IDCANCEL kNtIdcancel -#define IDABORT kNtIdabort -#define IDRETRY kNtIdretry -#define IDIGNORE kNtIdignore -#define IDYES kNtIdyes -#define IDNO kNtIdno -#define IDCLOSE kNtIdclose -#define IDHELP kNtIdhelp -#define IDTRYAGAIN kNtIdtryagain -#define IDCONTINUE kNtIdcontinue - -#define PROCESS_TERMINATE kNtProcessTerminate -#define PROCESS_CREATE_THREAD kNtProcessCreateThread -#define PROCESS_SET_SESSIONID kNtProcessSetSessionid -#define PROCESS_VM_OPERATION kNtProcessVmOperation -#define PROCESS_VM_READ kNtProcessVmRead -#define PROCESS_VM_WRITE kNtProcessVmWrite -#define PROCESS_DUP_HANDLE kNtProcessDupHandle -#define PROCESS_CREATE_PROCESS kNtProcessCreateProcess -#define PROCESS_SET_QUOTA kNtProcessSetQuota -#define PROCESS_SET_INFORMATION kNtProcessSetInformation -#define PROCESS_QUERY_INFORMATION kNtProcessQueryInformation -#define PROCESS_SUSPEND_RESUME kNtProcessSuspendResume -#define PROCESS_QUERY_LIMITED_INFORMATION kNtProcessQueryLimitedInformation -#define PROCESS_SET_LIMITED_INFORMATION kNtProcessSetLimitedInformation -#define PROCESS_ALL_ACCESS kNtProcessAllAccess - -#define GENERIC_READ kNtGenericRead -#define GENERIC_WRITE kNtGenericWrite -#define GENERIC_EXECUTE kNtGenericExecute -#define GENERIC_ALL kNtGenericAll -#define DELETE kNtDelete -#define READ_CONTROL kNtReadControl -#define WRITE_DAC kNtWriteDac -#define WRITE_OWNER kNtWriteOwner -#define SYNCHRONIZE kNtSynchronize -#define STANDARD_RIGHTS_REQUIRED kNtStandardRightsRequired -#define STANDARD_RIGHTS_READ kNtStandardRightsRead -#define STANDARD_RIGHTS_WRITE kNtStandardRightsWrite -#define STANDARD_RIGHTS_EXECUTE kNtStandardRightsExecute -#define STANDARD_RIGHTS_ALL kNtStandardRightsAll -#define SPECIFIC_RIGHTS_ALL kNtSpecificRightsAll -#define ACCESS_SYSTEM_SECURITY kNtAccessSystemSecurity -#define MAXIMUM_ALLOWED kNtMaximumAllowed -#define GENERIC_READ kNtGenericRead -#define GENERIC_WRITE kNtGenericWrite -#define GENERIC_EXECUTE kNtGenericExecute -#define GENERIC_ALL kNtGenericAll - -#define FILE_TYPE_UNKNOWN kNtFileTypeUnknown -#define FILE_TYPE_DISK kNtFileTypeDisk -#define FILE_TYPE_CHAR kNtFileTypeChar -#define FILE_TYPE_PIPE kNtFileTypePipe -#define FILE_TYPE_REMOTE kNtFileTypeRemote - -#define NT_DEBUG_PROCESS kNtDebugProcess -#define NT_DEBUG_ONLY_THIS_PROCESS kNtDebugOnlyThisProcess -#define NT_CREATE_SUSPENDED kNtCreateSuspended -#define NT_DETACHED_PROCESS kNtDetachedProcess -#define NT_CREATE_NEW_CONSOLE kNtCreateNewConsole -#define NT_NORMAL_PRIORITY_CLASS kNtNormalPriorityClass -#define NT_IDLE_PRIORITY_CLASS kNtIdlePriorityClass -#define NT_HIGH_PRIORITY_CLASS kNtHighPriorityClass -#define NT_REALTIME_PRIORITY_CLASS kNtRealtimePriorityClass -#define NT_CREATE_NEW_PROCESS_GROUP kNtCreateNewProcessGroup -#define NT_CREATE_UNICODE_ENVIRONMENT kNtCreateUnicodeEnvironment -#define NT_CREATE_SEPARATE_WOW_VDM kNtCreateSeparateWowVdm -#define NT_CREATE_SHARED_WOW_VDM kNtCreateSharedWowVdm -#define NT_CREATE_FORCEDOS kNtCreateForcedos -#define NT_BELOW_NORMAL_PRIORITY_CLASS kNtBelowNormalPriorityClass -#define NT_ABOVE_NORMAL_PRIORITY_CLASS kNtAboveNormalPriorityClass -#define NT_INHERIT_PARENT_AFFINITY kNtInheritParentAffinity -#define NT_CREATE_PROTECTED_PROCESS kNtCreateProtectedProcess -#define NT_EXTENDED_STARTUPINFO_PRESENT kNtExtendedStartupinfoPresent -#define NT_PROCESS_MODE_BACKGROUND_BEGIN kNtProcessModeBackgroundBegin -#define NT_PROCESS_MODE_BACKGROUND_END kNtProcessModeBackgroundEnd -#define NT_CREATE_SECURE_PROCESS kNtCreateSecureProcess -#define NT_CREATE_BREAKAWAY_FROM_JOB kNtCreateBreakawayFromJob -#define NT_CREATE_PRESERVE_CODE_AUTHZ_LEVEL kNtCreatePreserveCodeAuthzLevel -#define NT_CREATE_DEFAULT_ERROR_MODE kNtCreateDefaultErrorMode -#define NT_CREATE_NO_WINDOW kNtCreateNoWindow -#define NT_PROFILE_USER kNtProfileUser -#define NT_PROFILE_KERNEL kNtProfileKernel -#define NT_PROFILE_SERVER kNtProfileServer -#define NT_CREATE_IGNORE_SYSTEM_DEFAULT kNtCreateIgnoreSystemDefault - -#define FILE_READ_DATA kNtFileReadData -#define FILE_WRITE_DATA kNtFileWriteData -#define FILE_ADD_FILE kNtFileAddFile -#define FILE_APPEND_DATA kNtFileAppendData -#define FILE_ADD_SUBDIRECTORY kNtFileAddSubdirectory -#define FILE_CREATE_PIPE_INSTANCE kNtFileCreatePipeInstance -#define FILE_READ_EA kNtFileReadEa -#define FILE_WRITE_EA kNtFileWriteEa -#define FILE_EXECUTE kNtFileExecute -#define FILE_TRAVERSE kNtFileTraverse -#define FILE_DELETE_CHILD kNtFileDeleteChild -#define FILE_READ_ATTRIBUTES kNtFileReadAttributes -#define FILE_WRITE_ATTRIBUTES kNtFileWriteAttributes -#define FILE_ALL_ACCESS kNtFileAllAccess -#define FILE_GENERIC_READ kNtFileGenericRead -#define FILE_GENERIC_WRITE kNtFileGenericWrite -#define FILE_GENERIC_EXECUTE kNtFileGenericExecute - -#define TOKEN_PRIMARY kNtTokenPrimary -#define TOKEN_IMPERSONATION kNtTokenImpersonation - -#define TOKEN_PRIMARY kNtTokenPrimary -#define TOKEN_IMPERSONATION kNtTokenImpersonation -#define SECURITY_ANONYMOUS kNtSecurityAnonymous -#define SECURITY_IDENTIFICATION kNtSecurityIdentification -#define SECURITY_IMPERSONATION kNtSecurityImpersonation -#define SECURITY_DELEGATION kNtSecurityDelegation - -#define TOKEN_DUPLICATE kNtTokenDuplicate -#define TOKEN_IMPERSONATE kNtTokenImpersonate -#define TOKEN_QUERY kNtTokenQuery -#define TOKEN_QUERY_SOURCE kNtTokenQuerySource -#define TOKEN_ADJUST_PRIVILEGES kNtTokenAdjustPrivileges -#define TOKEN_ADJUST_GROUPS kNtTokenAdjustGroups -#define TOKEN_ADJUST_DEFAULT kNtTokenAdjustDefault -#define TOKEN_ADJUST_SESSIONID kNtTokenAdjustSessionid -#define TOKEN_ALL_ACCESS_P kNtTokenAllAccessP -#define TOKEN_ALL_ACCESS kNtTokenAllAccess -#define TOKEN_READ kNtTokenRead -#define TOKEN_WRITE kNtTokenWrite -#define TOKEN_EXECUTE kNtTokenExecute -#define TOKEN_TRUST_CONSTRAINT_MASK kNtTokenTrustConstraintMask -#define TOKEN_ACCESS_PSEUDO_HANDLE_WIN8 kNtTokenAccessPseudoHandleWin8 -#define TOKEN_ACCESS_PSEUDO_HANDLE kNtTokenAccessPseudoHandle - -#define FOREGROUND_BLUE kNtForegroundBlue -#define FOREGROUND_GREEN kNtForegroundGreen -#define FOREGROUND_RED kNtForegroundRed -#define FOREGROUND_INTENSITY kNtForegroundIntensity -#define BACKGROUND_BLUE kNtBackgroundBlue -#define BACKGROUND_GREEN kNtBackgroundGreen -#define BACKGROUND_RED kNtBackgroundRed -#define BACKGROUND_INTENSITY kNtBackgroundIntensity - -#define UNLEN 256 - -#define DUPLICATE_CLOSE_SOURCE kNtDuplicateCloseSource -#define DUPLICATE_SAME_ACCESS kNtDuplicateSameAccess - -#define IMAGE_FILE_MACHINE_UNKNOWN kNtImageFileMachineUnknown -#define IMAGE_FILE_MACHINE_TARGET_HOST kNtImageFileMachineTargetHost -#define IMAGE_FILE_MACHINE_I386 kNtImageFileMachineI386 -#define IMAGE_FILE_MACHINE_R3000 kNtImageFileMachineR3000 -#define IMAGE_FILE_MACHINE_R4000 kNtImageFileMachineR4000 -#define IMAGE_FILE_MACHINE_R10000 kNtImageFileMachineR10000 -#define IMAGE_FILE_MACHINE_WCEMIPSV2 kNtImageFileMachineWcemipsv2 -#define IMAGE_FILE_MACHINE_ALPHA kNtImageFileMachineAlpha -#define IMAGE_FILE_MACHINE_SH3 kNtImageFileMachineSh3 -#define IMAGE_FILE_MACHINE_SH3DSP kNtImageFileMachineSh3dsp -#define IMAGE_FILE_MACHINE_SH3E kNtImageFileMachineSh3e -#define IMAGE_FILE_MACHINE_SH4 kNtImageFileMachineSh4 -#define IMAGE_FILE_MACHINE_SH5 kNtImageFileMachineSh5 -#define IMAGE_FILE_MACHINE_ARM kNtImageFileMachineArm -#define IMAGE_FILE_MACHINE_THUMB kNtImageFileMachineThumb -#define IMAGE_FILE_MACHINE_ARMNT kNtImageFileMachineArmnt -#define IMAGE_FILE_MACHINE_AM33 kNtImageFileMachineAm33 -#define IMAGE_FILE_MACHINE_POWERPC kNtImageFileMachinePowerpc -#define IMAGE_FILE_MACHINE_POWERPCFP kNtImageFileMachinePowerpcfp -#define IMAGE_FILE_MACHINE_IA64 kNtImageFileMachineIa64 -#define IMAGE_FILE_MACHINE_MIPS16 kNtImageFileMachineMips16 -#define IMAGE_FILE_MACHINE_ALPHA64 kNtImageFileMachineAlpha64 -#define IMAGE_FILE_MACHINE_MIPSFPU kNtImageFileMachineMipsfpu -#define IMAGE_FILE_MACHINE_MIPSFPU16 kNtImageFileMachineMipsfpu16 -#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 -#define IMAGE_FILE_MACHINE_TRICORE kNtImageFileMachineTricore -#define IMAGE_FILE_MACHINE_CEF kNtImageFileMachineCef -#define IMAGE_FILE_MACHINE_EBC kNtImageFileMachineEbc -#define IMAGE_FILE_MACHINE_NEXGEN32E kNtImageFileMachineNexgen32e -#define IMAGE_FILE_MACHINE_M32R kNtImageFileMachineM32r -#define IMAGE_FILE_MACHINE_ARM64 kNtImageFileMachineArm64 -#define IMAGE_FILE_MACHINE_CEE kNtImageFileMachineCee - -#define PE_32BIT kNtPe32bit -#define PE_64BIT kNtPe64bit - -#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA \ - kNtImageDllcharacteristicsHighEntropyVa -#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE \ - kNtImageDllcharacteristicsDynamicBase -#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY \ - kNtImageDllcharacteristicsForceIntegrity -#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT kNtImageDllcharacteristicsNxCompat -#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION \ - kNtImageDllcharacteristicsNoIsolation -#define IMAGE_DLLCHARACTERISTICS_NO_SEH kNtImageDllcharacteristicsNoSeh -#define IMAGE_DLLCHARACTERISTICS_NO_BIND kNtImageDllcharacteristicsNoBind -#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER \ - kNtImageDllcharacteristicsAppcontainer -#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER kNtImageDllcharacteristicsWdmDriver -#define IMAGE_DLLCHARACTERISTICS_GUARD_CF kNtImageDllcharacteristicsGuardCf -#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE \ - kNtImageDllcharacteristicsTerminalServerAware - -#define IMAGE_SUBSYSTEM_UNKNOWN kNtImageSubsystemUnknown -#define IMAGE_SUBSYSTEM_NATIVE kNtImageSubsystemNative -#define IMAGE_SUBSYSTEM_WINDOWS_GUI kNtImageSubsystemWindowsGui -#define IMAGE_SUBSYSTEM_WINDOWS_CUI kNtImageSubsystemWindowsCui -#define IMAGE_SUBSYSTEM_OS2_CUI kNtImageSubsystemOs2Cui -#define IMAGE_SUBSYSTEM_POSIX_CUI kNtImageSubsystemPosixCui -#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS kNtImageSubsystemNativeWindows -#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI kNtImageSubsystemWindowsCeGui -#define IMAGE_SUBSYSTEM_EFI_APPLICATION kNtImageSubsystemEfiApplication -#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER \ - kNtImageSubsystemEfiBootServiceDriver -#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER kNtImageSubsystemEfiRuntimeDriver -#define IMAGE_SUBSYSTEM_EFI_ROM kNtImageSubsystemEfiRom -#define IMAGE_SUBSYSTEM_XBOX kNtImageSubsystemXbox -#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION \ - kNtImageSubsystemWindowsBootApplication -#define IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG kNtImageSubsystemXboxCodeCatalog - -#define IMAGE_FILE_RELOCS_STRIPPED kNtImageFileRelocsStripped -#define IMAGE_FILE_EXECUTABLE_IMAGE kNtImageFileExecutableImage -#define IMAGE_FILE_LINE_NUMS_STRIPPED kNtImageFileLineNumsStripped -#define IMAGE_FILE_LOCAL_SYMS_STRIPPED kNtImageFileLocalSymsStripped -#define IMAGE_FILE_AGGRESIVE_WS_TRIM kNtImageFileAggresiveWsTrim -#define IMAGE_FILE_LARGE_ADDRESS_AWARE kNtImageFileLargeAddressAware -#define IMAGE_FILE_BYTES_REVERSED_LO kNtImageFileBytesReversedLo -#define IMAGE_FILE_32BIT_MACHINE kNtImageFile_32bitMachine -#define IMAGE_FILE_DEBUG_STRIPPED kNtImageFileDebugStripped -#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP kNtImageFileRemovableRunFromSwap -#define IMAGE_FILE_NET_RUN_FROM_SWAP kNtImageFileNetRunFromSwap -#define IMAGE_FILE_SYSTEM kNtImageFileSystem -#define IMAGE_FILE_DLL kNtImageFileDll -#define IMAGE_FILE_UP_SYSTEM_ONLY kNtImageFileUpSystemOnly -#define IMAGE_FILE_BYTES_REVERSED_HI kNtImageFileBytesReversedHi - -#define IMAGE_DOS_SIGNATURE kNtImageDosSignature -#define IMAGE_OS2_SIGNATURE kNtImageOs2Signature -#define IMAGE_OS2_SIGNATURE_LE kNtImageOs2SignatureLe -#define IMAGE_VXD_SIGNATURE kNtImageVxdSignature -#define IMAGE_NT_SIGNATURE kNtImageNtSignature - -#define RICHKEY kNtRichkey -#define COOKIE_DEFAULT kNtCookieDefault -#define SIZE_OF_80387_REGISTERS kNtSizeOf_80387Registers -#define MAXIMUM_SUPPORTED_EXTENSION kNtMaximumSupportedExtension - -#define PE_SUBSYSTEM_WINDOWS_GUI kNtPeSubsystemWindowsGui -#define PE_SUBSYSTEM_WINDOWS_CUI kNtPeSubsystemWindowsCui - -#define PE_FILE_RELOCS_STRIPPED kNtPeFileRelocsStripped -#define PE_FILE_EXECUTABLE_IMAGE kNtPeFileExecutableImage -#define PE_FILE_LINE_NUMS_STRIPPED kNtPeFileLineNumsStripped -#define PE_FILE_LOCAL_SYMS_STRIPPED kNtPeFileLocalSymsStripped -#define PE_FILE_32BIT_MACHINE kNtPeFile_32bitMachine -#define PE_FILE_DLL kNtPeFileDll - -#define PE_SECTION_CNT_CODE kNtPeSectionCntCode -#define PE_SECTION_CNT_INITIALIZED_DATA kNtPeSectionCntInitializedData -#define PE_SECTION_CNT_UNINITIALIZED_DATA kNtPeSectionCntUninitializedData -#define PE_SECTION_GPREL kNtPeSectionGprel -#define PE_SECTION_MEM_DISCARDABLE kNtPeSectionMemDiscardable -#define PE_SECTION_MEM_NOT_CACHED kNtPeSectionMemNotCached -#define PE_SECTION_MEM_NOT_PAGED kNtPeSectionMemNotPaged -#define PE_SECTION_MEM_SHARED kNtPeSectionMemShared -#define PE_SECTION_MEM_EXECUTE kNtPeSectionMemExecute -#define PE_SECTION_MEM_READ kNtPeSectionMemRead -#define PE_SECTION_MEM_WRITE kNtPeSectionMemWrite - -#define PE_GUARD_CF_INSTRUMENTED kNtPeGuardCfInstrumented -#define PE_GUARD_CFW_INSTRUMENTED kNtPeGuardCfwInstrumented -#define PE_GUARD_CF_FUNCTION_TABLE_PRESENT kNtPeGuardCfFunctionTablePresent -#define PE_GUARD_SECURITY_COOKIE_UNUSED kNtPeGuardSecurityCookieUnused - -#define PE_REL_BASED_ABSOLUTE kNtPeRelBasedAbsolute -#define PE_REL_BASED_HIGH kNtPeRelBasedHigh -#define PE_REL_BASED_LOW kNtPeRelBasedLow -#define PE_REL_BASED_HIGHLOW kNtPeRelBasedHighlow -#define PE_REL_BASED_HIGHADJ kNtPeRelBasedHighadj -#define PE_REL_BASED_MIPS_JMPADDR kNtPeRelBasedMipsJmpaddr -#define PE_REL_BASED_SECTION kNtPeRelBasedSection -#define PE_REL_BASED_REL32 kNtPeRelBasedRel32 -#define PE_REL_BASED_MIPS_JMPADDR16 kNtPeRelBasedMipsJmpaddr16 -#define PE_REL_BASED_IA64_IMM64 kNtPeRelBasedIa64Imm64 -#define PE_REL_BASED_DIR64 kNtPeRelBasedDir64 -#define PE_REL_BASED_HIGH3ADJ kNtPeRelBasedHigh3adj - -#define IMAGE_DIRECTORY_ENTRY_EXPORT kNtImageDirectoryEntryExport -#define IMAGE_DIRECTORY_ENTRY_IMPORT kNtImageDirectoryEntryImport -#define IMAGE_DIRECTORY_ENTRY_RESOURCE kNtImageDirectoryEntryResource -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION kNtImageDirectoryEntryException -#define IMAGE_DIRECTORY_ENTRY_SECURITY kNtImageDirectoryEntrySecurity -#define IMAGE_DIRECTORY_ENTRY_BASERELOC kNtImageDirectoryEntryBasereloc -#define IMAGE_DIRECTORY_ENTRY_DEBUG kNtImageDirectoryEntryDebug -#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE kNtImageDirectoryEntryArchitecture -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR kNtImageDirectoryEntryGlobalptr -#define IMAGE_DIRECTORY_ENTRY_TLS kNtImageDirectoryEntryTls -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG kNtImageDirectoryEntryLoadConfig -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT kNtImageDirectoryEntryBoundImport -#define IMAGE_DIRECTORY_ENTRY_IAT kNtImageDirectoryEntryIat -#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT kNtImageDirectoryEntryDelayImport -#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR kNtImageDirectoryEntryComDescriptor - -#define IMAGE_SCN_TYPE_NO_PAD kNtImageScnTypeNoPad -#define IMAGE_SCN_CNT_CODE kNtImageScnCntCode -#define IMAGE_SCN_CNT_INITIALIZED_DATA kNtImageScnCntInitializedData -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA kNtImageScnCntUninitializedData -#define IMAGE_SCN_LNK_OTHER kNtImageScnLnkOther -#define IMAGE_SCN_LNK_INFO kNtImageScnLnkInfo -#define IMAGE_SCN_LNK_REMOVE kNtImageScnLnkRemove -#define IMAGE_SCN_LNK_COMDAT kNtImageScnLnkComdat -#define IMAGE_SCN_NO_DEFER_SPEC_EXC kNtImageScnNoDeferSpecExc -#define IMAGE_SCN_GPREL kNtImageScnGprel -#define IMAGE_SCN_MEM_FARDATA kNtImageScnMemFardata -#define IMAGE_SCN_MEM_PURGEABLE kNtImageScnMemPurgeable -#define IMAGE_SCN_MEM_16BIT kNtImageScnMem16bit -#define IMAGE_SCN_MEM_LOCKED kNtImageScnMemLocked -#define IMAGE_SCN_MEM_PRELOAD kNtImageScnMemPreload - -#define IMAGE_SCN_ALIGN_1BYTES kNtImageScnAlign1bytes -#define IMAGE_SCN_ALIGN_2BYTES kNtImageScnAlign2bytes -#define IMAGE_SCN_ALIGN_4BYTES kNtImageScnAlign4bytes -#define IMAGE_SCN_ALIGN_8BYTES kNtImageScnAlign8bytes -#define IMAGE_SCN_ALIGN_16BYTES kNtImageScnAlign16bytes -#define IMAGE_SCN_ALIGN_32BYTES kNtImageScnAlign32bytes -#define IMAGE_SCN_ALIGN_64BYTES kNtImageScnAlign64bytes -#define IMAGE_SCN_ALIGN_128BYTES kNtImageScnAlign128bytes -#define IMAGE_SCN_ALIGN_256BYTES kNtImageScnAlign256bytes -#define IMAGE_SCN_ALIGN_512BYTES kNtImageScnAlign512bytes -#define IMAGE_SCN_ALIGN_1024BYTES kNtImageScnAlign1024bytes -#define IMAGE_SCN_ALIGN_2048BYTES kNtImageScnAlign2048bytes -#define IMAGE_SCN_ALIGN_4096BYTES kNtImageScnAlign4096bytes -#define IMAGE_SCN_ALIGN_8192BYTES kNtImageScnAlign8192bytes -#define IMAGE_SCN_ALIGN_MASK kNtImageScnAlignMask - -#define IMAGE_SCN_LNK_NRELOC_OVFL kNtImageScnLnkNrelocOvfl -#define IMAGE_SCN_MEM_DISCARDABLE kNtImageScnMemDiscardable -#define IMAGE_SCN_MEM_NOT_CACHED kNtImageScnMemNotCached -#define IMAGE_SCN_MEM_NOT_PAGED kNtImageScnMemNotPaged -#define IMAGE_SCN_MEM_SHARED kNtImageScnMemShared -#define IMAGE_SCN_MEM_EXECUTE kNtImageScnMemExecute -#define IMAGE_SCN_MEM_READ kNtImageScnMemRead -#define IMAGE_SCN_MEM_WRITE kNtImageScnMemWrite -#define IMAGE_SCN_SCALE_INDEX kNtImageScnScaleIndex - -#define IMAGE_SYM_UNDEFINED kNtImageSymUndefined -#define IMAGE_SYM_ABSOLUTE kNtImageSymAbsolute -#define IMAGE_SYM_DEBUG kNtImageSymDebug -#define IMAGE_SYM_SECTION_MAX kNtImageSymSectionMax -#define IMAGE_SYM_SECTION_MAX_EX kNtImageSymSectionMaxEx -#define IMAGE_SYM_TYPE_NULL kNtImageSymTypeNull -#define IMAGE_SYM_TYPE_VOID kNtImageSymTypeVoid -#define IMAGE_SYM_TYPE_CHAR kNtImageSymTypeChar -#define IMAGE_SYM_TYPE_SHORT kNtImageSymTypeShort -#define IMAGE_SYM_TYPE_INT kNtImageSymTypeInt -#define IMAGE_SYM_TYPE_LONG kNtImageSymTypeLong -#define IMAGE_SYM_TYPE_FLOAT kNtImageSymTypeFloat -#define IMAGE_SYM_TYPE_DOUBLE kNtImageSymTypeDouble -#define IMAGE_SYM_TYPE_STRUCT kNtImageSymTypeStruct -#define IMAGE_SYM_TYPE_UNION kNtImageSymTypeUnion -#define IMAGE_SYM_TYPE_ENUM kNtImageSymTypeEnum -#define IMAGE_SYM_TYPE_MOE kNtImageSymTypeMoe -#define IMAGE_SYM_TYPE_BYTE kNtImageSymTypeByte -#define IMAGE_SYM_TYPE_WORD kNtImageSymTypeWord -#define IMAGE_SYM_TYPE_UINT kNtImageSymTypeUint -#define IMAGE_SYM_TYPE_DWORD kNtImageSymTypeDword -#define IMAGE_SYM_TYPE_PCODE kNtImageSymTypePcode -#define IMAGE_SYM_DTYPE_NULL kNtImageSymDtypeNull -#define IMAGE_SYM_DTYPE_POINTER kNtImageSymDtypePointer -#define IMAGE_SYM_DTYPE_FUNCTION kNtImageSymDtypeFunction -#define IMAGE_SYM_DTYPE_ARRAY kNtImageSymDtypeArray -#define IMAGE_SYM_CLASS_END_OF_FUNCTION kNtImageSymClassEndOfFunction -#define IMAGE_SYM_CLASS_NULL kNtImageSymClassNull -#define IMAGE_SYM_CLASS_AUTOMATIC kNtImageSymClassAutomatic -#define IMAGE_SYM_CLASS_EXTERNAL kNtImageSymClassExternal -#define IMAGE_SYM_CLASS_STATIC kNtImageSymClassStatic -#define IMAGE_SYM_CLASS_REGISTER kNtImageSymClassRegister -#define IMAGE_SYM_CLASS_EXTERNAL_DEF kNtImageSymClassExternalDef -#define IMAGE_SYM_CLASS_LABEL kNtImageSymClassLabel -#define IMAGE_SYM_CLASS_UNDEFINED_LABEL kNtImageSymClassUndefinedLabel -#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT kNtImageSymClassMemberOfStruct -#define IMAGE_SYM_CLASS_ARGUMENT kNtImageSymClassArgument -#define IMAGE_SYM_CLASS_STRUCT_TAG kNtImageSymClassStructTag -#define IMAGE_SYM_CLASS_MEMBER_OF_UNION kNtImageSymClassMemberOfUnion -#define IMAGE_SYM_CLASS_UNION_TAG kNtImageSymClassUnionTag -#define IMAGE_SYM_CLASS_TYPE_DEFINITION kNtImageSymClassTypeDefinition -#define IMAGE_SYM_CLASS_UNDEFINED_STATIC kNtImageSymClassUndefinedStatic -#define IMAGE_SYM_CLASS_ENUM_TAG kNtImageSymClassEnumTag -#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM kNtImageSymClassMemberOfEnum -#define IMAGE_SYM_CLASS_REGISTER_PARAM kNtImageSymClassRegisterParam -#define IMAGE_SYM_CLASS_BIT_FIELD kNtImageSymClassBitField -#define IMAGE_SYM_CLASS_FAR_EXTERNAL kNtImageSymClassFarExternal -#define IMAGE_SYM_CLASS_BLOCK kNtImageSymClassBlock -#define IMAGE_SYM_CLASS_FUNCTION kNtImageSymClassFunction -#define IMAGE_SYM_CLASS_END_OF_STRUCT kNtImageSymClassEndOfStruct -#define IMAGE_SYM_CLASS_FILE kNtImageSymClassFile -#define IMAGE_SYM_CLASS_SECTION kNtImageSymClassSection -#define IMAGE_SYM_CLASS_WEAK_EXTERNAL kNtImageSymClassWeakExternal -#define IMAGE_SYM_CLASS_CLR_TOKEN kNtImageSymClassClrToken - -#define IMAGE_COMDAT_SELECT_NODUPLICATES kNtImageComdatSelectNoduplicates -#define IMAGE_COMDAT_SELECT_ANY kNtImageComdatSelectAny -#define IMAGE_COMDAT_SELECT_SAME_SIZE kNtImageComdatSelectSameSize -#define IMAGE_COMDAT_SELECT_EXACT_MATCH kNtImageComdatSelectExactMatch -#define IMAGE_COMDAT_SELECT_ASSOCIATIVE kNtImageComdatSelectAssociative -#define IMAGE_COMDAT_SELECT_LARGEST kNtImageComdatSelectLargest -#define IMAGE_COMDAT_SELECT_NEWEST kNtImageComdatSelectNewest - -#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY kNtImageWeakExternSearchNolibrary -#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY kNtImageWeakExternSearchLibrary -#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS kNtImageWeakExternSearchAlias -#define IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY kNtImageWeakExternAntiDependency - -#define IMAGE_REL_NEXGEN32E_ABSOLUTE kNtImageRelNexgen32eAbsolute -#define IMAGE_REL_NEXGEN32E_ADDR64 kNtImageRelNexgen32eAddr64 -#define IMAGE_REL_NEXGEN32E_ADDR32 kNtImageRelNexgen32eAddr32 -#define IMAGE_REL_NEXGEN32E_ADDR32NB kNtImageRelNexgen32eAddr32nb -#define IMAGE_REL_NEXGEN32E_REL32 kNtImageRelNexgen32eRel32 -#define IMAGE_REL_NEXGEN32E_REL32_1 kNtImageRelNexgen32eRel321 -#define IMAGE_REL_NEXGEN32E_REL32_2 kNtImageRelNexgen32eRel322 -#define IMAGE_REL_NEXGEN32E_REL32_3 kNtImageRelNexgen32eRel323 -#define IMAGE_REL_NEXGEN32E_REL32_4 kNtImageRelNexgen32eRel324 -#define IMAGE_REL_NEXGEN32E_REL32_5 kNtImageRelNexgen32eRel325 -#define IMAGE_REL_NEXGEN32E_SECTION kNtImageRelNexgen32eSection -#define IMAGE_REL_NEXGEN32E_SECREL kNtImageRelNexgen32eSecrel -#define IMAGE_REL_NEXGEN32E_SECREL7 kNtImageRelNexgen32eSecrel7 -#define IMAGE_REL_NEXGEN32E_TOKEN kNtImageRelNexgen32eToken -#define IMAGE_REL_NEXGEN32E_SREL32 kNtImageRelNexgen32eSrel32 -#define IMAGE_REL_NEXGEN32E_PAIR kNtImageRelNexgen32ePair -#define IMAGE_REL_NEXGEN32E_SSPAN32 kNtImageRelNexgen32eSspan32 - -#define IMAGE_REL_BASED_ABSOLUTE kNtImageRelBasedAbsolute -#define IMAGE_REL_BASED_HIGH kNtImageRelBasedHigh -#define IMAGE_REL_BASED_LOW kNtImageRelBasedLow -#define IMAGE_REL_BASED_HIGHLOW kNtImageRelBasedHighlow -#define IMAGE_REL_BASED_HIGHADJ kNtImageRelBasedHighadj -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_5 kNtImageRelBasedMachineSpecific5 -#define IMAGE_REL_BASED_RESERVED kNtImageRelBasedReserved -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_7 kNtImageRelBasedMachineSpecific7 -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_8 kNtImageRelBasedMachineSpecific8 -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_9 kNtImageRelBasedMachineSpecific9 -#define IMAGE_REL_BASED_DIR64 kNtImageRelBasedDir64 - -#define IMAGE_ARCHIVE_START_SIZE kNtImageArchiveStartSize -#define IMAGE_ARCHIVE_START kNtImageArchiveStart -#define IMAGE_ARCHIVE_END kNtImageArchiveEnd -#define IMAGE_ARCHIVE_PAD kNtImageArchivePad -#define IMAGE_ARCHIVE_LINKER_MEMBER kNtImageArchiveLinkerMember -#define IMAGE_ARCHIVE_LONGNAMES_MEMBER kNtImageArchiveLongnamesMember -#define IMAGE_ARCHIVE_HYBRIDMAP_MEMBER kNtImageArchiveHybridmapMember - -#define IMAGE_ORDINAL_FLAG kNtImageOrdinalFlag -#define IMAGE_ORDINAL(Ordinal) NtImageOrdinal(Ordinal) -#define IMAGE_SNAP_BY_ORDINAL(Ordinal) NtImageSnapByOrdinal(Ordinal) - -#define IMAGE_RESOURCE_NAME_IS_STRING kNtImageResourceNameIsString -#define IMAGE_RESOURCE_DATA_IS_DIRECTORY kNtImageResourceDataIsDirectory - -#define IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE \ - kNtImageDynamicRelocationGuardRfPrologue -#define IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE \ - kNtImageDynamicRelocationGuardRfEpilogue - -#define IMAGE_HOT_PATCH_BASE_OBLIGATORY kNtImageHotPatchBaseObligatory -#define IMAGE_HOT_PATCH_CHUNK_INVERSE kNtImageHotPatchChunkInverse -#define IMAGE_HOT_PATCH_CHUNK_OBLIGATORY kNtImageHotPatchChunkObligatory -#define IMAGE_HOT_PATCH_CHUNK_RESERVED kNtImageHotPatchChunkReserved -#define IMAGE_HOT_PATCH_CHUNK_TYPE kNtImageHotPatchChunkType -#define IMAGE_HOT_PATCH_CHUNK_SOURCE_RVA kNtImageHotPatchChunkSourceRva -#define IMAGE_HOT_PATCH_CHUNK_TARGET_RVA kNtImageHotPatchChunkTargetRva -#define IMAGE_HOT_PATCH_CHUNK_SIZE kNtImageHotPatchChunkSize -#define IMAGE_HOT_PATCH_NONE kNtImageHotPatchNone -#define IMAGE_HOT_PATCH_FUNCTION kNtImageHotPatchFunction -#define IMAGE_HOT_PATCH_ABSOLUTE kNtImageHotPatchAbsolute -#define IMAGE_HOT_PATCH_REL32 kNtImageHotPatchRel32 -#define IMAGE_HOT_PATCH_CALL_TARGET kNtImageHotPatchCallTarget -#define IMAGE_HOT_PATCH_INDIRECT kNtImageHotPatchIndirect -#define IMAGE_HOT_PATCH_NO_CALL_TARGET kNtImageHotPatchNoCallTarget -#define IMAGE_HOT_PATCH_DYNAMIC_VALUE kNtImageHotPatchDynamicValue -#define IMAGE_GUARD_CF_INSTRUMENTED kNtImageGuardCfInstrumented -#define IMAGE_GUARD_CFW_INSTRUMENTED kNtImageGuardCfwInstrumented -#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT \ - kNtImageGuardCfFunctionTablePresent -#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED kNtImageGuardSecurityCookieUnused -#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT kNtImageGuardProtectDelayloadIat -#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION \ - kNtImageGuardDelayloadIatInItsOwnSection -#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT \ - kNtImageGuardCfExportSuppressionInfoPresent -#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION \ - kNtImageGuardCfEnableExportSuppression -#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT \ - kNtImageGuardCfLongjumpTablePresent -#define IMAGE_GUARD_RF_INSTRUMENTED kNtImageGuardRfInstrumented -#define IMAGE_GUARD_RF_ENABLE kNtImageGuardRfEnable -#define IMAGE_GUARD_RF_STRICT kNtImageGuardRfStrict -#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK \ - kNtImageGuardCfFunctionTableSizeMask -#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT \ - kNtImageGuardCfFunctionTableSizeShift -#define IMAGE_GUARD_FLAG_FID_SUPPRESSED kNtImageGuardFlagFidSuppressed -#define IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED kNtImageGuardFlagExportSuppressed - -#define IMAGE_ENCLAVE_IMPORT_MATCH_NONE kNtImageEnclaveImportMatchNone -#define IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID kNtImageEnclaveImportMatchUniqueId -#define IMAGE_ENCLAVE_IMPORT_MATCH_AUTHOR_ID kNtImageEnclaveImportMatchAuthorId -#define IMAGE_ENCLAVE_IMPORT_MATCH_FAMILY_ID kNtImageEnclaveImportMatchFamilyId -#define IMAGE_ENCLAVE_IMPORT_MATCH_IMAGE_ID kNtImageEnclaveImportMatchImageId - -#define IMAGE_DEBUG_TYPE_UNKNOWN kNtImageDebugTypeUnknown -#define IMAGE_DEBUG_TYPE_COFF kNtImageDebugTypeCoff -#define IMAGE_DEBUG_TYPE_CODEVIEW kNtImageDebugTypeCodeview -#define IMAGE_DEBUG_TYPE_FPO kNtImageDebugTypeFpo -#define IMAGE_DEBUG_TYPE_MISC kNtImageDebugTypeMisc -#define IMAGE_DEBUG_TYPE_EXCEPTION kNtImageDebugTypeException -#define IMAGE_DEBUG_TYPE_FIXUP kNtImageDebugTypeFixup -#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC kNtImageDebugTypeOmapToSrc -#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC kNtImageDebugTypeOmapFromSrc -#define IMAGE_DEBUG_TYPE_BORLAND kNtImageDebugTypeBorland -#define IMAGE_DEBUG_TYPE_RESERVED10 kNtImageDebugTypeReserved10 -#define IMAGE_DEBUG_TYPE_CLSID kNtImageDebugTypeClsid -#define IMAGE_DEBUG_TYPE_VC_FEATURE kNtImageDebugTypeVcFeature -#define IMAGE_DEBUG_TYPE_POGO kNtImageDebugTypePogo -#define IMAGE_DEBUG_TYPE_ILTCG kNtImageDebugTypeIltcg -#define IMAGE_DEBUG_TYPE_MPX kNtImageDebugTypeMpx -#define IMAGE_DEBUG_TYPE_REPRO kNtImageDebugTypeRepro - -#define FRAME_FPO kNtFrameFpo -#define FRAME_TRAP kNtFrameTrap -#define FRAME_TSS kNtFrameTss -#define FRAME_NONFPO kNtFrameNonfpo - -#define IMAGE_SIZEOF_SHORT_NAME kNtImageSizeofShortName -#define IMAGE_SIZEOF_SECTION_HEADER kNtImageSizeofSectionHeader -#define IMAGE_SIZEOF_SYMBOL kNtImageSizeofSymbol -#define IMAGE_ENCLAVE_LONG_ID_LENGTH kNtImageEnclaveLongIdLength -#define IMAGE_ENCLAVE_SHORT_ID_LENGTH kNtImageEnclaveShortIdLength -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES kNtImageNumberofDirectoryEntries - -#define FILE_BEGIN kNtFileBegin -#define FILE_CURRENT kNtFileCurrent -#define FILE_END kNtFileEnd - -#define WSADATA struct NtWsaData -#define LPWSADATA struct NtWsaData* - -#define FD_MAX_EVENTS 10 - -#define CSADDR_INFO struct NtCsAddrInfo -#define PCSADDR_INFO struct NtCsAddrInfo* -#define LPCSADDR_INFO struct NtCsAddrInfo* - -#define AFPROTOCOLS struct NtAfProtocols -#define PAFPROTOCOLS struct NtAfProtocols* -#define LPAFPROTOCOLS struct NtAfProtocols* - -#define WSAECOMPARATOR int -#define PWSAECOMPARATOR int* -#define LPWSAECOMPARATOR int* - -#define WSANETWORKEVENTS struct NtWsaNetworkEvents -#define PWSANETWORKEVENTS struct NtWsaNetworkEvents* -#define LPWSANETWORKEVENTS struct NtWsaNetworkEvents* - -#define WSANSCLASSINFOW struct NtWsansClassInfo -#define PWSANSCLASSINFOW struct NtWsansClassInfo* -#define LPWSANSCLASSINFOW struct NtWsansClassInfo* - -#define WSASERVICECLASSINFOW struct NtWsaServiceClassInfo -#define PWSASERVICECLASSINFOW struct NtWsaServiceClassInfo* -#define LPWSASERVICECLASSINFOW struct NtWsaServiceClassInfo* - -#define WSANAMESPACE_INFOEX struct NtWsaNamespaceInfoEx -#define PWSANAMESPACE_INFOEX struct NtWsaNamespaceInfoEx* -#define LPWSANAMESPACE_INFOEX struct NtWsaNamespaceInfoEx* - -#define WSAQUERYSET struct NtWsaQuerySet -#define PWSAQUERYSET struct NtWsaQuerySet* -#define LPWSAQUERYSET struct NtWsaQuerySet* - -#define WSAVERSION struct NtWsaVersion -#define PWSAVERSION struct NtWsaVersion* -#define LPWSAVERSION struct NtWsaVersion* - -#define SOCKADDR struct sockaddr -#define PSOCKADDR struct sockaddr* -#define LPSOCKADDR struct sockaddr* - -#define SOCKET_ADDRESS struct NtSocketAddress -#define PSOCKET_ADDRESS struct NtSocketAddress* -#define LPSOCKET_ADDRESS struct NtSocketAddress* - -#define REPARSE_DATA_BUFFER struct NtReparseDataBuffer -#define PREPARSE_DATA_BUFFER struct NtReparseDataBuffer* -#define LPREPARSE_DATA_BUFFER struct NtReparseDataBuffer* - -#define SOCKET_ADDRESS_LIST struct NtSocketAddressList -#define PSOCKET_ADDRESS_LIST struct NtSocketAddressList* -#define LPSOCKET_ADDRESS_LIST struct NtSocketAddressList* - -#define FLOWSPEC struct NtFlowSpec -#define LPFLOWSPEC struct NtFlowSpec* - -#define QOS struct NtQos -#define LPQOS struct NtQos* - -#define _WSAPROTOCOLCHAIN NtWsaProtocolChain -#define WSAPROTOCOLCHAIN struct NtWsaProtocolChain -#define LPWSAPROTOCOLCHAIN struct NtWsaProtocolChain* - -#define _WSAPROTOCOL_INFO NtWsaProtocolInfo -#define WSAPROTOCOL_INFO struct NtWsaProtocolInfo -#define LPWSAPROTOCOL_INFO struct NtWsaProtocolInfo* - -#define _WSABUF NtIovec -#define WSABUF struct NtIovec -#define LPWSABUF struct NtIovec* - -#define _GUID NtGuid -#define GUID struct NtGuid -#define LPGUID struct NtGuid* - -#define ADDRINFOEX struct NtAddrInfoEx -#define LPADDRINFOEX struct NtAddrInfoEx* - -#define WSAEVENT HANDLE -#define GROUP uint32_t -#define WSAOVERLAPPED OVERLAPPED -#define INVALID_SOCKET -1ULL -#define SOCKET_ERROR -1 -#define WSA_INVALID_EVENT -1L -#define WAIT_FAILED -1U -#define SOCKET uint64_t -#define WSA_WAIT_IO_COMPLETION 0xc0 -#define WSA_WAIT_TIMEOUT 258 - -#define LPCONDITIONPROC NtConditionProc -#define LPWSAOVERLAPPED_COMPLETION_ROUTINE NtWsaOverlappedCompletionRoutine - -#define WSACOMPLETIONTYPE int -#define PWSACOMPLETIONTYPE int* -#define LPWSACOMPLETIONTYPE int* -#define NSP_NOTIFY_IMMEDIATELY kNtNspNotifyImmediately -#define NSP_NOTIFY_HWND kNtNspNotifyHwnd -#define NSP_NOTIFY_EVENT kNtNspNotifyEvent -#define NSP_NOTIFY_PORT kNtNspNotifyPort -#define NSP_NOTIFY_APC kNtNspNotifyApc - -#define WSACOMPLETION struct NtWsaCompletion -#define PWSACOMPLETION struct NtWsaCompletion* -#define LPWSACOMPLETION struct NtWsaCompletion* - -#define WSAPOLLFD struct pollfd -#define PWSAPOLLFD struct pollfd* -#define LPWSAPOLLFD struct pollfd* - -#define SD_RECEIVE SHUT_RD -#define SD_SEND SHUT_WR -#define SD_BOTH SHUT_RDWR - -#define WSAMSG struct NtMsgHdr -#define PWSAMSG struct NtMsgHdr* -#define LPWSAMSG struct NtMsgHdr* - -#define _MEMORYSTATUSEX NtMemoryStatusEx -#define MEMORYSTATUSEX struct NtMemoryStatusEx -#define LPMEMORYSTATUSEX struct NtMemoryStatusEx* - -#define HKEY_CLASSES_ROOT kNtHkeyClassesRoot -#define HKEY_CURRENT_USER kNtHkeyCurrentUser -#define HKEY_LOCAL_MACHINE kNtHkeyLocalMachine -#define HKEY_USERS kNtHkeyUsers -#define HKEY_PERFORMANCE_DATA kNtHkeyPerformanceData -#define HKEY_PERFORMANCE_TEXT kNtHkeyPerformanceText -#define HKEY_PERFORMANCE_NLSTEXT kNtHkeyPerformanceNlstext -#define HKEY_CURRENT_CONFIG kNtHkeyCurrentConfig -#define HKEY_DYN_DATA kNtHkeyDynData -#define HKEY_CURRENT_USER_LOCAL_SETTINGS kNtHkeyCurrentUserLocalSettings -#define KEY_READ kNtKeyRead -#define KEY_WRITE kNtKeyWrite -#define KEY_EXECUTE kNtKeyExecute -#define KEY_ALL_ACCESS kNtKeyAllAccess -#define REG_NONE kNtRegNone -#define REG_SZ kNtRegSz -#define REG_EXPAND_SZ kNtRegExpandSz -#define REG_BINARY kNtRegBinary -#define REG_DWORD kNtRegDword -#define REG_DWORD_BIG_ENDIAN kNtRegDwordBigEndian -#define REG_LINK kNtRegLink -#define REG_MULTI_SZ kNtRegMultiSz -#define REG_RESOURCE_LIST kNtRegResourceList -#define REG_FULL_RESOURCE_DESCRIPTOR kNtRegFullResourceDescriptor -#define REG_RESOURCE_REQUIREMENTS_LIST kNtRegResourceRequirementsList -#define REG_QWORD kNtRegQword -#define RRF_RT_REG_NONE kNtRrfRtRegNone -#define RRF_RT_REG_SZ kNtRrfRtRegSz -#define RRF_RT_REG_EXPAND_SZ kNtRrfRtRegExpandSz -#define RRF_RT_REG_BINARY kNtRrfRtRegBinary -#define RRF_RT_REG_DWORD kNtRrfRtRegDword -#define RRF_RT_REG_MULTI_SZ kNtRrfRtRegMultiSz -#define RRF_RT_REG_QWORD kNtRrfRtRegQword -#define RRF_RT_DWORD kNtRrfRtDword -#define RRF_RT_QWORD kNtRrfRtQword -#define RRF_RT_ANY kNtRrfRtAny -#define RRF_SUBKEY_WOW6464KEY kNtRrfSubkeyWow6464key -#define RRF_SUBKEY_WOW6432KEY kNtRrfSubkeyWow6432key -#define RRF_WOW64_MASK kNtRrfWow64Mask -#define RRF_NOEXPAND kNtRrfNoexpand -#define RRF_ZEROONFAILURE kNtRrfZeroonfailure - -#define NUMA_NO_PREFERRED_NODE kNtNumaNoPreferredNode - -#define TF_DISCONNECT kNtTfDisconnect -#define TF_REUSE_SOCKET kNtTfReuseSocket -#define TF_WRITE_BEHIND kNtTfWriteBehind -#define TF_USE_DEFAULT_WORKER kNtTfUseDefaultWorker -#define TF_USE_SYSTEM_THREAD kNtTfUseSystemThread -#define TF_USE_KERNEL_APC kNtTfUseKernelApc - -#define SIO_UDP_CONNRESET kNtSioUdpConnreset -#define SIO_SOCKET_CLOSE_NOTIFY kNtSioSocketCloseNotify -#define SIO_UDP_NETRESET kNtSioUdpNetreset - -#define THREAD_TERMINATE kNtThreadTerminate -#define THREAD_SUSPEND_RESUME kNtThreadSuspendResume -#define THREAD_GET_CONTEXT kNtThreadGetContext -#define THREAD_SET_CONTEXT kNtThreadSetContext -#define THREAD_QUERY_INFORMATION kNtThreadQueryInformation -#define THREAD_SET_INFORMATION kNtThreadSetInformation -#define THREAD_SET_THREAD_TOKEN kNtThreadSetThreadToken -#define THREAD_IMPERSONATE kNtThreadImpersonate -#define THREAD_DIRECT_IMPERSONATION kNtThreadDirectImpersonation -#define THREAD_SET_LIMITED_INFORMATION kNtThreadSetLimitedInformation -#define THREAD_QUERY_LIMITED_INFORMATION kNtThreadQueryLimitedInformation -#define THREAD_RESUME kNtThreadResume -#define THREAD_ALL_ACCESS kNtThreadAllAccess - -#define _FILE_SEGMENT_ELEMENT NtFileSegmentElement -#define FILE_SEGMENT_ELEMENT union NtFileSegmentElement -#define PFILE_SEGMENT_ELEMENT union NtFileSegmentElement* - -#define FileBasicInfo kNtFileBasicInfo -#define FileStandardInfo kNtFileStandardInfo -#define FileNameInfo kNtFileNameInfo -#define FileRenameInfo kNtFileRenameInfo -#define FileDispositionInfo kNtFileDispositionInfo -#define FileAllocationInfo kNtFileAllocationInfo -#define FileEndOfFileInfo kNtFileEndOfFileInfo -#define FileStreamInfo kNtFileStreamInfo -#define FileCompressionInfo kNtFileCompressionInfo -#define FileAttributeTagInfo kNtFileAttributeTagInfo -#define FileIdBothDirectoryInfo kNtFileIdBothDirectoryInfo -#define FileIdBothDirectoryRestartInfo kNtFileIdBothDirectoryRestartInfo -#define FileIoPriorityHintInfo kNtFileIoPriorityHintInfo -#define FileRemoteProtocolInfo kNtFileRemoteProtocolInfo -#define FileFullDirectoryInfo kNtFileFullDirectoryInfo -#define FileFullDirectoryRestartInfo kNtFileFullDirectoryRestartInfo -#define FileStorageInfo kNtFileStorageInfo -#define FileAlignmentInfo kNtFileAlignmentInfo -#define FileIdInfo kNtFileIdInfo -#define FileIdExtdDirectoryInfo kNtFileIdExtdDirectoryInfo -#define FileIdExtdDirectoryRestartInfo kNtFileIdExtdDirectoryRestartInfo -#define FileDispositionInfoEx kNtFileDispositionInfoEx -#define FileRenameInfoEx kNtFileRenameInfoEx - -#define _FILE_FULL_DIR_INFO NtFileFullDirectoryInformation -#define FILE_FULL_DIR_INFO struct NtFileFullDirectoryInformation -#define PFILE_FULL_DIR_INFO struct NtFileFullDirectoryInformation* - -#define _FILE_BASIC_INFO NtFileBasicInformation -#define FILE_BASIC_INFO struct NtFileBasicInformation -#define PFILE_BASIC_INFO struct NtFileBasicInformation* - -#define _FILE_STANDARD_INFO NtFileStandardInformation -#define FILE_STANDARD_INFO struct NtFileStandardInformation -#define PFILE_STANDARD_INFO struct NtFileStandardInformation* - -#define HANDLE_FLAG_INHERIT kNtHandleFlagInherit -#define HANDLE_FLAG_PROTECT_FROM_CLOSE kNtHandleFlagProtectFromClose - -#define SYMBOLIC_LINK_FLAG_DIRECTORY kNtSymbolicLinkFlagDirectory - -#define NT_FORMAT_MESSAGE_ALLOCATE_BUFFER kNtFormatMessageAllocateBuffer -#define NT_FORMAT_MESSAGE_IGNORE_INSERTS kNtFormatMessageIgnoreInserts -#define NT_FORMAT_MESSAGE_FROM_STRING kNtFormatMessageFromString -#define NT_FORMAT_MESSAGE_FROM_HMODULE kNtFormatMessageFromHmodule -#define NT_FORMAT_MESSAGE_FROM_SYSTEM kNtFormatMessageFromSystem -#define NT_FORMAT_MESSAGE_ARGUMENT_ARRAY kNtFormatMessageArgumentArray -#define NT_FORMAT_MESSAGE_MAX_WIDTH_MASK kNtFormatMessageMaxWidthMask - -#define THREAD_BASE_PRIORITY_IDLE kNtThreadBasePriorityIdle -#define THREAD_BASE_PRIORITY_MIN kNtThreadBasePriorityMin -#define THREAD_BASE_PRIORITY_MAX kNtThreadBasePriorityMax -#define THREAD_BASE_PRIORITY_LOWRT kNtThreadBasePriorityLowrt - -#define THREAD_PRIORITY_IDLE kNtThreadPriorityIdle -#define THREAD_PRIORITY_LOWEST kNtThreadPriorityLowest -#define THREAD_PRIORITY_BELOW_NORMAL kNtThreadPriorityBelowNormal -#define THREAD_PRIORITY_NORMAL kNtThreadPriorityNormal -#define THREAD_PRIORITY_ABOVE_NORMAL kNtThreadPriorityAboveNormal -#define THREAD_PRIORITY_HIGHEST kNtThreadPriorityHighest -#define THREAD_PRIORITY_TIME_CRITICAL kNtThreadPriorityTimeCritical - -#endif /* COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ */ diff --git a/libc/log/die.c b/libc/log/die.c index a39b427a9..9870c8df9 100644 --- a/libc/log/die.c +++ b/libc/log/die.c @@ -38,7 +38,6 @@ * * @see __minicrash() for signal handlers, e.g. handling abort() * @asyncsignalsafe - * @threadsafe * @vforksafe */ relegated wontreturn void __die(void) { diff --git a/libc/log/minicrash.c b/libc/log/minicrash.c index 6638109f2..3602b2a10 100644 --- a/libc/log/minicrash.c +++ b/libc/log/minicrash.c @@ -49,7 +49,6 @@ * * @see __die() for crashing from normal code without aborting * @asyncsignalsafe - * @threadsafe * @vforksafe */ relegated dontinstrument void __minicrash(int sig, siginfo_t *si, void *arg) { diff --git a/libc/log/vflogf.c b/libc/log/vflogf.c index 56ce1f0aa..31769924c 100644 --- a/libc/log/vflogf.c +++ b/libc/log/vflogf.c @@ -81,7 +81,6 @@ static void vflogf_onfail(FILE *f) { * time that it took to connect. This is great in forking applications. * * @asyncsignalsafe - * @threadsafe */ void(vflogf)(unsigned level, const char *file, int line, FILE *f, const char *fmt, va_list va) { diff --git a/libc/macros.internal.h b/libc/macros.internal.h index e5ba80a60..396f2b749 100644 --- a/libc/macros.internal.h +++ b/libc/macros.internal.h @@ -10,6 +10,14 @@ * @fileoverview Common C preprocessor, assembler, and linker macros. */ +#ifdef MAX +#undef MAX +#endif + +#ifdef MIN +#undef MIN +#endif + #define TRUE 1 #define FALSE 0 diff --git a/libc/mem/aligned_alloc.c b/libc/mem/aligned_alloc.c index 6c734f313..fc2133098 100644 --- a/libc/mem/aligned_alloc.c +++ b/libc/mem/aligned_alloc.c @@ -27,7 +27,6 @@ * @return memory address, or NULL w/ errno * @throw EINVAL if !IS2POW(a) * @see pvalloc() - * @threadsafe */ void *aligned_alloc(size_t a, size_t n) { if (IS2POW(a)) { diff --git a/libc/mem/calloc.c b/libc/mem/calloc.c index c207741b9..ee9f7db65 100644 --- a/libc/mem/calloc.c +++ b/libc/mem/calloc.c @@ -30,7 +30,6 @@ void *(*hook_calloc)(size_t, size_t) = dlcalloc; * @return rax is memory address, or NULL w/ errno * @note overreliance on memalign is a sure way to fragment space * @see dlcalloc() - * @threadsafe */ void *calloc(size_t n, size_t itemsize) { return hook_calloc(n, itemsize); diff --git a/libc/mem/free.c b/libc/mem/free.c index ed9864d6a..7c0c480d0 100644 --- a/libc/mem/free.c +++ b/libc/mem/free.c @@ -31,7 +31,6 @@ void (*hook_free)(void *) = dlfree; * * @param p is allocation address, which may be NULL * @see dlfree() - * @threadsafe */ void free(void *p) { hook_free(p); diff --git a/libc/mem/gc.c b/libc/mem/gc.c index fc3ab1581..d53760a65 100644 --- a/libc/mem/gc.c +++ b/libc/mem/gc.c @@ -115,7 +115,6 @@ void __defer(void *rbp, void *fn, void *arg) { * @warning do not realloc() with gc()'d pointer * @warning be careful about static keyword due to impact of inlining * @note you should use -fno-omit-frame-pointer - * @threadsafe */ void *(_gc)(void *thing) { struct StackFrame *frame; @@ -135,7 +134,6 @@ void *(_gc)(void *thing) { * @warning do not realloc() with gc()'d pointer * @warning be careful about static keyword due to impact of inlining * @note you should use -fno-omit-frame-pointer - * @threadsafe */ void *(_defer)(void *fn, void *arg) { struct StackFrame *frame; diff --git a/libc/mem/get_current_dir_name.c b/libc/mem/get_current_dir_name.c index 505d9d318..0e850f84e 100644 --- a/libc/mem/get_current_dir_name.c +++ b/libc/mem/get_current_dir_name.c @@ -27,7 +27,6 @@ * that'll be returned. * * @return pointer that must be free()'d, or NULL w/ errno - * @threadsafe */ char *get_current_dir_name(void) { const char *p; diff --git a/libc/mem/hook_realloc_in_place.c b/libc/mem/hook_realloc_in_place.c index 191cfcfc3..df85da90f 100644 --- a/libc/mem/hook_realloc_in_place.c +++ b/libc/mem/hook_realloc_in_place.c @@ -36,7 +36,6 @@ void *(*hook_realloc_in_place)(void *, size_t) = dlrealloc_in_place; * @param n is number of bytes needed * @return rax is result, or NULL w/ errno * @see dlrealloc_in_place() - * @threadsafe */ void *realloc_in_place(void *p, size_t n) { return hook_realloc_in_place(p, n); diff --git a/libc/mem/malloc.c b/libc/mem/malloc.c index a527e1361..706f8e3ea 100644 --- a/libc/mem/malloc.c +++ b/libc/mem/malloc.c @@ -41,7 +41,6 @@ void *(*hook_malloc)(size_t) = dlmalloc; * * @param rdi is number of bytes needed, coerced to 1+ * @return new memory, or NULL w/ errno - * @threadsafe */ void *malloc(size_t n) { return hook_malloc(n); diff --git a/libc/mem/malloc_usable_size.c b/libc/mem/malloc_usable_size.c index 2dcda5fe6..d7af246cd 100644 --- a/libc/mem/malloc_usable_size.c +++ b/libc/mem/malloc_usable_size.c @@ -39,7 +39,6 @@ size_t (*hook_malloc_usable_size)(void *) = dlmalloc_usable_size; * @param p is address of allocation * @return total number of bytes * @see dlmalloc_usable_size() - * @threadsafe */ size_t malloc_usable_size(void *p) { return hook_malloc_usable_size(p); diff --git a/libc/mem/memalign.c b/libc/mem/memalign.c index 6d5579f42..e6c33944a 100644 --- a/libc/mem/memalign.c +++ b/libc/mem/memalign.c @@ -34,7 +34,6 @@ void *(*hook_memalign)(size_t, size_t) = dlmemalign; * @param bytes is number of bytes needed, coerced to 1+ * @return rax is memory address, or NULL w/ errno * @see valloc(), pvalloc() - * @threadsafe */ void *memalign(size_t align, size_t bytes) { return hook_memalign(align, bytes); diff --git a/libc/mem/posix_memalign.c b/libc/mem/posix_memalign.c index 149f48d87..b561b4be9 100644 --- a/libc/mem/posix_memalign.c +++ b/libc/mem/posix_memalign.c @@ -36,7 +36,6 @@ * @return return 0 or EINVAL or ENOMEM w/o setting errno * @see memalign() * @returnserrno - * @threadsafe */ errno_t posix_memalign(void **pp, size_t alignment, size_t bytes) { int e; diff --git a/libc/mem/pvalloc.c b/libc/mem/pvalloc.c index 4ee636b4f..899416b1e 100644 --- a/libc/mem/pvalloc.c +++ b/libc/mem/pvalloc.c @@ -29,7 +29,6 @@ * @param n number of bytes needed * @return memory address, or NULL w/ errno * @see valloc() - * @threadsafe */ void *pvalloc(size_t n) { if (ckd_add(&n, n, FRAMESIZE - 1)) { diff --git a/libc/mem/realloc.c b/libc/mem/realloc.c index 9e9609c7b..14c9a8cc5 100644 --- a/libc/mem/realloc.c +++ b/libc/mem/realloc.c @@ -59,7 +59,6 @@ void *(*hook_realloc)(void *, size_t) = dlrealloc; * @param n is number of bytes needed * @return rax is result, or NULL w/ errno w/o free(p) * @see dlrealloc() - * @threadsafe */ void *realloc(void *p, size_t n) { return hook_realloc(p, n); diff --git a/libc/mem/reallocarray.c b/libc/mem/reallocarray.c index 47958a34c..b720b406b 100644 --- a/libc/mem/reallocarray.c +++ b/libc/mem/reallocarray.c @@ -27,7 +27,6 @@ * @param ptr may be NULL for malloc() behavior * @param nmemb may be 0 for free() behavior; shrinking is promised too * @return new address or NULL w/ errno and ptr is NOT free()'d - * @threadsafe */ void *reallocarray(void *ptr, size_t nmemb, size_t itemsize) { size_t n; diff --git a/libc/mem/strdup.c b/libc/mem/strdup.c index 17cb55afb..f3fe00ce3 100644 --- a/libc/mem/strdup.c +++ b/libc/mem/strdup.c @@ -25,7 +25,6 @@ * @param s is a NUL-terminated byte string * @return new string or NULL w/ errno * @error ENOMEM - * @threadsafe */ char *strdup(const char *s) { size_t len = strlen(s); diff --git a/libc/mem/strndup.c b/libc/mem/strndup.c index 39f4bc116..4ef4c7726 100644 --- a/libc/mem/strndup.c +++ b/libc/mem/strndup.c @@ -26,7 +26,6 @@ * @param n if less than strlen(s) will truncate the string * @return new string or NULL w/ errno * @error ENOMEM - * @threadsafe */ char *strndup(const char *s, size_t n) { char *s2; diff --git a/libc/mem/valloc.c b/libc/mem/valloc.c index 401b6f489..81dcec841 100644 --- a/libc/mem/valloc.c +++ b/libc/mem/valloc.c @@ -26,7 +26,6 @@ * @param n number of bytes needed * @return memory address, or NULL w/ errno * @see pvalloc() - * @threadsafe */ void *valloc(size_t n) { return memalign(FRAMESIZE, n); diff --git a/libc/mem/wcsdup.c b/libc/mem/wcsdup.c index b7170cdd4..724bdb2d0 100644 --- a/libc/mem/wcsdup.c +++ b/libc/mem/wcsdup.c @@ -21,7 +21,6 @@ /** * Allocates copy of wide string. - * @threadsafe */ wchar_t *wcsdup(const wchar_t *s) { size_t len = wcslen(s); diff --git a/libc/nexgen32e/gc.S b/libc/nexgen32e/gc.S index f86f5eea3..60b8ce085 100644 --- a/libc/nexgen32e/gc.S +++ b/libc/nexgen32e/gc.S @@ -32,7 +32,6 @@ // // @param rax,rdx,xmm0,xmm1,st0,st1 is return value // @see test/libc/runtime/gc_test.c -// @threadsafe .ftrace1 __gc: .ftrace2 diff --git a/libc/nexgen32e/gclongjmp.S b/libc/nexgen32e/gclongjmp.S index b9e3151a1..2a33decb3 100644 --- a/libc/nexgen32e/gclongjmp.S +++ b/libc/nexgen32e/gclongjmp.S @@ -28,7 +28,6 @@ // @param esi is returned by setjmp() invocation (coerced nonzero) // @assume system five nexgen32e abi conformant // @see examples/ctrlc.c -// @threadsafe // @noreturn .ftrace1 _gclongjmp: diff --git a/libc/nt/kernel32/CloseHandle.S b/libc/nt/kernel32/CloseHandle.S index de7c8b382..d0bf6080e 100644 --- a/libc/nt/kernel32/CloseHandle.S +++ b/libc/nt/kernel32/CloseHandle.S @@ -1,2 +1,20 @@ #include "libc/nt/codegen.h" .imp kernel32,__imp_CloseHandle,CloseHandle + + .text.windows + .ftrace1 +CloseHandle: + .ftrace2 +#ifdef __x86_64__ + push %rbp + mov %rsp,%rbp + mov %rdi,%rcx + sub $32,%rsp + call *__imp_CloseHandle(%rip) + leave +#elif defined(__aarch64__) + mov x0,#0 +#endif + ret + .endfn CloseHandle,globl + .previous diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 4af5999d0..4f7ea3a29 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -9,7 +9,6 @@ # KERNEL32.DLL # # Name Actual DLL Arity -imp '' CloseHandle kernel32 1 imp '' CreateDirectoryW kernel32 2 imp '' CreateFileA kernel32 7 imp '' CreateFileMappingNumaW kernel32 7 @@ -57,6 +56,7 @@ imp 'CancelIoEx' CancelIoEx kernel32 2 imp 'CancelSynchronousIo' CancelSynchronousIo kernel32 1 imp 'CheckRemoteDebuggerPresent' CheckRemoteDebuggerPresent kernel32 2 imp 'ClearCommBreak' ClearCommBreak kernel32 1 +imp 'CloseHandle' CloseHandle kernel32 1 imp 'ConnectNamedPipe' ConnectNamedPipe kernel32 2 imp 'ContinueDebugEvent' ContinueDebugEvent kernel32 3 imp 'CopyFile' CopyFileW kernel32 3 diff --git a/libc/proc/fork.c b/libc/proc/fork.c index 8ff302ba9..50d21feb3 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -103,7 +103,6 @@ int _fork(uint32_t dwCreationFlags) { * @raise EAGAIN if `RLIMIT_NPROC` was exceeded or system lacked resources * @raise ENOMEM if we require more vespene gas * @asyncsignalsafe - * @threadsafe */ int fork(void) { return _fork(0); diff --git a/libc/proc/posix_spawn.c b/libc/proc/posix_spawn.c index 7d32b1e14..814f5a42b 100644 --- a/libc/proc/posix_spawn.c +++ b/libc/proc/posix_spawn.c @@ -21,7 +21,6 @@ #include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/proc/ntspawn.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/fd.internal.h" #include "libc/calls/struct/rlimit.h" @@ -51,6 +50,7 @@ #include "libc/nt/runtime.h" #include "libc/nt/struct/processinformation.h" #include "libc/nt/struct/startupinfo.h" +#include "libc/proc/ntspawn.h" #include "libc/proc/posix_spawn.h" #include "libc/proc/posix_spawn.internal.h" #include "libc/proc/proc.internal.h" @@ -305,7 +305,6 @@ static textwindows dontinline errno_t posix_spawn_windows( * @see posix_spawnp() for `$PATH` searching * @returnserrno * @tlsrequired - * @threadsafe */ errno_t posix_spawn(int *pid, const char *path, const posix_spawn_file_actions_t *file_actions, diff --git a/libc/proc/systemvpe.c b/libc/proc/systemvpe.c index 781e9a758..c7143bc4e 100644 --- a/libc/proc/systemvpe.c +++ b/libc/proc/systemvpe.c @@ -46,7 +46,6 @@ * status that can be accessed using macros like WEXITSTATUS(s), * WIFSIGNALED(s), WTERMSIG(s), etc. * @see system() - * @threadsafe */ int systemvpe(const char *prog, char *const argv[], char *const envp[]) { char *exe; diff --git a/libc/proc/vfork.S b/libc/proc/vfork.S index 9bf801b8b..9b9e19a55 100644 --- a/libc/proc/vfork.S +++ b/libc/proc/vfork.S @@ -35,7 +35,6 @@ // // @return pid of child process or 0 if forked process // @returnstwice -// @threadsafe // @vforksafe .ftrace1 vfork: diff --git a/libc/proc/wait4-nt.c b/libc/proc/wait4-nt.c index 6a738f734..2299e9d63 100644 --- a/libc/proc/wait4-nt.c +++ b/libc/proc/wait4-nt.c @@ -25,7 +25,7 @@ #include "libc/calls/struct/timespec.h" #include "libc/cosmo.h" #include "libc/errno.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/dll.h" #include "libc/intrin/strace.internal.h" diff --git a/libc/runtime/clktck.c b/libc/runtime/clktck.c index 4283573ba..7f6ca99d7 100644 --- a/libc/runtime/clktck.c +++ b/libc/runtime/clktck.c @@ -19,7 +19,7 @@ #include "libc/runtime/clktck.h" #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/getauxval.internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index c6ca37d8e..a771817af 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -631,7 +631,6 @@ static int CloneLinux(int (*func)(void *arg, int rc), char *stk, size_t stksz, * @param ctid lets the child receive its thread id without having to * call gettid() and is ignored if `CLONE_CHILD_SETTID` isn't set * @return 0 on success, or errno on errno - * @threadsafe */ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg, void *ptid, void *tls, void *ctid) { diff --git a/libc/runtime/isheap.c b/libc/runtime/isheap.c index 1eb5fded0..9651ed6ee 100644 --- a/libc/runtime/isheap.c +++ b/libc/runtime/isheap.c @@ -20,11 +20,14 @@ #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" +// TODO(jart): DELETE + /** * Returns true if address isn't stack and was malloc'd or mmap'd. * * @assume stack addresses are always greater than heap addresses * @assume stack memory isn't stored beneath %rsp (-mno-red-zone) + * @deprecated */ optimizesize bool _isheap(void *p) { intptr_t x, y; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 327612989..7a7b1c604 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -89,15 +89,13 @@ void _intsort(int *, size_t); void _longsort(long *, size_t); /* diagnostics */ void ShowCrashReports(void); -void __printargs(const char *); int ftrace_install(void); int ftrace_enabled(int); int strace_enabled(int); bool strace_enter(void); -void _bt(const char *, ...); void __print_maps(void); -long _GetMaxFd(void); -/* builtin shell language */ +void __printargs(const char *); +/* builtin sh-like system/popen dsl */ int _cocmd(int, char **, char **); /* executable program */ char *GetProgramExecutableName(void); @@ -105,9 +103,6 @@ char *GetInterpreterExecutableName(char *, size_t); int __open_executable(void); /* execution control */ int verynice(void); -axdx_t setlongerjmp(jmp_buf) -libcesque returnstwice paramsnonnull(); -void longerjmp(jmp_buf, intptr_t) libcesque wontreturn paramsnonnull(); void __warn_if_powersave(void); void _Exit1(int) libcesque wontreturn; void __paginate(int, const char *); @@ -131,7 +126,6 @@ const char *GetCpuidOs(void); const char *GetCpuidEmulator(void); void GetCpuidBrand(char[13], uint32_t); long __get_rlimit(int); -int __set_rlimit(int, int64_t); const char *__describe_os(void); long __get_sysctl(int, int); int __get_arg_max(void) pureconst; diff --git a/libc/runtime/zipos-close.c b/libc/runtime/zipos-close.c index c70ed746a..9a9c038f4 100644 --- a/libc/runtime/zipos-close.c +++ b/libc/runtime/zipos-close.c @@ -27,7 +27,6 @@ * * @param fd is vetted by close() * @asyncsignalsafe - * @threadsafe * @vforksafe */ int __zipos_close(int fd) { diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index 0565232e5..397fc5e12 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -159,7 +159,6 @@ static void __zipos_init(void) { /** * Returns pointer to zip central directory of current executable. * @asyncsignalsafe - * @threadsafe */ struct Zipos *__zipos_get(void) { cosmo_once(&__zipos_once, __zipos_init); diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index cb6ec3c6d..d1b2e442d 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -214,7 +214,6 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags, * * @param uri is obtained via __zipos_parseuri() * @asyncsignalsafe - * @threadsafe */ int __zipos_open(struct ZiposUri *name, int flags) { diff --git a/libc/sock/pselect.c b/libc/sock/pselect.c index 0ccdd3a98..b19acd627 100644 --- a/libc/sock/pselect.c +++ b/libc/sock/pselect.c @@ -55,7 +55,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, diff --git a/libc/sock/select.c b/libc/sock/select.c index 6c2ba0f0d..d72afa495 100644 --- a/libc/sock/select.c +++ b/libc/sock/select.c @@ -42,7 +42,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, diff --git a/libc/stdio/asprintf.c b/libc/stdio/asprintf.c index 6e540a169..549fc191a 100644 --- a/libc/stdio/asprintf.c +++ b/libc/stdio/asprintf.c @@ -26,7 +26,6 @@ * portability, since that's guaranteed to work with all libraries * @return bytes written (excluding NUL) or -1 w/ errno * @see xasprintf() for a better API - * @threadsafe */ int asprintf(char **strp, const char *fmt, ...) { int res; diff --git a/libc/stdio/clearerr.c b/libc/stdio/clearerr.c index bc5fad837..911b94232 100644 --- a/libc/stdio/clearerr.c +++ b/libc/stdio/clearerr.c @@ -23,7 +23,6 @@ * * @param f is file object stream pointer * @see clearerr_unlocked() - * @threadsafe */ void clearerr(FILE *f) { flockfile(f); diff --git a/libc/stdio/clearerr_unlocked.c b/libc/stdio/clearerr_unlocked.c index 55f048a7d..b79524668 100644 --- a/libc/stdio/clearerr_unlocked.c +++ b/libc/stdio/clearerr_unlocked.c @@ -24,7 +24,6 @@ * * @param f is file object stream pointer * @see clearerr() - * @threadsafe */ void clearerr_unlocked(FILE *f) { f->state = 0; diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index bead6c70e..6271a2bc1 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -513,6 +513,7 @@ static struct dirent *readdir_impl(DIR *dir) { * @param dir is the object opendir() or fdopendir() returned * @return next entry or NULL on end or error, which can be * differentiated by setting errno to 0 beforehand + * @threadunsafe */ struct dirent *readdir(DIR *dir) { struct dirent *e; @@ -535,7 +536,6 @@ struct dirent *readdir(DIR *dir) { * @param result will receive `output` pointer, or null on eof * @return 0 on success, or errno on error * @returnserrno - * @threadsafe */ errno_t readdir_r(DIR *dir, struct dirent *output, struct dirent **result) { int err, olderr; @@ -587,7 +587,6 @@ int closedir(DIR *dir) { /** * Returns offset into directory data. - * @threadsafe */ long telldir(DIR *dir) { long rc; @@ -599,7 +598,6 @@ long telldir(DIR *dir) { /** * Returns file descriptor associated with DIR object. - * @threadsafe */ int dirfd(DIR *dir) { return dir->fd; @@ -607,7 +605,6 @@ int dirfd(DIR *dir) { /** * Seeks to beginning of directory stream. - * @threadsafe */ void rewinddir(DIR *dir) { lockdir(dir); @@ -634,7 +631,6 @@ void rewinddir(DIR *dir) { /** * Seeks in directory stream. - * @threadsafe */ void seekdir(DIR *dir, long tell) { lockdir(dir); diff --git a/libc/stdio/feof.c b/libc/stdio/feof.c index eeca17292..2b910c033 100644 --- a/libc/stdio/feof.c +++ b/libc/stdio/feof.c @@ -23,7 +23,6 @@ * * @param f is file object stream pointer * @see feof_unlocked() - * @threadsafe */ int feof(FILE *f) { int rc; diff --git a/libc/stdio/ferror.c b/libc/stdio/ferror.c index d11ef64f7..73b79e8f0 100644 --- a/libc/stdio/ferror.c +++ b/libc/stdio/ferror.c @@ -25,7 +25,6 @@ * @return non-zero if and only if it's an error state * @see ferror_unlocked(), feof() * @note EOF doesn't count - * @threadsafe */ errno_t ferror(FILE *f) { int rc; diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c index 5618a8ae4..826dc484e 100644 --- a/libc/stdio/fflush.c +++ b/libc/stdio/fflush.c @@ -23,7 +23,6 @@ * * @param f is the stream handle, or 0 for all streams * @return is 0 on success or -1 on error - * @threadsafe */ int fflush(FILE *f) { int rc; diff --git a/libc/stdio/fgetc.c b/libc/stdio/fgetc.c index 05b4e05dd..478e3e0e1 100644 --- a/libc/stdio/fgetc.c +++ b/libc/stdio/fgetc.c @@ -24,7 +24,6 @@ * @param f is non-null file object stream pointer * @return byte in range 0..255, or -1 w/ errno * @see fgetc_unlocked() - * @threadsafe */ int fgetc(FILE *f) { int rc; diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c index 360896f66..437c2c556 100644 --- a/libc/stdio/fgets.c +++ b/libc/stdio/fgets.c @@ -34,7 +34,6 @@ * @return s on success, NULL on error, or NULL if EOF happens when * zero characters have been read * @see fgets_unlocked() - * @threadsafe */ char *fgets(char *s, int size, FILE *f) { char *res; diff --git a/libc/stdio/fgetwc.c b/libc/stdio/fgetwc.c index ddc471ea3..28b43cb3f 100644 --- a/libc/stdio/fgetwc.c +++ b/libc/stdio/fgetwc.c @@ -24,7 +24,6 @@ * @param f is non-null file object stream pointer * @return wide character or -1 on EOF or error * @see fgetwc_unlocked() - * @threadsafe */ wint_t fgetwc(FILE *f) { wint_t wc; diff --git a/libc/stdio/fgetws.c b/libc/stdio/fgetws.c index 4ac3f156a..2c8f2854f 100644 --- a/libc/stdio/fgetws.c +++ b/libc/stdio/fgetws.c @@ -29,7 +29,6 @@ * @param size is byte length of `s` * @param f is file stream object pointer * @see fgetws() - * @threadsafe */ wchar_t *fgetws(wchar_t *s, int size, FILE *f) { wchar_t *rc; diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c index 294becdbf..b81ebcb4c 100644 --- a/libc/stdio/fileno.c +++ b/libc/stdio/fileno.c @@ -24,7 +24,6 @@ * * @param f is file stream object pointer * @return fd on success or -1 w/ errno; - * @threadsafe */ int fileno(FILE *f) { int rc; diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c index f0bdac9ad..cd15f84c7 100644 --- a/libc/stdio/fputc.c +++ b/libc/stdio/fputc.c @@ -23,7 +23,6 @@ * * @param c is byte to buffer or write, which is masked * @return c as unsigned char if written or -1 w/ errno - * @threadsafe */ int fputc(int c, FILE *f) { int rc; diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c index aef211a86..8bba14dda 100644 --- a/libc/stdio/fputs.c +++ b/libc/stdio/fputs.c @@ -28,7 +28,6 @@ * @param s is a NUL-terminated string that's non-NULL * @param f is an open stream * @return bytes written, or -1 w/ errno - * @threadsafe */ int fputs(const char *s, FILE *f) { int rc; diff --git a/libc/stdio/fputwc.c b/libc/stdio/fputwc.c index 4ecced63f..692e56cc9 100644 --- a/libc/stdio/fputwc.c +++ b/libc/stdio/fputwc.c @@ -24,7 +24,6 @@ * @param wc has wide character * @param f is file object stream pointer * @return wide character if written or -1 w/ errno - * @threadsafe */ wint_t fputwc(wchar_t wc, FILE *f) { wint_t rc; diff --git a/libc/stdio/fputws.c b/libc/stdio/fputws.c index c9b533f8b..096d112d4 100644 --- a/libc/stdio/fputws.c +++ b/libc/stdio/fputws.c @@ -28,7 +28,6 @@ * @param s is a NUL-terminated string that's non-NULL * @param f is an open stream * @return strlen(s), or -1 w/ errno - * @threadsafe */ int fputws(const wchar_t *s, FILE *f) { int rc; diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 24f2cc446..ee82f8275 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -27,7 +27,6 @@ * @param stride specifies the size of individual items * @param count is the number of strides to fetch * @return count on success, [0,count) on eof, or 0 on error or count==0 - * @threadsafe */ size_t fread(void *buf, size_t stride, size_t count, FILE *f) { size_t rc; diff --git a/libc/stdio/fseek.c b/libc/stdio/fseek.c index e78db477e..0da8e521b 100644 --- a/libc/stdio/fseek.c +++ b/libc/stdio/fseek.c @@ -32,7 +32,6 @@ * @param offset is the byte delta * @param whence can be SEET_SET, SEEK_CUR, or SEEK_END * @returns 0 on success or -1 on error - * @threadsafe */ int fseek(FILE *f, int64_t offset, int whence) { int rc; diff --git a/libc/stdio/ftell.c b/libc/stdio/ftell.c index 5210815a1..ce23fbd7e 100644 --- a/libc/stdio/ftell.c +++ b/libc/stdio/ftell.c @@ -44,7 +44,6 @@ static inline int64_t ftell_unlocked(FILE *f) { * * @param stream is a non-null stream handle * @returns current byte offset from beginning, or -1 w/ errno - * @threadsafe */ int64_t ftell(FILE *f) { int64_t rc; diff --git a/libc/stdio/ftw.c b/libc/stdio/ftw.c index 23034f973..e66ddba98 100644 --- a/libc/stdio/ftw.c +++ b/libc/stdio/ftw.c @@ -39,6 +39,7 @@ asm(".include \"libc/disclaimer.inc\""); * @return 0 on success, -1 on error, or non-zero `fn` result * @see examples/walk.c for example * @see nftw() + * @threadsafe */ int ftw(const char *dirpath, int fn(const char *fpath, diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c index 9fddb9921..7888be1b7 100644 --- a/libc/stdio/fwrite.c +++ b/libc/stdio/fwrite.c @@ -26,7 +26,6 @@ * @param stride specifies the size of individual items * @param count is the number of strides to write * @return count on success, [0,count) on EOF, 0 on error or count==0 - * @threadsafe */ size_t fwrite(const void *data, size_t stride, size_t count, FILE *f) { size_t rc; diff --git a/libc/stdio/getwchar.c b/libc/stdio/getwchar.c index 2bae268ed..a455dbc11 100644 --- a/libc/stdio/getwchar.c +++ b/libc/stdio/getwchar.c @@ -21,7 +21,6 @@ /** * Reads UTF-8 character from stream. * @return wide character or -1 on EOF or error - * @threadsafe */ wint_t getwchar(void) { return fgetwc(stdin); diff --git a/libc/stdio/nftw.c b/libc/stdio/nftw.c index 59ea2d31a..7e61243f1 100644 --- a/libc/stdio/nftw.c +++ b/libc/stdio/nftw.c @@ -160,6 +160,7 @@ static int do_nftw(char *path, * * @return 0 on success, -1 on error, or non-zero `fn` result * @see examples/walk.c for example + * @threadsafe */ int nftw(const char *dirpath, int fn(const char *fpath, diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index b408fb15c..7f3265873 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -52,7 +52,6 @@ * @raise EAGAIN if `RLIMIT_NPROC` was exceeded * @raise EINTR if signal was delivered * @cancellationpoint - * @threadsafe */ FILE *popen(const char *cmdline, const char *mode) { FILE *f, *f2; diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c index 4cbf20297..1739c34ea 100644 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -22,7 +22,6 @@ * Writes byte to stdout. * * @return c (as unsigned char) if written or -1 w/ errno - * @threadsafe */ int putchar(int c) { return fputc(c, stdout); diff --git a/libc/stdio/putwchar.c b/libc/stdio/putwchar.c index fe0c20b51..8fe5cf01c 100644 --- a/libc/stdio/putwchar.c +++ b/libc/stdio/putwchar.c @@ -21,7 +21,6 @@ /** * Writes wide character to stdout. * @return wc if written or -1 w/ errno - * @threadsafe */ wint_t putwchar(wchar_t wc) { return fputwc(wc, stdout); diff --git a/libc/stdio/rand.c b/libc/stdio/rand.c index 1c5524213..6ff04b99e 100644 --- a/libc/stdio/rand.c +++ b/libc/stdio/rand.c @@ -36,6 +36,7 @@ * @note this function does well on bigcrush and practrand * @note this function is not intended for cryptography * @see lemur64(), _rand64(), rdrand() + * @threadunsafe */ int rand(void) { return KnuthLinearCongruentialGenerator(&g_rando) >> 33; diff --git a/libc/calls/sysparam.h b/libc/stdio/sysparam.h similarity index 75% rename from libc/calls/sysparam.h rename to libc/stdio/sysparam.h index 865a53bf5..1cdcb44fc 100644 --- a/libc/calls/sysparam.h +++ b/libc/stdio/sysparam.h @@ -1,5 +1,5 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_SYSPARAM_H_ -#define COSMOPOLITAN_LIBC_CALLS_SYSPARAM_H_ +#ifndef COSMOPOLITAN_LIBC_SYSPARAM_H_ +#define COSMOPOLITAN_LIBC_SYSPARAM_H_ #define MAXSYMLINKS 20 #define MAXHOSTNAMELEN 64 @@ -27,6 +27,16 @@ COSMOPOLITAN_C_START_ #define powerof2(n) !(((n)-1) & (n)) #define howmany(n, d) (((n) + ((d)-1)) / (d)) +#ifdef MIN +#undef MIN +#endif +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#ifdef MAX +#undef MAX +#endif +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_SYSPARAM_H_ */ +#endif /* COSMOPOLITAN_LIBC_SYSPARAM_H_ */ diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c index 6211f1cc8..ee0c2b88a 100644 --- a/libc/stdio/tmpfile.c +++ b/libc/stdio/tmpfile.c @@ -57,7 +57,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ FILE *tmpfile(void) { diff --git a/libc/stdio/ungetc.c b/libc/stdio/ungetc.c index 672e9dade..3e3bc3825 100644 --- a/libc/stdio/ungetc.c +++ b/libc/stdio/ungetc.c @@ -20,7 +20,6 @@ /** * Pushes byte back to stream. - * @threadsafe */ int ungetc(int c, FILE *f) { int rc; diff --git a/libc/stdio/ungetwc.c b/libc/stdio/ungetwc.c index 3ec9f03df..5f39cacad 100644 --- a/libc/stdio/ungetwc.c +++ b/libc/stdio/ungetwc.c @@ -20,7 +20,6 @@ /** * Pushes wide character back to stream. - * @threadsafe */ wint_t ungetwc(wint_t c, FILE *f) { wint_t rc; diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c index 5e8a7035a..6a7c10ec8 100644 --- a/libc/stdio/vasprintf.c +++ b/libc/stdio/vasprintf.c @@ -23,7 +23,6 @@ /** * Formats string w/ dynamic memory allocation. * @see xasprintf() for a better API - * @threadsafe */ int vasprintf(char **strp, const char *fmt, va_list va) { va_list vb; diff --git a/libc/stdio/vfprintf_unlocked.c b/libc/stdio/vfprintf_unlocked.c index 9e28a5201..2dce1045e 100644 --- a/libc/stdio/vfprintf_unlocked.c +++ b/libc/stdio/vfprintf_unlocked.c @@ -59,12 +59,11 @@ static int __vfprintf_nbuf(const char *s, struct state *t, size_t n) { for (i = 0; i < n; ++i) { t->b.p[t->b.n++] = s[i]; if (t->b.n == sizeof(t->b.p)) { - if (!fwrite_unlocked(s, 1, t->b.n, t->f)) { + if (!fwrite_unlocked(t->b.p, 1, t->b.n, t->f)) { return -1; } t->b.n = 0; - } - if (ckd_add(&t->n, t->n, 1)) { + } else if (ckd_add(&t->n, t->n, 1)) { return eoverflow(); } } diff --git a/libc/str/dosdatetimetounix.c b/libc/str/dosdatetimetounix.c index 158b65a10..b6fb7fc48 100644 --- a/libc/str/dosdatetimetounix.c +++ b/libc/str/dosdatetimetounix.c @@ -26,7 +26,7 @@ * @note type signature supports dates greater than 2100 * @see PKZIP, FAT */ -int64_t DosDateTimeToUnix(unsigned date, unsigned time) { +int64_t DosDateTimeToUnix(uint32_t date, uint32_t time) { unsigned year, month, day, hour, minute, second, yday, leap; year = ((date & 0xfffffe00) >> 9) + 1980 - 1900; month = MAX(1, MIN(12, (date & 0x01e0) >> 5)); diff --git a/libc/str/getzipcfiletimestamps.c b/libc/str/getzipcfiletimestamps.c index 12640aa8f..44d0c0a3b 100644 --- a/libc/str/getzipcfiletimestamps.c +++ b/libc/str/getzipcfiletimestamps.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/zip.internal.h" static inline int pop(int x) { diff --git a/libc/str/str.mk b/libc/str/str.mk index da938328b..e9b5f4166 100644 --- a/libc/str/str.mk +++ b/libc/str/str.mk @@ -75,6 +75,7 @@ o/$(MODE)/libc/str/iswseparator.o: private \ CFLAGS += \ -fno-jump-tables +# ensure that division is optimized o/$(MODE)/libc/str/bcmp.o \ o/$(MODE)/libc/str/strcmp.o \ o/$(MODE)/libc/str/windowsdurationtotimeval.o \ diff --git a/libc/str/strtok.c b/libc/str/strtok.c index 941029a3d..740d8e801 100644 --- a/libc/str/strtok.c +++ b/libc/str/strtok.c @@ -25,7 +25,7 @@ * @param sep is a NUL-terminated set of bytes to consider separators * @return pointer to next token or NULL for end * @see strtok_r() and strsep() for superior functions - * @notasyncsignalsafe + * @threadunsafe */ char *strtok(char *s, const char *sep) { static char *state; diff --git a/libc/str/timespectowindowstime.c b/libc/str/timespectowindowstime.c index 5e118e3d8..439cd0dc1 100644 --- a/libc/str/timespectowindowstime.c +++ b/libc/str/timespectowindowstime.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" int64_t TimeSpecToWindowsTime(struct timespec t) { return t.tv_nsec / 100 + (t.tv_sec + MODERNITYSECONDS) * HECTONANOSECONDS; diff --git a/libc/str/timevaltowindowstime.c b/libc/str/timevaltowindowstime.c index ee32ad900..dcf65fe20 100644 --- a/libc/str/timevaltowindowstime.c +++ b/libc/str/timevaltowindowstime.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" int64_t TimeValToWindowsTime(struct timeval t) { return t.tv_usec * 10 + (t.tv_sec + MODERNITYSECONDS) * HECTONANOSECONDS; diff --git a/libc/str/windowsdurationtotimespec.c b/libc/str/windowsdurationtotimespec.c index b1b5c3ef8..1426c5219 100644 --- a/libc/str/windowsdurationtotimespec.c +++ b/libc/str/windowsdurationtotimespec.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" struct timespec WindowsDurationToTimeSpec(int64_t x) { return (struct timespec){x / HECTONANOSECONDS, x % HECTONANOSECONDS * 100}; diff --git a/libc/str/windowsdurationtotimeval.c b/libc/str/windowsdurationtotimeval.c index 5e7f1110a..6cbf32bde 100644 --- a/libc/str/windowsdurationtotimeval.c +++ b/libc/str/windowsdurationtotimeval.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" struct timeval WindowsDurationToTimeVal(int64_t x) { return (struct timeval){x / HECTONANOSECONDS, x % HECTONANOSECONDS / 10}; diff --git a/libc/str/windowstimetotimespec.c b/libc/str/windowstimetotimespec.c index a87a575f3..8b116265b 100644 --- a/libc/str/windowstimetotimespec.c +++ b/libc/str/windowstimetotimespec.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" /** * Converts Windows COBOL timestamp to UNIX epoch in nanoseconds. diff --git a/libc/str/windowstimetotimeval.c b/libc/str/windowstimetotimeval.c index 615897b4f..ad4139c29 100644 --- a/libc/str/windowstimetotimeval.c +++ b/libc/str/windowstimetotimeval.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" /** * Converts Windows COBOL timestamp to UNIX epoch in microseconds. diff --git a/libc/sysv/calls/sys_clock_gettime.S b/libc/sysv/calls/sys_clock_gettime.S deleted file mode 100644 index 42653a63f..000000000 --- a/libc/sysv/calls/sys_clock_gettime.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall sys_clock_gettime,0x1ab0570e8ffff0e4,113,4095,globl,hidden diff --git a/libc/sysv/calls/sys_gettimeofday.S b/libc/sysv/calls/sys_gettimeofday.S deleted file mode 100644 index 77ee3fbd8..000000000 --- a/libc/sysv/calls/sys_gettimeofday.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall sys_gettimeofday,0x1a20430742074060,169,116,globl,hidden diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index cb66ccd64..f2d8ab620 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -584,7 +584,7 @@ syscon clock CLOCK_MONOTONIC_PRECISE 1 1 1 6 11 3 3 1 # syscon clock CLOCK_MONOTONIC_FAST 1 1 1 6 12 3 3 1 # syscon clock CLOCK_MONOTONIC_COARSE 6 6 1 6 12 3 3 1 # Linux 2.6.32+; bsd consensus; not available on RHEL5 syscon clock CLOCK_MONOTONIC_RAW 4 4 127 4 127 127 127 127 # actually monotonic; not subject to NTP adjustments; Linux 2.6.28+; XNU/NT/FreeBSD/OpenBSD faked; not available on RHEL5 -syscon clock CLOCK_PROCESS_CPUTIME_ID 2 2 127 12 15 2 0x40000000 127 # +syscon clock CLOCK_PROCESS_CPUTIME_ID 2 2 127 12 15 2 0x40000000 127 # NetBSD lets you bitwise a PID into clockid_t syscon clock CLOCK_THREAD_CPUTIME_ID 3 3 127 16 14 4 0x20000000 127 # syscon clock CLOCK_PROF 127 127 127 127 2 127 2 127 # syscon clock CLOCK_BOOTTIME 7 7 127 127 127 6 127 127 # diff --git a/libc/sysv/consts/ENOBUFS.S b/libc/sysv/consts/ENOBUFS.S index 164795804..04fd4102d 100644 --- a/libc/sysv/consts/ENOBUFS.S +++ b/libc/sysv/consts/ENOBUFS.S @@ -1,2 +1,5 @@ #include "libc/sysv/consts/syscon.internal.h" .syscon errno,ENOBUFS,105,105,55,55,55,55,55,10055 +#ifdef __x86_64__ +.yoink kDos2Errno.ENOBUFS +#endif diff --git a/libc/sysv/syscall.S b/libc/sysv/syscall.S deleted file mode 100644 index 0c8c490fe..000000000 --- a/libc/sysv/syscall.S +++ /dev/null @@ -1,85 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/macros.internal.h" -.privileged - -// Performs raw System Five system call. -// -// This function provides a direct path into system call support -// that's friendly to C code, since it doesn't need an intermediate -// thunk. It only supports arities up to six, since there's no way -// to do more safely; this isn't a problem with Linux, although -// certain BSD calls may not be available. -// -// @param %rdi is system call ordinal, which isn't translated, -// and must be correct for the underlying host system -// @param %rsi,%rdx,%rcx,%r8,%r9 may supply parameters 1 through 5 -// @param sixth is optionally pushed on the stack before call -// @return %rax has result, or -1 w/ errno on failure - .ftrace1 -syscall: - .ftrace2 - push %rbp - mov %rsp,%rbp - -// slide arguments into their right places - mov %rdi,%rax // nr - mov %rsi,%rdi // arg 1 - mov %rdx,%rsi // arg 2 - mov %rcx,%rdx // arg 3 - mov %r8,%rcx // arg 4 - mov %r9,%r8 // arg 5 - mov 16(%rbp),%r9 // arg 6 - push 32(%rbp) // arg 8 - push 24(%rbp) // arg 7 - -// convert from consts.sh to syscalls.sh encoding - push %rcx - mov __hostos(%rip),%cl - test $_HOSTLINUX,%cl - jnz 2f -1: test $_HOSTFREEBSD,%cl - jz 1f - shl $4*7,%rax - jmp 2f -1: test $_HOSTOPENBSD,%cl - jz 1f - shl $4*10,%rax - jmp 2f -1: test $_HOSTNETBSD,%cl - jz 1f - shl $4*13,%rax - jmp 2f -1: test $_HOSTXNU,%cl - jz 2f - mov %eax,%ecx - and $0x0f000000,%ecx - and $0x00000fff,%eax - shl $4*3,%eax - or %ecx,%eax -2: pop %rcx - -// trigger the system call - call *__systemfive(%rip) - -// clean up stack and return - leave - ret - .endfn syscall,globl diff --git a/libc/nexgen32e/setlongerjmp.S b/libc/sysv/syscall2.S similarity index 68% rename from libc/nexgen32e/setlongerjmp.S rename to libc/sysv/syscall2.S index b40fcc57c..04de25d07 100644 --- a/libc/nexgen32e/setlongerjmp.S +++ b/libc/sysv/syscall2.S @@ -1,7 +1,7 @@ /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -18,46 +18,33 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -// Saves caller CPU state to cacheline. +// Invokes system call w/ arity of two. // -// @param rdi points to jmp_buf -// @return eax contains 0 when set, and 1 if jumped -// @return rdx contains value passed to longerjmp() -// @returnstwice - .ftrace1 -setlongerjmp: - .ftrace2 -#ifdef __x86_64__ - lea 8(%rsp),%rax - mov %rax,(%rdi) - mov %rbx,8(%rdi) - mov %rbp,16(%rdi) - mov %r12,24(%rdi) - mov %r13,32(%rdi) - mov %r14,40(%rdi) - mov %r15,48(%rdi) - mov (%rsp),%rax - mov %rax,56(%rdi) - xor %eax,%eax - xor %edx,%edx +// This function has three parameters. The first two are for +// args passed along to the system call. The third's for the +// the magic number, indicating which system call is called. +// +// The returned value follows the Linux kernel convention ie +// errors are returned as `-errno`, rather than -1 w/ errno. +__syscall2: +#ifdef __aarch64__ + mov x8,x2 // syscall number (linux) + mov x16,x2 // syscall number (xnu) + mov x9,0 // clear carry flag + adds x9,x9,0 // clear carry flag + svc 0 + bcs 1f ret -#elif defined(__aarch64__) - stp x19,x20,[x0,#0] - stp x21,x22,[x0,#16] - stp x23,x24,[x0,#32] - stp x25,x26,[x0,#48] - stp x27,x28,[x0,#64] - stp x29,x30,[x0,#80] - mov x2,sp - str x2,[x0,#104] - stp d8,d9,[x0,#112] - stp d10,d11,[x0,#128] - stp d12,d13,[x0,#144] - stp d14,d15,[x0,#160] - mov x0,#0 - mov x1,#0 +1: neg x0,x0 ret +#elif defined(__x86_64__) + mov %edx,%eax // arg3 -> syscall number + clc // linux saves carry flag + syscall // bsds set carry on errs + jnc 1f + neg %rax // normalizes to system v +1: ret #else #error "unsupported architecture" #endif - .endfn setlongerjmp,globl + .endfn __syscall2,globl diff --git a/libc/nexgen32e/longerjmp.S b/libc/sysv/syscall3.S similarity index 68% rename from libc/nexgen32e/longerjmp.S rename to libc/sysv/syscall3.S index 129ee4b93..8316971b9 100644 --- a/libc/nexgen32e/longerjmp.S +++ b/libc/sysv/syscall3.S @@ -1,7 +1,7 @@ /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -18,41 +18,33 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -// Loads previously saved processor state. +// Invokes system call w/ arity of three. // -// @param rdi points to the jmp_buf -// @param rsi is returned by setlongerjmp() invocation -// @noreturn - .ftrace1 -longerjmp: - .ftrace2 -#ifdef __x86_64__ - mov $1,%eax - mov %rsi,%rdx - mov (%rdi),%rsp - mov 8(%rdi),%rbx - mov 16(%rdi),%rbp - mov 24(%rdi),%r12 - mov 32(%rdi),%r13 - mov 40(%rdi),%r14 - mov 48(%rdi),%r15 - jmp *56(%rdi) -#elif defined(__aarch64__) - ldp x19,x20,[x0,#0] - ldp x21,x22,[x0,#16] - ldp x23,x24,[x0,#32] - ldp x25,x26,[x0,#48] - ldp x27,x28,[x0,#64] - ldp x29,x30,[x0,#80] - ldr x2,[x0,#104] - mov sp,x2 - ldp d8 ,d9,[x0,#112] - ldp d10,d11,[x0,#128] - ldp d12,d13,[x0,#144] - ldp d14,d15,[x0,#160] - mov x0,x1 - br x30 +// This function takes four params. The first three are for +// args passed along to the system call. The 4th is for the +// the magic number, indicating which system call is called +// +// The return value follows the Linux Kernel (System V) ABI +// where -errno is returned, rather than doing -1 w/ errno. +__syscall3: +#ifdef __aarch64__ + mov x8,x3 // syscall number (linux) + mov x16,x3 // syscall number (xnu) + mov x9,0 // clear carry flag + adds x9,x9,0 // clear carry flag + svc 0 + bcs 1f + ret +1: neg x0,x0 + ret +#elif defined(__x86_64__) + mov %ecx,%eax // arg4 -> syscall number + clc // linux saves carry flag + syscall // bsds set carry on errs + jnc 1f + neg %rax // normalizes to system v +1: ret #else #error "unsupported architecture" #endif - .endfn longerjmp,globl + .endfn __syscall3,globl diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index adfbea1ee..cfe3afb2a 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -127,7 +127,6 @@ scall sys_unlink 0x00a00a00a200a057 0x0b5 globl hidden scall sys_fchmod 0x07c07c07c207c05b 0x034 globl hidden scall sys_fchown 0x07b07b07b207b05d 0x037 globl hidden # @asyncsignalsafe scall sys_umask 0x03c03c03c203c05f 0x0a6 globl hidden -scall sys_gettimeofday 0x1a20430742074060 0x0a9 globl hidden # xnu esi/edx=0 scall sys_getrlimit 0x0c20c20c220c2061 0x0a3 globl hidden scall __sys_getrusage 0x1bd0130752075062 0x0a5 globl hidden scall sys_sysinfo 0xfffffffffffff063 0x0b3 globl hidden @@ -251,7 +250,6 @@ scall sys_ktimer_getoverrun 0xffffff0effffffff 0xfff globl # no wrapper scall sys_ktimer_gettime 0xffffff0eefffffff 0xfff globl # no wrapper scall sys_ktimer_settime 0xffffff0edfffffff 0xfff globl # no wrapper scall sys_clock_settime 0x1ac0580e9ffff0e3 0x070 globl hidden # no wrapper -scall sys_clock_gettime 0x1ab0570e8ffff0e4 0x071 globl hidden # Linux 2.6+ (c. 2003); XNU uses magic address scall sys_clock_getres 0x1ad0590eaffff0e5 0x072 globl hidden scall sys_mbind 0xfffffffffffff0ed 0x0eb globl # no wrapper; numa numa yeah scall set_mempolicy 0xfffffffffffff0ee 0x0ed globl diff --git a/libc/sysv/sysv.mk b/libc/sysv/sysv.mk index 00a96f3e8..9ea8e042a 100644 --- a/libc/sysv/sysv.mk +++ b/libc/sysv/sysv.mk @@ -38,7 +38,8 @@ LIBC_SYSV_A_FILES := \ libc/sysv/syslib.S \ libc/sysv/syscount.S \ libc/sysv/restorert.S \ - libc/sysv/syscall.S \ + libc/sysv/syscall2.S \ + libc/sysv/syscall3.S \ libc/sysv/systemfive.S \ libc/sysv/sysret.c \ libc/sysv/sysv.c \ @@ -165,6 +166,10 @@ o/$(MODE)/libc/sysv/syslib.o: libc/sysv/syslib.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< o/$(MODE)/libc/sysv/syscount.o: libc/sysv/syscount.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/libc/sysv/syscall2.o: libc/sysv/syscall2.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/libc/sysv/syscall3.o: libc/sysv/syscall3.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< o/$(MODE)/libc/sysv/restorert.o: libc/sysv/restorert.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< o/$(MODE)/libc/sysv/calls/%.o: libc/sysv/calls/%.S diff --git a/libc/testlib/ezbenchcontrol.c b/libc/testlib/ezbenchcontrol.c index f6526ddd2..f3775c4db 100644 --- a/libc/testlib/ezbenchcontrol.c +++ b/libc/testlib/ezbenchcontrol.c @@ -19,6 +19,8 @@ #include "libc/calls/calls.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" @@ -26,6 +28,7 @@ static bool once; static double g_ezbenchcontrol; double __testlib_ezbenchcontrol(void) { + char host[64]; char ibuf[12]; int Core, Tries, Interrupts; if (!once) { @@ -41,9 +44,11 @@ double __testlib_ezbenchcontrol(void) { if (Tries == 10) { tinyprint(2, "warning: failed to accurately benchmark control\n"); } + strcpy(host, "unknown"); + gethostname(host, 64); FormatInt32(ibuf, g_ezbenchcontrol); - tinyprint(2, "will subtract benchmark overhead of ", ibuf, " cycles\n\n", - NULL); + tinyprint(2, "benchmarks on ", host, " (", __describe_os(), + "; overhead of ", ibuf, " cycles)\n", NULL); once = true; } return g_ezbenchcontrol; diff --git a/libc/thread/makecontext.c b/libc/thread/makecontext.c index 02af6ea57..5014c288c 100644 --- a/libc/thread/makecontext.c +++ b/libc/thread/makecontext.c @@ -88,7 +88,6 @@ static void runcontext(struct Gadget *call, ucontext_t *link) { * which if null will result in pthread_exit() being called * @param argc is effectively ignored (see notes above) * @see setcontext(), getcontext(), swapcontext() - * @threadsafe */ void makecontext(ucontext_t *uc, void func(), int argc, ...) { va_list va; diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 275dfa5e8..51586acd3 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -335,7 +335,6 @@ static const char *DescribeHandle(char buf[12], errno_t err, pthread_t *th) { * @raise EPERM if scheduling policy was requested and user account * isn't authorized to use it * @returnserrno - * @threadsafe */ errno_t pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { diff --git a/libc/thread/pthread_detach.c b/libc/thread/pthread_detach.c index ac479c9ca..336f7f84f 100644 --- a/libc/thread/pthread_detach.c +++ b/libc/thread/pthread_detach.c @@ -62,7 +62,6 @@ static errno_t pthread_detach_impl(struct PosixThread *pt) { * @return 0 on success, or errno with error * @raise EINVAL if `thread` isn't joinable * @returnserrno - * @threadsafe */ errno_t pthread_detach(pthread_t thread) { struct PosixThread *pt = (struct PosixThread *)thread; diff --git a/libc/thread/pthread_exit.c b/libc/thread/pthread_exit.c index 62088a458..f1c46ebad 100644 --- a/libc/thread/pthread_exit.c +++ b/libc/thread/pthread_exit.c @@ -94,7 +94,6 @@ void _pthread_unkey(struct CosmoTib *tib) { * destructors is also undefined. * * @param rc is reported later to pthread_join() - * @threadsafe * @noreturn */ wontreturn void pthread_exit(void *rc) { diff --git a/libc/thread/pthread_join.c b/libc/thread/pthread_join.c index 233a4372b..3906c3fa2 100644 --- a/libc/thread/pthread_join.c +++ b/libc/thread/pthread_join.c @@ -35,7 +35,6 @@ * @raise ECANCELED if calling thread was cancelled in masked mode * @cancellationpoint * @returnserrno - * @threadsafe */ errno_t pthread_join(pthread_t thread, void **value_ptr) { return pthread_timedjoin_np(thread, value_ptr, 0); diff --git a/libc/thread/pthread_timedjoin_np.c b/libc/thread/pthread_timedjoin_np.c index d636ac926..ceb68d9c0 100644 --- a/libc/thread/pthread_timedjoin_np.c +++ b/libc/thread/pthread_timedjoin_np.c @@ -99,7 +99,6 @@ static errno_t _pthread_wait(atomic_int *ctid, struct timespec *abstime) { * @raise EBUSY if `abstime` deadline elapsed * @cancellationpoint * @returnserrno - * @threadsafe */ errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr, struct timespec *abstime) { diff --git a/libc/thread/pthread_tryjoin_np.c b/libc/thread/pthread_tryjoin_np.c index ae5f02881..896426317 100644 --- a/libc/thread/pthread_tryjoin_np.c +++ b/libc/thread/pthread_tryjoin_np.c @@ -35,7 +35,6 @@ * @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_open.c b/libc/thread/sem_open.c index a73269b80..eafd0a37d 100644 --- a/libc/thread/sem_open.c +++ b/libc/thread/sem_open.c @@ -165,7 +165,6 @@ static struct Semaphore *sem_open_get(const sem_t *sem, * @raise ENFILE if system-wide file limit has been reached * @raise ENOMEM if we require more vespene gas * @raise EINTR if signal handler was called - * @threadsafe */ sem_t *sem_open(const char *name, int oflag, ...) { sem_t *sem; diff --git a/libc/thread/tls.h b/libc/thread/tls.h index f0677b4fc..28fba51e8 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -3,9 +3,8 @@ #define TLS_ALIGNMENT 64 -#define TIB_FLAG_TIME_CRITICAL 1 -#define TIB_FLAG_VFORKED 2 -#define TIB_FLAG_WINCRASHING 4 +#define TIB_FLAG_VFORKED 1 +#define TIB_FLAG_WINCRASHING 2 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ diff --git a/libc/time/ctime.c b/libc/time/ctime.c index c77c453d8..f0e90fbdb 100644 --- a/libc/time/ctime.c +++ b/libc/time/ctime.c @@ -2,6 +2,10 @@ #include "libc/time/struct/tm.h" #include "libc/time/time.h" +/** + * Represents time as string. + * @threadunsafe + */ char *ctime(const time_t *timep) { /* ** Section 4.12.3.2 of X3.159-1989 requires that diff --git a/libc/time/iso8601.c b/libc/time/iso8601.c index a131124ea..0f12b8ffc 100644 --- a/libc/time/iso8601.c +++ b/libc/time/iso8601.c @@ -55,7 +55,6 @@ * @return pointer to nul terminator within `p`, cf. stpcpy() * @see iso8601us() for microsecond timestamps * @asyncsignalsafe - * @threadsafe */ char *iso8601(char p[hasatleast 20], struct tm *tm) { int x; diff --git a/libc/time/iso8601us.c b/libc/time/iso8601us.c index 1fb24f501..c624aa363 100644 --- a/libc/time/iso8601us.c +++ b/libc/time/iso8601us.c @@ -62,7 +62,6 @@ * @return pointer to nul terminator within `p`, cf. stpcpy() * @see iso8601() if microsecond resolution isn't desirable * @asyncsignalsafe - * @threadsafe */ char *iso8601us(char p[hasatleast 27], struct tm *tm, long ns) { p = iso8601(p, tm); diff --git a/libc/time/localtime.c b/libc/time/localtime.c index a69e31b5c..26e2dab19 100644 --- a/libc/time/localtime.c +++ b/libc/time/localtime.c @@ -1615,6 +1615,9 @@ gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset, * Re-entrant version of gmtime. */ +/** + * Converts UNIX timestamp to broken-down representation. + */ struct tm * gmtime_r(const time_t *timep, struct tm *tmp) { @@ -1622,6 +1625,10 @@ gmtime_r(const time_t *timep, struct tm *tmp) return gmtsub(gmtptr, timep, 0, tmp); } +/** + * Converts UNIX timestamp to broken-down representation. + * @threadunsafe (see gmtime_r) + */ struct tm * gmtime(const time_t *timep) { diff --git a/libc/time/time.h b/libc/time/time.h index 3e9a0c1d2..42e03a53f 100644 --- a/libc/time/time.h +++ b/libc/time/time.h @@ -15,6 +15,7 @@ char *ctime_r(const int64_t *, char[hasatleast 26]); double difftime(int64_t, int64_t) pureconst; int64_t posix2time(int64_t) pureconst; int64_t time2posix(int64_t) pureconst; +int stime(const int64_t *); void tzset(void); #ifdef _COSMO_SOURCE diff --git a/libc/time/times.c b/libc/time/times.c index d31759135..cfbc20f79 100644 --- a/libc/time/times.c +++ b/libc/time/times.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/tms.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/accounting.h" #include "libc/nt/runtime.h" #include "libc/runtime/clktck.h" diff --git a/libc/x/xload.c b/libc/x/xload.c index 89dae7e9c..e0e0e3f53 100644 --- a/libc/x/xload.c +++ b/libc/x/xload.c @@ -39,7 +39,6 @@ * @param n is byte length of deflated data * @param m is byte length of inflated data * @return pointer to inflated data - * @threadsafe */ void *xload(_Atomic(void *) *a, const void *p, size_t n, size_t m) { void *r, *z; diff --git a/test/libc/calls/clock_gettime_test.c b/test/libc/calls/clock_gettime_test.c index ec6079029..bff8c1792 100644 --- a/test/libc/calls/clock_gettime_test.c +++ b/test/libc/calls/clock_gettime_test.c @@ -16,7 +16,6 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" #include "libc/calls/internal.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" @@ -32,20 +31,23 @@ #include "libc/testlib/testlib.h" #include "libc/time/time.h" +TEST(clock_gettime, nullResult_validatesClockParam) { + ASSERT_SYS(EINVAL, -1, clock_gettime(666, 0)); +} + TEST(clock_gettime, test) { struct timespec ts = {0}; ASSERT_EQ(0, clock_gettime(0, &ts)); ASSERT_NE(0, ts.tv_sec); ASSERT_NE(0, ts.tv_nsec); -#ifndef __aarch64__ - bool isfast; - // we support vdso on aarch64 but qemu-aarch64 won't let us test it - if (IsLinux() && __is_linux_2_6_23()) { - ASSERT_GT((intptr_t)__clock_gettime_get(&isfast), - getauxval(AT_SYSINFO_EHDR)); - ASSERT_TRUE(isfast); - } -#endif +} + +TEST(clock_gettime, testClockRealtime) { + struct timeval tv; + struct timespec ts; + EXPECT_NE(-1, gettimeofday(&tv, NULL)); + EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts)); + EXPECT_LT((unsigned)ABS(ts.tv_sec - tv.tv_sec), 5u); } BENCH(clock_gettime, bench) { @@ -54,25 +56,21 @@ BENCH(clock_gettime, bench) { gettimeofday(&tv, 0); // trigger init clock_gettime(0, &ts); // trigger init EZBENCH2("rdtsc", donothing, rdtsc()); - EZBENCH2("gettimeofday", donothing, gettimeofday(&tv, 0)); - EZBENCH2("timespec_real", donothing, timespec_real()); - EZBENCH2("clock_gettime 0", donothing, - clock_gettime(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("clock_gettime 1", donothing, + EZBENCH2("clock_gettime(mono)", donothing, clock_gettime(CLOCK_MONOTONIC_FAST, &ts)); - EZBENCH2("__clock_gettime 0", donothing, - __clock_gettime(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("__clock_gettime 1", donothing, - __clock_gettime(CLOCK_MONOTONIC_FAST, &ts)); + EZBENCH2("clock_gettime(real)", donothing, + clock_gettime(CLOCK_REALTIME_FAST, &ts)); + EZBENCH2("timespec_real", donothing, timespec_real()); + EZBENCH2("gettimeofday", donothing, gettimeofday(&tv, 0)); if (IsWindows()) { - EZBENCH2("sys_clock_gettime 0", donothing, + EZBENCH2("sys_clock_gettime r", donothing, sys_clock_gettime_nt(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("sys_clock_gettime 1", donothing, + EZBENCH2("sys_clock_gettime m", donothing, sys_clock_gettime_nt(CLOCK_MONOTONIC_FAST, &ts)); } else { - EZBENCH2("sys_clock_gettime 0", donothing, + EZBENCH2("sys_clock_gettime r", donothing, sys_clock_gettime(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("sys_clock_gettime 1", donothing, + EZBENCH2("sys_clock_gettime m", donothing, sys_clock_gettime(CLOCK_MONOTONIC_FAST, &ts)); } } diff --git a/test/libc/calls/commandv_test.c b/test/libc/calls/commandv_test.c index 85810a5d7..0b0a24122 100644 --- a/test/libc/calls/commandv_test.c +++ b/test/libc/calls/commandv_test.c @@ -48,31 +48,41 @@ void TearDown(void) { } TEST(commandv, testPathSearch) { - EXPECT_SYS(0, 0, touch("bin/sh", 0755)); + EXPECT_SYS(0, 3, creat("bin/sh", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("bin/sh", commandv("sh", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSlashes_wontSearchPath_butChecksAccess) { - EXPECT_SYS(0, 0, touch("home/sh.com", 0755)); + EXPECT_SYS(0, 3, creat("home/sh.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("home/sh.com", commandv("home/sh.com", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSameDir_doesntHappenByDefaultUnlessItsWindows) { - EXPECT_SYS(0, 0, touch("bog.com", 0755)); + EXPECT_SYS(0, 3, creat("bog.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ(NULL, commandv("bog.com", pathbuf, sizeof(pathbuf))); EXPECT_EQ(ENOENT, errno); } TEST(commandv, testSameDir_willHappenWithColonBlank) { ASSERT_NE(-1, setenv("PATH", "bin:", true)); - EXPECT_SYS(0, 0, touch("bog.com", 0755)); + EXPECT_SYS(0, 3, creat("bog.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("bog.com", commandv("bog.com", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSameDir_willHappenWithColonBlank2) { ASSERT_NE(-1, setenv("PATH", ":bin", true)); - EXPECT_SYS(0, 0, touch("bog.com", 0755)); + EXPECT_SYS(0, 3, creat("bog.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("bog.com", commandv("bog.com", pathbuf, sizeof(pathbuf))); } diff --git a/test/libc/calls/open_test.c b/test/libc/calls/open_test.c index 0ef42909f..3d5309351 100644 --- a/test/libc/calls/open_test.c +++ b/test/libc/calls/open_test.c @@ -343,7 +343,7 @@ TEST(open, readOnlyCreatMode) { char buf[8]; struct stat st; ASSERT_SYS(0, 3, open("x", O_RDWR | O_CREAT | O_TRUNC, 0500)); - ASSERT_SYS(0, 2, pwrite(3, "hi", 2, 0)); + ASSERT_SYS(0, 2, pwrite(3, "MZ", 2, 0)); ASSERT_SYS(0, 2, pread(3, buf, 8, 0)); ASSERT_SYS(0, 0, close(3)); ASSERT_SYS(0, 0, stat("x", &st)); @@ -410,13 +410,13 @@ TEST(open, readonlyCreateMode_dontChangeStatusIfExists) { char buf[8]; struct stat st; ASSERT_SYS(0, 3, creat("wut", 0700)); - ASSERT_SYS(0, 2, pwrite(3, "hi", 2, 0)); + ASSERT_SYS(0, 2, pwrite(3, "MZ", 2, 0)); ASSERT_SYS(0, 0, close(3)); // since the file already exists, unix doesn't change read-only ASSERT_SYS(0, 3, open("wut", O_CREAT | O_TRUNC | O_RDWR, 0500)); ASSERT_SYS(0, 0, pread(3, buf, 8, 0)); ASSERT_SYS(0, 0, fstat(3, &st)); - ASSERT_EQ(0100700, st.st_mode); + ASSERT_EQ(0100600, st.st_mode & 0700666); ASSERT_SYS(0, 0, close(3)); } @@ -424,7 +424,7 @@ TEST(open, creatRdonly) { char buf[8]; ASSERT_SYS(EINVAL, -1, open("foo", O_CREAT | O_TRUNC | O_RDONLY, 0700)); ASSERT_SYS(0, 3, open("foo", O_CREAT | O_RDONLY, 0700)); - ASSERT_SYS(EBADF, -1, pwrite(3, "hi", 2, 0)); + ASSERT_SYS(EBADF, -1, pwrite(3, "MZ", 2, 0)); ASSERT_SYS(0, 0, pread(3, buf, 8, 0)); ASSERT_SYS(0, 0, close(3)); } diff --git a/test/libc/calls/sigbus_test.c b/test/libc/calls/sigbus_test.c new file mode 100644 index 000000000..4bb852b7d --- /dev/null +++ b/test/libc/calls/sigbus_test.c @@ -0,0 +1,108 @@ +/*-*- 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 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/ucontext.h" +#include "libc/dce.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/sysconf.h" +#include "libc/sysv/consts/auxv.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "third_party/xed/x86.h" + +volatile int gotsig; +volatile int gotcode; + +void SetUpOnce(void) { + testlib_enable_tmp_setup_teardown(); +} + +void SetUp(void) { + gotsig = 0; +} + +void OnSig(int sig, siginfo_t *si, void *arg) { + ucontext_t *ctx = arg; + gotsig = sig; + gotcode = si->si_code; +#ifdef __aarch64__ + ctx->uc_mcontext.pc += 4; +#elif defined(__x86_64__) + struct XedDecodedInst xedd; + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); + xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); + ctx->uc_mcontext.rip += xedd.length; +#else +#error "unsupported architecture" +#endif /* __x86_64__ */ +} + +TEST(sigbus, test) { + + if (IsWindows()) { + // TODO(jart): Just write a kernel style memory manager from scratch + // for WIN32 and don't depend on their mapping functions + return; + } + + // create a file with less than one page of content + ASSERT_SYS(0, 3, open("foo", O_CREAT | O_RDWR, 0666)); + ASSERT_SYS(0, 2, write(3, "hi", 2)); + + // map two pages of the file into memory + char *map; + long pagesz = getauxval(AT_PAGESZ); + ASSERT_NE(MAP_FAILED, + (map = mmap(0, pagesz * 2, PROT_READ, MAP_PRIVATE, 3, 0))); + + // verify the file content is there + ASSERT_EQ('h', map[0]); + ASSERT_EQ('i', map[1]); + + // memory reads past file eof on first page get zero-filled + ASSERT_EQ(0, map[2]); + + // listen for sigbus + struct sigaction sa; + struct sigaction oldsa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = OnSig; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, &oldsa); + + // memory reads past file eof on subsequent pages cause page fault to sigbus + volatile char x = map[pagesz]; + (void)x; + + // verify the signal was raised + EXPECT_EQ(SIGBUS, gotsig); + EXPECT_EQ(BUS_ADRERR, gotcode); + + // clean up + sigaction(SIGBUS, &oldsa, 0); + munmap(map, pagesz * 2); +} diff --git a/test/libc/calls/stat_test.c b/test/libc/calls/stat_test.c index e505cc288..1e0427799 100644 --- a/test/libc/calls/stat_test.c +++ b/test/libc/calls/stat_test.c @@ -24,6 +24,7 @@ #include "libc/calls/struct/stat.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/limits.h" #include "libc/mem/gc.internal.h" #include "libc/nt/files.h" #include "libc/runtime/runtime.h" @@ -97,11 +98,19 @@ TEST(stat, zipos) { EXPECT_SYS(0, 0, stat("/zip/.python/", &st)); } +BENCH(fstat, bench) { + struct stat st; + ASSERT_SYS(0, 3, creat("foo.sh", 0777)); + ASSERT_SYS(0, 2, write(3, "#!", 2)); + EZBENCH2("fstat() fs", donothing, fstat(3, &st)); + ASSERT_SYS(0, 0, close(3)); +} + BENCH(stat, bench) { + char path[PATH_MAX]; struct stat st; union metastat ms; EXPECT_SYS(0, 0, makedirs(".python/test", 0755)); - EZBENCH2("__stat2cosmo", donothing, __stat2cosmo(&st, &ms)); EXPECT_SYS(0, 0, touch(".python/test/" "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", @@ -114,4 +123,6 @@ BENCH(stat, bench) { stat("/zip/.python/test/" "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", &st)); + EZBENCH2("getcwd()", donothing, getcwd(path, PATH_MAX)); + EZBENCH2("__stat2cosmo", donothing, __stat2cosmo(&st, &ms)); } diff --git a/test/libc/fmt/timevaltofiletime_test.c b/test/libc/fmt/timevaltofiletime_test.c index 720043cd0..2ed2f8ea4 100644 --- a/test/libc/fmt/timevaltofiletime_test.c +++ b/test/libc/fmt/timevaltofiletime_test.c @@ -16,11 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/time/time.h" #include "libc/calls/struct/timeval.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/struct/filetime.h" #include "libc/testlib/testlib.h" -#include "libc/time/time.h" TEST(TimeValToFileTime, roundTrip) { struct timeval tv1, tv2; diff --git a/test/libc/proc/posix_spawn_test.c b/test/libc/proc/posix_spawn_test.c index a9ad58283..543620541 100644 --- a/test/libc/proc/posix_spawn_test.c +++ b/test/libc/proc/posix_spawn_test.c @@ -128,31 +128,6 @@ TEST(posix_spawn, ape) { ASSERT_EQ(42, WEXITSTATUS(ws)); } -TEST(posix_spawn, withoutComExtension_stillWorks) { - int ws, pid; - char *prog = "./life"; - char *args[] = {prog, 0}; - char *envs[] = {0}; - testlib_extract("/zip/life.com", prog, 0755); - ASSERT_EQ(0, posix_spawn(&pid, prog, NULL, NULL, args, envs)); - ASSERT_NE(-1, waitpid(pid, &ws, 0)); - ASSERT_TRUE(WIFEXITED(ws)); - ASSERT_EQ(42, WEXITSTATUS(ws)); -} - -TEST(posix_spawn, execveAutoAppendsComSuffix) { - if (!IsWindows()) return; // only on windows for now - int ws, pid; - char *prog = "./life"; - char *args[] = {prog, 0}; - char *envs[] = {0}; - testlib_extract("/zip/life.com", "life.com", 0755); - ASSERT_EQ(0, posix_spawn(&pid, prog, NULL, NULL, args, envs)); - ASSERT_NE(-1, waitpid(pid, &ws, 0)); - ASSERT_TRUE(WIFEXITED(ws)); - ASSERT_EQ(42, WEXITSTATUS(ws)); -} - TEST(posix_spawn, elf) { if (IsXnu() || IsWindows() || IsMetal()) return; int ws, pid; diff --git a/test/libc/time/clock_gettime_test.c b/test/libc/time/clock_gettime_test.c deleted file mode 100644 index 05eaf6c75..000000000 --- a/test/libc/time/clock_gettime_test.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timespec.h" -#include "libc/fmt/conv.h" -#include "libc/macros.internal.h" -#include "libc/mem/gc.internal.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/clock.h" -#include "libc/testlib/testlib.h" -#include "libc/time/time.h" -#include "libc/x/x.h" - -TEST(clock_gettime, testClockRealtime) { - struct timeval tv; - struct timespec ts; - EXPECT_NE(-1, gettimeofday(&tv, NULL)); - EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts)); - EXPECT_LT((unsigned)ABS(ts.tv_sec - tv.tv_sec), 5u); -} diff --git a/third_party/chibicc/alloc.c b/third_party/chibicc/alloc.c index c33919a7c..13f08b087 100644 --- a/third_party/chibicc/alloc.c +++ b/third_party/chibicc/alloc.c @@ -16,8 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" #include "third_party/chibicc/chibicc.h" long alloc_node_count; @@ -26,7 +26,7 @@ long alloc_obj_count; long alloc_type_count; wontreturn void __oom_hook(size_t request) { - fprintf(stderr, "error: chibicc ran out of memory\n"); + tinyprint(2, "error: chibicc ran out of memory\n", NULL); exit(1); } diff --git a/third_party/libcxx/filesystem_common.hh b/third_party/libcxx/filesystem_common.hh index 42f665183..c2686af0b 100644 --- a/third_party/libcxx/filesystem_common.hh +++ b/third_party/libcxx/filesystem_common.hh @@ -18,6 +18,7 @@ #include "third_party/libcxx/cstdlib" #include "libc/calls/struct/stat.h" #include "libc/sysv/consts/at.h" +#include "libc/calls/struct/timeval.h" #include "third_party/libcxx/climits" #define _LIBCPP_USE_UTIMENSAT diff --git a/third_party/libcxx/thread.cc b/third_party/libcxx/thread.cc index e6c7420d6..179f5eddb 100644 --- a/third_party/libcxx/thread.cc +++ b/third_party/libcxx/thread.cc @@ -29,7 +29,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/third_party/musl/grp.c b/third_party/musl/grp.c index a1a5e06be..ec9093676 100644 --- a/third_party/musl/grp.c +++ b/third_party/musl/grp.c @@ -215,14 +215,27 @@ static struct GetgrentState { struct group gr; } g_getgrent[1]; +/** + * Closes group database. + * @threadunsafe + */ void endgrent() { setgrent(); } + +/** + * Rewinds to beginning of group database. + * @threadunsafe + */ void setgrent() { if (g_getgrent->f) fclose(g_getgrent->f); g_getgrent->f = 0; } +/** + * Returns successive entries in /etc/group database. + * @threadunsafe + */ struct group *getgrent() { struct group *res; size_t size = 0, nmem = 0; diff --git a/third_party/musl/pwd.c b/third_party/musl/pwd.c index d81ac8238..3964ec2c4 100644 --- a/third_party/musl/pwd.c +++ b/third_party/musl/pwd.c @@ -240,6 +240,7 @@ static struct GetpwentState { * Closes global handle to password database. * * @see getpwent() + * @threadunsafe */ void endpwent(void) @@ -251,6 +252,7 @@ endpwent(void) * Rewinds global handle to password database. * * @see getpwent() + * @threadunsafe */ void setpwent(void) @@ -264,7 +266,8 @@ setpwent(void) * Returns next entry in password database. * * @return pointer to entry static memory, or NULL on EOF - * @see getpwent() + * @see setpwent() + * @threadunsafe */ struct passwd * getpwent() @@ -287,6 +290,7 @@ getpwent() * if `/etc/passwd` doesn't exist, or is fake (e.g. MacOS). * * @return pointer to passwd entry static memory, or NULL if not found + * @threadunsafe */ struct passwd * getpwuid(uid_t uid) @@ -305,6 +309,7 @@ getpwuid(uid_t uid) * if `/etc/passwd` doesn't exist, or is fake (e.g. MacOS). * * @return pointer to passwd entry static memory, or NULL if not found + * @threadunsafe */ struct passwd * getpwnam(const char *name) diff --git a/third_party/nsync/futex.c b/third_party/nsync/futex.c index 9d6b47268..227d96044 100644 --- a/third_party/nsync/futex.c +++ b/third_party/nsync/futex.c @@ -290,9 +290,7 @@ int nsync_futex_wait_ (atomic_int *w, int expect, char pshare, const struct time } } else { Polyfill: - tib->tib_flags |= TIB_FLAG_TIME_CRITICAL; rc = nsync_futex_polyfill_ (w, expect, timeout); - tib->tib_flags &= ~TIB_FLAG_TIME_CRITICAL; } Finished: diff --git a/third_party/python/Modules/_threadmodule.c b/third_party/python/Modules/_threadmodule.c index d15a0b8ca..11428a4e0 100644 --- a/third_party/python/Modules/_threadmodule.c +++ b/third_party/python/Modules/_threadmodule.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/utsname.h" #include "libc/calls/struct/winsize.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/termios.h" #include "libc/calls/weirdtypes.h" #include "libc/dce.h" diff --git a/third_party/python/Modules/posixmodule.c b/third_party/python/Modules/posixmodule.c index 51240832d..a29ef0841 100644 --- a/third_party/python/Modules/posixmodule.c +++ b/third_party/python/Modules/posixmodule.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/utsname.h" #include "libc/calls/struct/winsize.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/termios.h" #include "libc/calls/weirdtypes.h" #include "libc/dce.h" diff --git a/third_party/python/Modules/timemodule.c b/third_party/python/Modules/timemodule.c index dc139310d..d02650681 100644 --- a/third_party/python/Modules/timemodule.c +++ b/third_party/python/Modules/timemodule.c @@ -10,7 +10,7 @@ #include "libc/calls/struct/tms.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/accounting.h" #include "libc/nt/runtime.h" #include "libc/runtime/clktck.h" diff --git a/third_party/python/PC/winreg.c b/third_party/python/PC/winreg.c index 9ae9e1086..0aa32f944 100644 --- a/third_party/python/PC/winreg.c +++ b/third_party/python/PC/winreg.c @@ -4,18 +4,44 @@ │ Python 3 │ │ https://docs.python.org/3/license.html │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/isystem/windows.h" #include "libc/nt/registry.h" #include "third_party/python/Include/abstract.h" #include "third_party/python/Include/ceval.h" #include "third_party/python/Include/listobject.h" #include "third_party/python/Include/longobject.h" #include "third_party/python/Include/modsupport.h" +#include "third_party/python/Include/object.h" #include "third_party/python/Include/objimpl.h" #include "third_party/python/Include/pyerrors.h" #include "third_party/python/Include/pyhash.h" #include "third_party/python/Include/pymacro.h" #include "third_party/python/Include/structmember.h" + +#undef NULL +#define NULL 0 + +#define BOOL bool32 +#define DWORD32 uint32_t +#define HKEY int64_t +#define ULONG uint32_t +#define ACCESS_MASK ULONG +#define REGSAM ACCESS_MASK + +#define HKEY_CLASSES_ROOT kNtHkeyClassesRoot +#define HKEY_CURRENT_USER kNtHkeyCurrentUser +#define HKEY_LOCAL_MACHINE kNtHkeyLocalMachine +#define HKEY_USERS kNtHkeyUsers +#define HKEY_PERFORMANCE_DATA kNtHkeyPerformanceData +#define HKEY_PERFORMANCE_TEXT kNtHkeyPerformanceText +#define HKEY_PERFORMANCE_NLSTEXT kNtHkeyPerformanceNlstext +#define HKEY_CURRENT_CONFIG kNtHkeyCurrentConfig +#define HKEY_DYN_DATA kNtHkeyDynData +#define HKEY_CURRENT_USER_LOCAL_SETTINGS kNtHkeyCurrentUserLocalSettings +#define KEY_READ kNtKeyRead +#define KEY_WRITE kNtKeyWrite +#define KEY_EXECUTE kNtKeyExecute +#define KEY_ALL_ACCESS kNtKeyAllAccess + /* clang-format off */ /* diff --git a/third_party/sqlite3/os_unix.c b/third_party/sqlite3/os_unix.c index 1bf5b0067..801ed24da 100644 --- a/third_party/sqlite3/os_unix.c +++ b/third_party/sqlite3/os_unix.c @@ -126,7 +126,7 @@ #include "libc/sysv/consts/ok.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/limits.h" #endif /* SQLITE_ENABLE_LOCKING_STYLE */ diff --git a/third_party/zip/unix.c b/third_party/zip/unix.c index b815c35c5..0af1e2c31 100644 --- a/third_party/zip/unix.c +++ b/third_party/zip/unix.c @@ -705,7 +705,7 @@ char *d; /* directory to delete */ #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/third_party/zstd/programs/util.c b/third_party/zstd/programs/util.c index 0c36955ab..04e070d7b 100644 --- a/third_party/zstd/programs/util.c +++ b/third_party/zstd/programs/util.c @@ -1631,7 +1631,7 @@ failed: #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/tool/build/lib/elfwriter_zip.c b/tool/build/lib/elfwriter_zip.c index caf29bc0e..ea4829bfe 100644 --- a/tool/build/lib/elfwriter_zip.c +++ b/tool/build/lib/elfwriter_zip.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dos.internal.h" #include "libc/elf/def.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/mem/gc.h" diff --git a/tool/decode/zip.c b/tool/decode/zip.c index 8f7a0762f..51b9df1c3 100644 --- a/tool/decode/zip.c +++ b/tool/decode/zip.c @@ -18,8 +18,8 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" -#include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/bits.h" #include "libc/intrin/safemacros.internal.h" #include "libc/log/check.h" diff --git a/tool/net/redbean.c b/tool/net/redbean.c index f6d5c0c63..c67b7c6e7 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -38,6 +38,7 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bits.h" #include "libc/intrin/bsr.h"