mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Improve system calls
- Wrap clock_getres() - Wrap sched_setscheduler() - Make sleep() api conformant - Polyfill sleep() using select() - Improve clock_gettime() polyfill - Make nanosleep() POSIX conformant - Slightly improve some DNS functions - Further strengthen pledge() sandboxing - Improve rounding of timeval / timespec - Allow layering of pledge() calls on Linux - Polyfill sched_yield() using select() on XNU - Delete more system constants we probably don't need
This commit is contained in:
parent
5df3e4e7a8
commit
853b6c3864
330 changed files with 1971 additions and 1223 deletions
|
@ -13,6 +13,6 @@
|
|||
int main(int argc, char *argv[]) {
|
||||
volatile long double x = -.5;
|
||||
volatile long double y = 1.5;
|
||||
printf("atan2l(%.19Lg, %.19Lg) is %.19Lg\n", x, y, atan2l(x, y));
|
||||
printf("Hello World! %.19Lg\n", atan2l(x, y));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,15 +16,15 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/math.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
/**
|
||||
* Adds resource usages.
|
||||
* Accumulates resource statistics in `y` to `x`.
|
||||
*/
|
||||
void AddRusage(struct rusage *x, const struct rusage *y) {
|
||||
x->ru_utime = AddTimeval(x->ru_utime, y->ru_utime);
|
||||
x->ru_stime = AddTimeval(x->ru_stime, y->ru_stime);
|
||||
void _addrusage(struct rusage *x, const struct rusage *y) {
|
||||
x->ru_utime = _timeval_add(x->ru_utime, y->ru_utime);
|
||||
x->ru_stime = _timeval_add(x->ru_stime, y->ru_stime);
|
||||
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
|
||||
x->ru_ixrss += y->ru_ixrss;
|
||||
x->ru_idrss += y->ru_idrss;
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/math.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
|
||||
/**
|
||||
* Adds two microsecond timestamps.
|
||||
*/
|
||||
struct timeval AddTimeval(struct timeval x, struct timeval y) {
|
||||
struct timeval _timeval_add(struct timeval x, struct timeval y) {
|
||||
x.tv_sec += y.tv_sec;
|
||||
x.tv_usec += y.tv_usec;
|
||||
if (x.tv_usec >= 1000000) {
|
||||
|
|
69
libc/calls/clock_getres.c
Normal file
69
libc/calls/clock_getres.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*-*- 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/asan.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
int sys_clock_getres(int, struct timespec *) hidden;
|
||||
|
||||
static int sys_clock_getres_poly(int clock, struct timespec *ts, int64_t real) {
|
||||
if (clock == CLOCK_REALTIME) {
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = real;
|
||||
return 0;
|
||||
} else if (clock == CLOCK_MONOTONIC) {
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 1;
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
||||
static int sys_clock_getres_nt(int clock, struct timespec *ts) {
|
||||
return sys_clock_getres_poly(clock, ts, 100);
|
||||
}
|
||||
|
||||
static int sys_clock_getres_xnu(int clock, struct timespec *ts) {
|
||||
return sys_clock_getres_poly(clock, ts, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns granularity of clock.
|
||||
*/
|
||||
int clock_getres(int clock, struct timespec *ts) {
|
||||
int rc;
|
||||
if (!ts || (IsAsan() && !__asan_is_valid_timespec(ts))) {
|
||||
rc = efault();
|
||||
} else if (clock == 127) {
|
||||
rc = einval(); // 127 is used by consts.sh to mean unsupported
|
||||
} else if (IsWindows()) {
|
||||
rc = sys_clock_getres_nt(clock, ts);
|
||||
} else if (IsXnu()) {
|
||||
rc = sys_clock_getres_xnu(clock, ts);
|
||||
} else {
|
||||
rc = sys_clock_getres(clock, ts);
|
||||
}
|
||||
STRACE("clock_getres(%d, [%s]) → %d% m", clock, DescribeTimespec(rc, ts), rc);
|
||||
return rc;
|
||||
}
|
60
libc/calls/clock_gettime-mono.c
Normal file
60
libc/calls/clock_gettime-mono.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-*- 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/bits/likely.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/clockstonanos.internal.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static struct {
|
||||
bool once;
|
||||
char lock;
|
||||
uint64_t base;
|
||||
struct timespec mono;
|
||||
} g_mono;
|
||||
|
||||
int sys_clock_gettime_mono(struct timespec *ts) {
|
||||
// this routine stops being monotonic after 194 years of uptime
|
||||
uint64_t nanos;
|
||||
struct timespec res;
|
||||
if (X86_HAVE(INVTSC)) {
|
||||
if (__threaded) {
|
||||
_spinlock(&g_mono.lock);
|
||||
}
|
||||
if (UNLIKELY(!g_mono.once)) {
|
||||
clock_gettime(CLOCK_REALTIME, &g_mono.mono);
|
||||
g_mono.base = rdtsc();
|
||||
g_mono.once = true;
|
||||
}
|
||||
nanos = ClocksToNanos(rdtsc(), g_mono.base);
|
||||
res = g_mono.mono;
|
||||
res.tv_sec += nanos / 1000000000;
|
||||
res.tv_nsec += nanos % 1000000000;
|
||||
_spunlock(&g_mono.lock);
|
||||
*ts = res;
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
|
@ -16,51 +16,22 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/clockstonanos.internal.h"
|
||||
|
||||
textwindows int sys_clock_gettime_nt(int clockid, struct timespec *ts) {
|
||||
uint64_t nanos;
|
||||
static bool once;
|
||||
static char lock;
|
||||
struct timespec res;
|
||||
static uint64_t base;
|
||||
textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
|
||||
struct NtFileTime ft;
|
||||
static struct timespec mono;
|
||||
if (!ts) return efault();
|
||||
if (clockid == CLOCK_REALTIME) {
|
||||
if (clock == CLOCK_REALTIME) {
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
*ts = FileTimeToTimeSpec(ft);
|
||||
return 0;
|
||||
} else if ((clockid == CLOCK_MONOTONIC || clockid == CLOCK_MONOTONIC_RAW) &&
|
||||
X86_HAVE(INVTSC)) {
|
||||
// this routine stops being monotonic after 194 years of uptime
|
||||
if (__threaded) _spinlock(&lock);
|
||||
if (UNLIKELY(!once)) {
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
mono = FileTimeToTimeSpec(ft);
|
||||
base = rdtsc();
|
||||
once = true;
|
||||
}
|
||||
nanos = ClocksToNanos(rdtsc(), base);
|
||||
res = mono;
|
||||
res.tv_sec += nanos / 1000000000;
|
||||
res.tv_nsec += nanos % 1000000000;
|
||||
_spunlock(&lock);
|
||||
*ts = res;
|
||||
return 0;
|
||||
} else if (clock == CLOCK_MONOTONIC) {
|
||||
return sys_clock_gettime_mono(ts);
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
|
|
|
@ -17,11 +17,15 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_clock_gettime_xnu(int clockid, struct timespec *ts) {
|
||||
int sys_clock_gettime_xnu(int clock, struct timespec *ts) {
|
||||
axdx_t ad;
|
||||
ad = sys_gettimeofday((struct timeval *)ts, NULL, NULL);
|
||||
if (clock == CLOCK_REALTIME) {
|
||||
ad = sys_gettimeofday((struct timeval *)ts, 0, 0);
|
||||
if (ad.ax != -1) {
|
||||
if (ad.ax) {
|
||||
ts->tv_sec = ad.ax;
|
||||
|
@ -32,4 +36,9 @@ int sys_clock_gettime_xnu(int clockid, struct timespec *ts) {
|
|||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (clock == CLOCK_MONOTONIC) {
|
||||
return sys_clock_gettime_mono(ts);
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,23 +48,25 @@
|
|||
* __clock_gettime l: 35𝑐 11𝑛𝑠
|
||||
* sys_clock_gettime l: 220𝑐 71𝑛𝑠
|
||||
*
|
||||
* @param clockid can be CLOCK_REALTIME, CLOCK_MONOTONIC, etc.
|
||||
* @param clock can be CLOCK_REALTIME, CLOCK_MONOTONIC, etc.
|
||||
* @param ts is where the result is stored
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @error EINVAL if clockid isn't supported on this system
|
||||
* @error EINVAL if clock isn't supported on this system
|
||||
* @see strftime(), gettimeofday()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int clock_gettime(int clockid, struct timespec *ts) {
|
||||
int clock_gettime(int clock, struct timespec *ts) {
|
||||
int rc;
|
||||
if (IsAsan() && !__asan_is_valid_timespec(ts)) {
|
||||
if (clock == 127) {
|
||||
rc = einval(); // 127 is used by consts.sh to mean unsupported
|
||||
} else if (!ts || (IsAsan() && !__asan_is_valid_timespec(ts))) {
|
||||
rc = efault();
|
||||
} else {
|
||||
rc = __clock_gettime(clockid, ts);
|
||||
rc = __clock_gettime(clock, ts);
|
||||
}
|
||||
#if SYSDEBUG
|
||||
if (!__time_critical) {
|
||||
STRACE("clock_gettime(%d, [%s]) → %d% m", clockid, DescribeTimespec(rc, ts),
|
||||
STRACE("clock_gettime(%d, [%s]) → %d% m", clock, DescribeTimespec(rc, ts),
|
||||
rc);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@ typedef int clock_gettime_f(int, struct timespec *);
|
|||
extern clock_gettime_f *__clock_gettime;
|
||||
clock_gettime_f *__clock_gettime_get(bool *) hidden;
|
||||
int __clock_gettime_init(int, struct timespec *) hidden;
|
||||
int sys_clock_gettime_mono(struct timespec *) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_MATH_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_MATH_H_
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct timeval AddTimeval(struct timeval, struct timeval);
|
||||
struct timespec AddTimespec(struct timespec, struct timespec);
|
||||
void AddRusage(struct rusage *, const struct rusage *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_MATH_H_ */
|
|
@ -16,64 +16,84 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/nt/time.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/clockstonanos.internal.h"
|
||||
|
||||
textwindows noinstrument int sys_nanosleep_nt(const struct timespec *req,
|
||||
textwindows int sys_nanosleep_nt(const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int rc;
|
||||
bool alertable;
|
||||
uint32_t slice;
|
||||
int64_t ms, sec, nsec;
|
||||
uint64_t begin;
|
||||
int64_t ms, toto, nanos;
|
||||
struct timespec elapsed;
|
||||
|
||||
// check req is legal timespec
|
||||
if (!(0 <= req->tv_nsec && req->tv_nsec < 1000000000)) {
|
||||
return einval();
|
||||
}
|
||||
|
||||
// save beginning timestamp
|
||||
if (!__time_critical && rem) {
|
||||
begin = rdtsc();
|
||||
} else {
|
||||
begin = 0; // to prevent uninitialized warning
|
||||
}
|
||||
|
||||
// convert timespec to milliseconds
|
||||
if (__builtin_mul_overflow(req->tv_sec, 1000, &ms) ||
|
||||
__builtin_add_overflow(ms, req->tv_nsec / 1000000, &ms)) {
|
||||
__builtin_add_overflow(ms, (req->tv_nsec + 999999) / 1000000, &ms)) {
|
||||
ms = INT64_MAX;
|
||||
}
|
||||
if (!ms && (req->tv_sec || req->tv_nsec)) {
|
||||
ms = 1;
|
||||
}
|
||||
rc = 0;
|
||||
do {
|
||||
|
||||
for (toto = ms;;) {
|
||||
|
||||
// check if signal was delivered
|
||||
if (!__time_critical && _check_interrupts(false, g_fds.p)) {
|
||||
rc = eintr();
|
||||
break;
|
||||
}
|
||||
slice = MIN(__SIG_POLLING_INTERVAL_MS, ms);
|
||||
if (__time_critical) {
|
||||
alertable = false;
|
||||
} else {
|
||||
alertable = true;
|
||||
POLLTRACE("sys_nanosleep_nt polling for %'ldms of %'ld");
|
||||
}
|
||||
if (SleepEx(slice, alertable) == kNtWaitIoCompletion) {
|
||||
POLLTRACE("IOCP EINTR");
|
||||
continue;
|
||||
}
|
||||
ms -= slice;
|
||||
} while (ms > 0);
|
||||
ms = MAX(ms, 0);
|
||||
if (rem) {
|
||||
sec = ms / 1000;
|
||||
nsec = ms % 1000 * 1000000000;
|
||||
rem->tv_nsec -= nsec;
|
||||
if (rem->tv_nsec < 0) {
|
||||
--rem->tv_sec;
|
||||
rem->tv_nsec = 1000000000 - rem->tv_nsec;
|
||||
}
|
||||
rem->tv_sec -= sec;
|
||||
nanos = ClocksToNanos(rdtsc(), begin);
|
||||
elapsed.tv_sec = nanos / 1000000000;
|
||||
elapsed.tv_nsec = nanos % 1000000000;
|
||||
*rem = _timespec_sub(*req, elapsed);
|
||||
if (rem->tv_sec < 0) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return eintr();
|
||||
}
|
||||
|
||||
// configure the sleep
|
||||
slice = MIN(__SIG_POLLING_INTERVAL_MS, ms);
|
||||
if (__time_critical) {
|
||||
alertable = false;
|
||||
} else {
|
||||
alertable = true;
|
||||
POLLTRACE("... sleeping %'ldms of %'ld", toto - ms, toto);
|
||||
}
|
||||
|
||||
// perform the sleep
|
||||
if (SleepEx(slice, alertable) == kNtWaitIoCompletion) {
|
||||
POLLTRACE("IOCP EINTR"); // in case we ever figure it out
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if full duration has elapsed
|
||||
if ((ms -= slice) <= 0) {
|
||||
if (rem) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,43 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
|
||||
int sys_nanosleep_xnu(const struct timespec *req, struct timespec *rem) {
|
||||
long millis;
|
||||
millis = req->tv_nsec / 1000;
|
||||
millis = MAX(1, millis);
|
||||
return sys_select(0, 0, 0, 0, &(struct timeval){req->tv_sec, millis});
|
||||
int rc;
|
||||
axdx_t axdx;
|
||||
struct timeval tv;
|
||||
struct timespec begin, end, elapsed;
|
||||
|
||||
if (rem) {
|
||||
if (sys_clock_gettime_xnu(CLOCK_MONOTONIC, &begin) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tv = _timespec2timeval(*req);
|
||||
rc = sys_select(0, 0, 0, 0, &tv);
|
||||
|
||||
if (rem) {
|
||||
if (!rc) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
} else if (rc == -1 && errno == EINTR) {
|
||||
sys_clock_gettime_xnu(CLOCK_MONOTONIC, &end);
|
||||
elapsed = _timespec_sub(end, begin);
|
||||
*rem = _timespec_sub(*req, elapsed);
|
||||
if (rem->tv_sec < 0) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,26 @@
|
|||
|
||||
/**
|
||||
* Sleeps for a particular amount of time.
|
||||
*
|
||||
* @param req is the duration of time we should sleep
|
||||
* @param rem if non-NULL will receive the amount of time that wasn't
|
||||
* slept because a signal was delivered. If no signal's delivered
|
||||
* then this value will be set to `{0, 0}`. It's also fine to set
|
||||
* this value to the same pointer as `req`.
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @raise EINVAL if `req->tv_nsec ∉ [0,1000000000)`
|
||||
* @raise EINTR if a signal was delivered, and `rem` is updated
|
||||
* @raise EFAULT if `req` is NULL or `req` / `rem` is a bad pointer
|
||||
* @raise ENOSYS on bare metal
|
||||
* @note POSIX.1 specifies nanosleep() measures against `CLOCK_REALTIME`
|
||||
* however Linux measures uses `CLOCK_MONOTONIC`. This shouldn't
|
||||
* matter, since POSIX.1 further specifies that discontinuous
|
||||
* changes in `CLOCK_REALTIME` shouldn't impact nanosleep()
|
||||
* @norestart
|
||||
*/
|
||||
noinstrument int nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
int nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
int rc;
|
||||
|
||||
if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
|
||||
(rem && !__asan_is_valid_timespec(rem))))) {
|
||||
rc = efault();
|
||||
|
@ -46,9 +62,21 @@ noinstrument int nanosleep(const struct timespec *req, struct timespec *rem) {
|
|||
} else {
|
||||
rc = sys_nanosleep_nt(req, rem);
|
||||
}
|
||||
|
||||
// Linux Kernel doesn't change the remainder value on success, but
|
||||
// some kernels like OpenBSD will. POSIX doesn't specify the Linux
|
||||
// behavior. So we polyfill it here.
|
||||
if (!rc && rem) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
}
|
||||
|
||||
#if defined(SYSDEBUG) && _POLLTRACE
|
||||
if (!__time_critical) {
|
||||
POLLTRACE("nanosleep(%s, [%s]) → %d% m", DescribeTimespec(rc, req),
|
||||
DescribeTimespec(rc, rem), rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
50
libc/calls/pause-nt.c
Normal file
50
libc/calls/pause-nt.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*-*- 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/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_pause_nt(void) {
|
||||
long ms, totoms;
|
||||
ms = 0;
|
||||
totoms = 0;
|
||||
for (;;) {
|
||||
|
||||
if (_check_interrupts(false, g_fds.p)) {
|
||||
return eintr();
|
||||
}
|
||||
|
||||
if (SleepEx(__SIG_POLLING_INTERVAL_MS, true) == kNtWaitIoCompletion) {
|
||||
POLLTRACE("IOCP EINTR"); // in case we ever figure it out
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(SYSDEBUG) && defined(_POLLTRACE)
|
||||
ms += __SIG_POLLING_INTERVAL_MS;
|
||||
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
||||
totoms += ms, ms = 0;
|
||||
POLLTRACE("... pausing for %'lums...", totoms);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -18,34 +18,51 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
||||
/**
|
||||
* Waits for signal.
|
||||
*
|
||||
* This suspends execution until an unmasked signal is delivered and its
|
||||
* callback function has been called. The current signal mask is used.
|
||||
* This suspends execution until an unmasked signal is delivered. If the
|
||||
* signal delivery kills the process, this won't return. The signal mask
|
||||
* of the current thread is used. If a signal handler exists, this shall
|
||||
* return after it's been invoked.
|
||||
*
|
||||
* @return should always be -1 w/ EINTR
|
||||
* This function is equivalent to:
|
||||
*
|
||||
* select(0, 0, 0, 0, 0);
|
||||
*
|
||||
* However this has a tinier footprint and better logging.
|
||||
*
|
||||
* @return -1 w/ errno set to EINTR
|
||||
* @see sigsuspend()
|
||||
* @norestart
|
||||
*/
|
||||
int pause(void) {
|
||||
int e, rc;
|
||||
sigset_t mask;
|
||||
e = errno;
|
||||
int rc;
|
||||
STRACE("pause() → [...]");
|
||||
if ((rc = sys_pause()) == -1 && errno == ENOSYS) {
|
||||
errno = e;
|
||||
if (sigprocmask(SIG_BLOCK, 0, &mask) == -1) return -1;
|
||||
rc = sigsuspend(&mask);
|
||||
|
||||
if (!IsWindows()) {
|
||||
// We'll polyfill pause() using select() with a null timeout, which
|
||||
// should hopefully do the same thing, which means wait forever but
|
||||
// the usual signal interrupt rules apply.
|
||||
//
|
||||
// "If the readfds, writefds, and errorfds arguments are all null
|
||||
// pointers and the timeout argument is not a null pointer, the
|
||||
// pselect() or select() function shall block for the time
|
||||
// specified, or until interrupted by a signal. If the readfds,
|
||||
// writefds, and errorfds arguments are all null pointers and the
|
||||
// timeout argument is a null pointer, the pselect() or select()
|
||||
// function shall block until interrupted by a signal." ──Quoth
|
||||
// IEEE 1003.1-2017 §functions/select
|
||||
//
|
||||
rc = sys_select(0, 0, 0, 0, 0);
|
||||
} else {
|
||||
rc = sys_pause_nt();
|
||||
}
|
||||
|
||||
STRACE("[...] pause → %d% m", rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
/**
|
||||
* Tunes process on Linux.
|
||||
*
|
||||
* @raise ENOSYS on non-Linux.
|
||||
* @raise ENOSYS on non-Linux
|
||||
*/
|
||||
privileged int prctl(int operation, ...) {
|
||||
int rc;
|
||||
|
|
33
libc/calls/sched-sysv.internal.h
Normal file
33
libc/calls/sched-sysv.internal.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_SCHED_SYSV_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_SCHED_SYSV_INTERNAL_H_
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define MAXCPUS_NETBSD 256
|
||||
#define MAXCPUS_OPENBSD 64
|
||||
#define P_ALL_LWPS 0 /* for effect on all threads in pid */
|
||||
|
||||
int sys_sched_get_priority_max(int);
|
||||
int sys_sched_get_priority_min(int);
|
||||
int sys_sched_getparam(int, struct sched_param *);
|
||||
int sys_sched_getscheduler(int);
|
||||
int sys_sched_setaffinity(int, uint64_t, const void *) hidden;
|
||||
int sys_sched_setparam(int, const struct sched_param *);
|
||||
int sys_sched_setscheduler(int, int, const struct sched_param *);
|
||||
int sys_sched_yield(void) hidden;
|
||||
int64_t sys_sched_getaffinity(int, uint64_t, void *) hidden;
|
||||
|
||||
int sys_sched_getscheduler_netbsd(int);
|
||||
int sys_sched_setparam_netbsd(int, int, int, const struct sched_param *) //
|
||||
asm("sys_sched_setparam");
|
||||
int sys_sched_getparam_netbsd(int, int, int *, struct sched_param *) //
|
||||
asm("sys_sched_getparam");
|
||||
int sys_sched_setaffinity_netbsd(int, int, size_t, const void *) //
|
||||
asm("sys_sched_setaffinity");
|
||||
int sys_sched_getaffinity_netbsd(int, int, size_t, void *) //
|
||||
asm("sys_sched_setaffinity");
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_SCHED_SYSV_INTERNAL_H_ */
|
53
libc/calls/sched_get_priority_max.c
Normal file
53
libc/calls/sched_get_priority_max.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- 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/calls.h"
|
||||
#include "libc/calls/sched-sysv.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static int sys_sched_get_priority_max_netbsd(int policy) {
|
||||
if (policy == SCHED_OTHER) {
|
||||
return -1;
|
||||
} else if (policy == SCHED_RR || policy == SCHED_FIFO) {
|
||||
return 63; // NetBSD Libc needs 19 system calls to compute this!
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns maximum `sched_param::sched_priority` for `policy`.
|
||||
*
|
||||
* @return priority, or -1 w/ errno
|
||||
* @raise ENOSYS on XNU, Windows, OpenBSD
|
||||
* @raise EINVAL if `policy` is invalid
|
||||
*/
|
||||
int sched_get_priority_max(int policy) {
|
||||
int rc;
|
||||
if (IsNetbsd()) {
|
||||
rc = sys_sched_get_priority_max_netbsd(policy);
|
||||
} else {
|
||||
rc = sys_sched_get_priority_max(policy);
|
||||
}
|
||||
STRACE("sched_get_priority_max(%s) → %d% m", DescribeSchedPolicy(policy), rc);
|
||||
return rc;
|
||||
}
|
53
libc/calls/sched_get_priority_min.c
Normal file
53
libc/calls/sched_get_priority_min.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- 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/calls.h"
|
||||
#include "libc/calls/sched-sysv.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static int sys_sched_get_priority_min_netbsd(int policy) {
|
||||
if (policy == SCHED_OTHER) {
|
||||
return -1;
|
||||
} else if (policy == SCHED_RR || policy == SCHED_FIFO) {
|
||||
return 0; // NetBSD Libc needs 19 system calls to compute this!
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns minimum `sched_param::sched_priority` for `policy`.
|
||||
*
|
||||
* @return priority, or -1 w/ errno
|
||||
* @raise ENOSYS on XNU, Windows, OpenBSD
|
||||
* @raise EINVAL if `policy` is invalid
|
||||
*/
|
||||
int sched_get_priority_min(int policy) {
|
||||
int rc;
|
||||
if (IsNetbsd()) {
|
||||
rc = sys_sched_get_priority_min_netbsd(policy);
|
||||
} else {
|
||||
rc = sys_sched_get_priority_min(policy);
|
||||
}
|
||||
STRACE("sched_get_priority_min(%s) → %d% m", DescribeSchedPolicy(policy), rc);
|
||||
return rc;
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sched-sysv.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
28
libc/calls/sched_getparam.c
Normal file
28
libc/calls/sched_getparam.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- 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/sched-sysv.internal.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
|
||||
/**
|
||||
* Gets scheduler policy parameter.
|
||||
* @raise ENOSYS on XNU, Windows
|
||||
*/
|
||||
int sched_getparam(int pid, struct sched_param *param) {
|
||||
return sys_sched_getparam(pid, param);
|
||||
}
|
31
libc/calls/sched_getscheduler-netbsd.c
Normal file
31
libc/calls/sched_getscheduler-netbsd.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- 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/calls.h"
|
||||
#include "libc/calls/sched-sysv.internal.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
|
||||
int sys_sched_getscheduler_netbsd(int pid) {
|
||||
int policy;
|
||||
struct sched_param sp;
|
||||
if (sys_sched_getparam_netbsd(pid, P_ALL_LWPS, &policy, &sp) != -1) {
|
||||
return policy;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
39
libc/calls/sched_getscheduler.c
Normal file
39
libc/calls/sched_getscheduler.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- 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/sched-sysv.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Gets scheduler policy for `pid`.
|
||||
*
|
||||
* @param pid is id of process (where 0 is same as getpid())
|
||||
* @return scheduler policy, or -1 w/ errno
|
||||
*/
|
||||
int sched_getscheduler(int pid) {
|
||||
int rc;
|
||||
if (IsNetbsd()) {
|
||||
rc = sys_sched_getscheduler_netbsd(pid);
|
||||
} else {
|
||||
rc = sys_sched_getscheduler(pid);
|
||||
}
|
||||
STRACE("sched_getscheduler(%d) → %d% m", pid, rc);
|
||||
return rc;
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sched-sysv.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
|
|
28
libc/calls/sched_setparam.c
Normal file
28
libc/calls/sched_setparam.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- 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/sched-sysv.internal.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
|
||||
/**
|
||||
* Sets scheduler policy parameter.
|
||||
* @raise ENOSYS on XNU, Windows
|
||||
*/
|
||||
int sched_setparam(int pid, const struct sched_param *param) {
|
||||
return sys_sched_setparam(pid, param);
|
||||
}
|
106
libc/calls/sched_setscheduler.c
Normal file
106
libc/calls/sched_setscheduler.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*-*- 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/sched-sysv.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Sets scheduling policy of process, e.g.
|
||||
*
|
||||
* struct sched_param p = {sched_get_priority_max(SCHED_OTHER)};
|
||||
* LOGIFNEG1(sched_setscheduler(0, SCHED_OTHER, &p));
|
||||
*
|
||||
* Processes with numerically higher priority values are scheduled
|
||||
* before processes with numerically lower priority values.
|
||||
*
|
||||
* @param pid is the id of the process whose scheduling policy should be
|
||||
* changed. This applies to all threads associated with the process.
|
||||
* Linux is special; the kernel treats this as a thread id (noting
|
||||
* that `getpid() == gettid()` is always the case on Linux for the
|
||||
* main thread) and will only take effect for the specified tid.
|
||||
* Therefore this function is POSIX-compliant iif `!__threaded`.
|
||||
* Setting `pid` to zero means the same thing as getpid().
|
||||
*
|
||||
* @param policy specifies the kernel's timesharing strategy.
|
||||
*
|
||||
* The `policy` must have one of:
|
||||
*
|
||||
* - `SCHED_OTHER` (or `SCHED_NORMAL`) for the default policy
|
||||
* - `SCHED_RR` for real-time round-robin scheduling
|
||||
* - `SCHED_FIFO` for real-time first-in first-out scheduling
|
||||
* - `SCHED_BATCH` for "batch" style execution of processes if
|
||||
* supported (Linux), otherwise it's treated as `SCHED_OTHER`
|
||||
* - `SCHED_IDLE` for running very low priority background jobs
|
||||
* if it's supported (Linux), otherwise this is `SCHED_OTHER`
|
||||
*
|
||||
* The `policy` may optionally bitwise-or any one of:
|
||||
*
|
||||
* - `SCHED_RESET_ON_FORK` will cause the scheduling policy to be
|
||||
* automatically reset to `SCHED_NORMAL` upon fork() if supported;
|
||||
* otherwise this flag is polyfilled as zero, so that it may be
|
||||
* safely used (without having to check if the o/s is Linux).
|
||||
*
|
||||
* @param param must be set to the scheduler parameter, which should be
|
||||
* greater than or equal to sched_get_priority_min(policy) and less
|
||||
* than or equal to sched_get_priority_max(policy). Linux allows the
|
||||
* static priority range 1 to 99 for the `SCHED_FIFO` and `SCHED_RR`
|
||||
* policies, and the priority 0 for the remaining policies.
|
||||
*
|
||||
* @return the former scheduling policy of the specified process. If
|
||||
* this function fails, then the scheduling policy is not changed,
|
||||
* and -1 w/ errno is returned.
|
||||
*
|
||||
* @raise ENOSYS on XNU, Windows, OpenBSD
|
||||
* @raise EPERM if not authorized to use scheduler in question (e.g.
|
||||
* trying to use a real-time scheduler as non-root on Linux) or
|
||||
* possibly because pledge() was used and isn't allowing this
|
||||
* @raise EINVAL if `param` is NULL
|
||||
* @raise EINVAL if `policy` is invalid
|
||||
* @raise EINVAL if `param` has value out of ranges defined by `policy`
|
||||
*/
|
||||
int sched_setscheduler(int pid, int policy, const struct sched_param *param) {
|
||||
int rc, old;
|
||||
|
||||
if (IsNetbsd()) {
|
||||
rc = sys_sched_getscheduler_netbsd(pid);
|
||||
} else {
|
||||
rc = sys_sched_getscheduler(pid);
|
||||
}
|
||||
|
||||
if (rc != -1) {
|
||||
old = rc;
|
||||
if (IsNetbsd()) {
|
||||
rc = sys_sched_setparam_netbsd(pid, P_ALL_LWPS, policy, param);
|
||||
} else {
|
||||
rc = sys_sched_setscheduler(pid, policy, param);
|
||||
}
|
||||
if (rc != -1) {
|
||||
rc = old;
|
||||
}
|
||||
}
|
||||
|
||||
STRACE("sched_setscheduler(%d, %s, %s) → %d% m", pid,
|
||||
DescribeSchedPolicy(policy), DescribeSchedParam(param), rc);
|
||||
return rc;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_SCHED_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_SCHED_H_
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int sched_setscheduler(int, int, const struct sched_param *);
|
||||
int sched_getscheduler(int);
|
||||
int sched_setparam(int, const struct sched_param *);
|
||||
int sched_getparam(int, struct sched_param *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_SCHED_H_ */
|
|
@ -26,6 +26,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
|
@ -80,6 +81,7 @@ textwindows void _check_sigalrm(void) {
|
|||
textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue,
|
||||
struct itimerval *out_opt_oldvalue) {
|
||||
long double elapsed, untilnext;
|
||||
|
||||
if (which != ITIMER_REAL ||
|
||||
(newvalue && (!(0 <= newvalue->it_value.tv_usec &&
|
||||
newvalue->it_value.tv_usec < 1000000) ||
|
||||
|
@ -87,6 +89,7 @@ textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue,
|
|||
newvalue->it_interval.tv_usec < 1000000)))) {
|
||||
return einval();
|
||||
}
|
||||
|
||||
if (out_opt_oldvalue) {
|
||||
if (__hastimer) {
|
||||
elapsed = nowl() - __lastalrm;
|
||||
|
@ -106,6 +109,7 @@ textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue,
|
|||
out_opt_oldvalue->it_value.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (newvalue) {
|
||||
if (newvalue->it_interval.tv_sec || newvalue->it_interval.tv_usec ||
|
||||
newvalue->it_value.tv_sec || newvalue->it_value.tv_usec) {
|
||||
|
@ -124,5 +128,6 @@ textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue,
|
|||
__hastimer = false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,16 +16,32 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Sleeps for a particular amount of time.
|
||||
* Sleeps for particular number of seconds.
|
||||
*
|
||||
* @return 0 if the full time elapsed, otherwise we assume an interrupt
|
||||
* was delivered, in which case the errno condition is ignored, and
|
||||
* this function shall return the number of unslept seconds rounded
|
||||
* using the ceiling function
|
||||
* @see nanosleep(), usleep()
|
||||
* @asyncsignalsafe
|
||||
* @norestart
|
||||
*/
|
||||
int sleep(uint32_t seconds) {
|
||||
return nanosleep(&(struct timespec){seconds, 0}, NULL);
|
||||
unsigned sleep(unsigned seconds) {
|
||||
int err;
|
||||
unsigned unslept;
|
||||
struct timespec tv = {seconds};
|
||||
err = errno;
|
||||
nanosleep(&tv, &tv);
|
||||
errno = err;
|
||||
unslept = tv.tv_sec;
|
||||
if (tv.tv_nsec && unslept < UINT_MAX) {
|
||||
++unslept;
|
||||
}
|
||||
return unslept;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_MAXINSNS 4096
|
||||
|
||||
#define BPF_CLASS(code) ((code)&0x07)
|
||||
#define BPF_LD 0x00 /* load ops */
|
||||
#define BPF_LDX 0x01 /* load into register */
|
||||
#define BPF_LD 0x00 /* load into accumulator */
|
||||
#define BPF_LDX 0x01 /* load into index register */
|
||||
#define BPF_ST 0x02 /* store from immediate */
|
||||
#define BPF_STX 0x03 /* store from register */
|
||||
#define BPF_ALU 0x04 /* 32-bit arithmetic */
|
||||
|
@ -19,6 +19,7 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_W 0x00 /* 32-bit */
|
||||
#define BPF_H 0x08 /* 16-bit */
|
||||
#define BPF_B 0x10 /* 8-bit */
|
||||
#define BPF_DW 0x18 /* 64-bit (eBPF only) */
|
||||
|
||||
#define BPF_MODE(code) ((code)&0xe0)
|
||||
#define BPF_IMM 0x00 /* 64-bit immediate */
|
||||
|
@ -52,7 +53,6 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
#define BPF_JMP32 0x06
|
||||
#define BPF_ALU64 0x07
|
||||
#define BPF_DW 0x18
|
||||
#define BPF_ATOMIC 0xc0
|
||||
#define BPF_XADD 0xc0
|
||||
#define BPF_MOV 0xb0
|
||||
|
|
|
@ -25,6 +25,7 @@ struct rusage {
|
|||
int getrusage(int, struct rusage *);
|
||||
int wait3(int *, int, struct rusage *);
|
||||
int wait4(int, int *, int, struct rusage *);
|
||||
void _addrusage(struct rusage *, const struct rusage *);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_RUSAGE_H_ */
|
||||
|
|
|
@ -6,5 +6,12 @@ struct sched_param {
|
|||
int32_t sched_priority;
|
||||
};
|
||||
|
||||
int sched_get_priority_max(int);
|
||||
int sched_get_priority_min(int);
|
||||
int sched_getparam(int, struct sched_param *);
|
||||
int sched_getscheduler(int);
|
||||
int sched_setparam(int, const struct sched_param *);
|
||||
int sched_setscheduler(int, int, const struct sched_param *);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SCHED_PARAM_H_ */
|
||||
|
|
|
@ -8,6 +8,9 @@ struct timespec {
|
|||
};
|
||||
|
||||
int sys_futex(int *, int, int, const struct timespec *, int *);
|
||||
bool _timespec_gt(struct timespec, struct timespec);
|
||||
struct timespec _timespec_add(struct timespec, struct timespec);
|
||||
struct timespec _timespec_sub(struct timespec, struct timespec);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMESPEC_H_ */
|
||||
|
|
34
libc/calls/struct/timespec_gt.c
Normal file
34
libc/calls/struct/timespec_gt.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- 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/struct/timespec.h"
|
||||
|
||||
/**
|
||||
* Returns true if timespec `x` is greater than `y`.
|
||||
*/
|
||||
bool _timespec_gt(struct timespec x, struct timespec y) {
|
||||
if (x.tv_sec > y.tv_sec) {
|
||||
return true;
|
||||
}
|
||||
if (x.tv_sec == y.tv_sec) {
|
||||
if (x.tv_nsec > y.tv_nsec) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -8,6 +8,7 @@ struct timeval {
|
|||
};
|
||||
|
||||
int lutimes(const char *, const struct timeval[2]);
|
||||
struct timeval _timeval_add(struct timeval, struct timeval);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_ */
|
||||
|
|
|
@ -74,8 +74,6 @@ i32 sys_pipe2(i32[hasatleast 2], u32) hidden;
|
|||
i32 sys_pledge(const char *, const char *) hidden;
|
||||
i32 sys_posix_openpt(i32) hidden;
|
||||
i32 sys_renameat(i32, const char *, i32, const char *) hidden;
|
||||
i32 sys_sched_setaffinity(i32, u64, const void *) hidden;
|
||||
i32 sys_sched_yield(void) hidden;
|
||||
i32 sys_setgid(i32) hidden;
|
||||
i32 sys_setpgid(i32, i32) hidden;
|
||||
i32 sys_setpriority(i32, u32, i32) hidden;
|
||||
|
@ -103,7 +101,6 @@ i64 sys_pwrite(i32, const void *, u64, i64, i64) hidden;
|
|||
i64 sys_read(i32, void *, u64) hidden;
|
||||
i64 sys_readlink(const char *, char *, u64) hidden;
|
||||
i64 sys_readlinkat(int, const char *, char *, u64) hidden;
|
||||
i64 sys_sched_getaffinity(i32, u64, void *) hidden;
|
||||
i64 sys_sendfile(i32, i32, i64 *, u64) hidden;
|
||||
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) hidden;
|
||||
i64 sys_write(i32, const void *, u64) hidden;
|
||||
|
|
|
@ -13,6 +13,7 @@ int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX], int) hidden;
|
|||
int __mkntpathat(int, const char *, int, char16_t[hasatleast PATH_MAX]) hidden;
|
||||
int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64], bool) hidden;
|
||||
int ntaccesscheck(const char16_t *, uint32_t) paramsnonnull() hidden;
|
||||
int sys_pause_nt(void) hidden;
|
||||
int64_t __fix_enotdir(int64_t, char16_t *) hidden;
|
||||
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) hidden;
|
||||
int64_t __winerr(void) nocallback privileged;
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/math.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
|
||||
/**
|
||||
* Adds two nanosecond timestamps.
|
||||
*/
|
||||
struct timespec AddTimespec(struct timespec x, struct timespec y) {
|
||||
struct timespec _timespec_add(struct timespec x, struct timespec y) {
|
||||
x.tv_sec += y.tv_sec;
|
||||
x.tv_nsec += y.tv_nsec;
|
||||
if (x.tv_nsec >= 10000000000) {
|
32
libc/calls/timespec_sub.c
Normal file
32
libc/calls/timespec_sub.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- 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/struct/timespec.h"
|
||||
|
||||
/**
|
||||
* Subtracts two nanosecond timestamps.
|
||||
*/
|
||||
struct timespec _timespec_sub(struct timespec x, struct timespec y) {
|
||||
x.tv_sec -= y.tv_sec;
|
||||
x.tv_nsec -= y.tv_nsec;
|
||||
if (x.tv_nsec < 0) {
|
||||
x.tv_nsec += 1000000000;
|
||||
x.tv_sec -= 1;
|
||||
}
|
||||
return x;
|
||||
}
|
|
@ -16,17 +16,21 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Sleeps for particular amount of microseconds.
|
||||
* Sleeps for particular number of microseconds.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @raise EINTR if a signal was delivered while sleeping
|
||||
* @see nanosleep(), sleep()
|
||||
* @norestart
|
||||
*/
|
||||
int usleep(uint32_t microseconds) {
|
||||
return nanosleep(&(struct timespec){(uint64_t)microseconds / 1000000,
|
||||
(uint64_t)microseconds % 1000000 * 1000},
|
||||
NULL);
|
||||
int usleep(uint32_t micros) {
|
||||
struct timespec ts = {
|
||||
micros / 1000000,
|
||||
micros % 1000000 * 1000,
|
||||
};
|
||||
return nanosleep(&ts, 0);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
@ -37,10 +38,8 @@ int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
|||
if (rc == -1 && errno == ENOSYS && path) {
|
||||
errno = olderr;
|
||||
if (ts) {
|
||||
tv[0].tv_sec = ts[0].tv_sec;
|
||||
tv[0].tv_usec = ts[0].tv_nsec / 1000;
|
||||
tv[1].tv_sec = ts[1].tv_sec;
|
||||
tv[1].tv_usec = ts[1].tv_nsec / 1000;
|
||||
tv[0] = _timespec2timeval(ts[0]);
|
||||
tv[1] = _timespec2timeval(ts[1]);
|
||||
rc = sys_utimes(path, tv);
|
||||
} else {
|
||||
rc = sys_utimes(path, NULL);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/utime.h"
|
||||
|
@ -40,20 +41,16 @@ int sys_utimensat_xnu(int dirfd, const char *path, const struct timespec ts[2],
|
|||
if (ts[0].tv_nsec == UTIME_NOW) {
|
||||
tv[0] = now;
|
||||
} else if (ts[0].tv_nsec == UTIME_OMIT) {
|
||||
tv[0].tv_sec = st.st_atim.tv_sec;
|
||||
tv[0].tv_usec = st.st_atim.tv_nsec / 1000;
|
||||
tv[0] = _timespec2timeval(st.st_atim);
|
||||
} else {
|
||||
tv[0].tv_sec = ts[0].tv_sec;
|
||||
tv[0].tv_usec = ts[0].tv_nsec / 1000;
|
||||
tv[0] = _timespec2timeval(ts[0]);
|
||||
}
|
||||
if (ts[1].tv_nsec == UTIME_NOW) {
|
||||
tv[1] = now;
|
||||
} else if (ts[1].tv_nsec == UTIME_OMIT) {
|
||||
tv[1].tv_sec = st.st_mtim.tv_sec;
|
||||
tv[1].tv_usec = st.st_mtim.tv_nsec / 1000;
|
||||
tv[1] = _timespec2timeval(st.st_mtim);
|
||||
} else {
|
||||
tv[1].tv_sec = ts[1].tv_sec;
|
||||
tv[1].tv_usec = ts[1].tv_nsec / 1000;
|
||||
tv[1] = _timespec2timeval(ts[1]);
|
||||
}
|
||||
} else {
|
||||
tv[0] = now;
|
||||
|
|
|
@ -37,6 +37,15 @@
|
|||
#define AI_ADDRCONFIG 0x0400
|
||||
#define AI_V4MAPPED 0x0800
|
||||
|
||||
#define NI_NUMERICSCOPE 0
|
||||
#define NI_NUMERICHOST 1
|
||||
#define NI_NUMERICSERV 2
|
||||
#define NI_NOFQDN 4
|
||||
#define NI_NAMEREQD 8
|
||||
#define NI_DGRAM 16
|
||||
#define NI_MAXSERV 32
|
||||
#define NI_MAXHOST 1025
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_ENT_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_ENT_H_
|
||||
#include "libc/dns/dns.h"
|
||||
|
||||
#define HOST_NOT_FOUND 1
|
||||
#define TRY_AGAIN 2
|
||||
#define NO_RECOVERY 3
|
||||
#define NO_DATA 4
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
struct netent {
|
||||
char *n_name; /* official network name */
|
||||
char **n_aliases; /* alias list */
|
||||
|
@ -35,6 +39,10 @@ struct servent {
|
|||
char *s_proto; /* protocol to use */
|
||||
};
|
||||
|
||||
extern int h_errno;
|
||||
void herror(const char *);
|
||||
const char *hstrerror(int);
|
||||
|
||||
struct netent *getnetent(void);
|
||||
struct netent *getnetbyname(const char *);
|
||||
struct netent *getnetbyaddr(uint32_t, int);
|
||||
|
|
24
libc/dns/h_errno.c
Normal file
24
libc/dns/h_errno.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- 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/dns/dns.h"
|
||||
|
||||
/**
|
||||
* Error number global for gethostbyname*(), gethostbyaddr*(), etc.
|
||||
*/
|
||||
int h_errno;
|
|
@ -25,12 +25,12 @@
|
|||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/ent.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int h_errno;
|
||||
|
||||
/**
|
||||
* Prints `h_errno` description to stderr.
|
||||
* @see perror()
|
||||
*/
|
||||
void herror(const char *s) {
|
||||
}
|
||||
|
||||
const char *hstrerror(int err) {
|
||||
return "unknown";
|
||||
fprintf(stderr, "%s%s%s\n", s ? s : "", s ? ": " : "", hstrerror(h_errno));
|
||||
}
|
||||
|
|
37
libc/dns/hstrerror.c
Normal file
37
libc/dns/hstrerror.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- 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/dns/ent.h"
|
||||
|
||||
/**
|
||||
* Turns `h_errno` value into string.
|
||||
*/
|
||||
const char *hstrerror(int err) {
|
||||
switch (err) {
|
||||
case HOST_NOT_FOUND:
|
||||
return "HOST_NOT_FOUND";
|
||||
case TRY_AGAIN:
|
||||
return "TRY_AGAIN";
|
||||
case NO_RECOVERY:
|
||||
return "NO_RECOVERY";
|
||||
case NO_DATA:
|
||||
return "NO_DATA";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
|
@ -42,6 +42,7 @@ size_t wcsxfrm(wchar_t *, const wchar_t *, size_t);
|
|||
│ cosmopolitan § conversion » time ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
struct timeval _timespec2timeval(struct timespec);
|
||||
int64_t DosDateTimeToUnix(unsigned, unsigned) libcesque nosideeffect;
|
||||
struct timeval WindowsTimeToTimeVal(int64_t) libcesque nosideeffect;
|
||||
struct timespec WindowsTimeToTimeSpec(int64_t) libcesque nosideeffect;
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigaltstack.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/struct/iovec.h"
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
|
@ -52,6 +54,8 @@ const char *DescribeProtFlags(char[48], int);
|
|||
const char *DescribeRemapFlags(char[48], int);
|
||||
const char *DescribeRlimit(char[64], int, const struct rlimit *);
|
||||
const char *DescribeRlimitName(char[20], int);
|
||||
const char *DescribeSchedParam(char[32], const struct sched_param *);
|
||||
const char *DescribeSchedPolicy(char[48], int);
|
||||
const char *DescribeSeccompOperation(int);
|
||||
const char *DescribeSigaction(char[128], int, const struct sigaction *);
|
||||
const char *DescribeSigaltstk(char[128], int, const struct sigaltstack *);
|
||||
|
@ -64,6 +68,7 @@ const char *DescribeSocketProtocol(char[12], int);
|
|||
const char *DescribeSocketType(char[64], int);
|
||||
const char *DescribeStat(char[300], int, const struct stat *);
|
||||
const char *DescribeTimespec(char[45], int, const struct timespec *);
|
||||
const char *DescribeTimeval(char[45], int, const struct timeval *);
|
||||
|
||||
void DescribeIov(const struct iovec *, int, ssize_t);
|
||||
void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
||||
|
@ -95,6 +100,8 @@ void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
|||
#define DescribeRemapFlags(dirfd) DescribeRemapFlags(alloca(48), dirfd)
|
||||
#define DescribeRlimit(rc, rl) DescribeRlimit(alloca(64), rc, rl)
|
||||
#define DescribeRlimitName(rl) DescribeRlimitName(alloca(20), rl)
|
||||
#define DescribeSchedParam(x) DescribeSchedParam(alloca(32), x)
|
||||
#define DescribeSchedPolicy(x) DescribeSchedPolicy(alloca(48), x)
|
||||
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(128), rc, sa)
|
||||
#define DescribeSigaltstk(rc, ss) DescribeSigaltstk(alloca(128), rc, ss)
|
||||
#define DescribeSigset(rc, ss) DescribeSigset(alloca(64), rc, ss)
|
||||
|
@ -106,6 +113,7 @@ void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
|||
#define DescribeSocketType(x) DescribeSocketType(alloca(64), x)
|
||||
#define DescribeStat(rc, st) DescribeStat(alloca(300), rc, st)
|
||||
#define DescribeTimespec(rc, ts) DescribeTimespec(alloca(45), rc, ts)
|
||||
#define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts)
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
36
libc/intrin/describeschedparam.c
Normal file
36
libc/intrin/describeschedparam.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- 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/struct/sched_param.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeSchedParam)(char buf[32], const struct sched_param *x) {
|
||||
char *p;
|
||||
if (!x) return "0";
|
||||
p = buf;
|
||||
*p++ = '{';
|
||||
p = FormatInt32(p, x->sched_priority);
|
||||
*p++ = '}';
|
||||
*p = 0;
|
||||
return buf;
|
||||
}
|
40
libc/intrin/describeschedpolicy.c
Normal file
40
libc/intrin/describeschedpolicy.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- 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/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeSchedPolicy)(char buf[48], int x) {
|
||||
struct DescribeFlags flags[] = {
|
||||
{SCHED_RESET_ON_FORK, "RESET_ON_FORK"}, //
|
||||
{SCHED_OTHER, "OTHER"}, //
|
||||
{SCHED_FIFO, "FIFO"}, //
|
||||
{SCHED_RR, "RR"}, //
|
||||
{SCHED_BATCH, "BATCH"}, //
|
||||
{SCHED_IDLE, "IDLE"}, //
|
||||
{SCHED_DEADLINE, "DEADLINE"}, //
|
||||
};
|
||||
return DescribeFlags(buf, 48, flags, ARRAYLEN(flags), "SCHED_", x);
|
||||
}
|
35
libc/intrin/describetimeval.c
Normal file
35
libc/intrin/describetimeval.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
const char *(DescribeTimeval)(char buf[45], int rc, const struct timeval *tv) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!tv) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(tv)) ||
|
||||
(IsAsan() && !__asan_is_valid(tv, sizeof(*tv)))) {
|
||||
ksnprintf(buf, 45, "%p", tv);
|
||||
} else {
|
||||
ksnprintf(buf, 45, "{%ld, %ld}", tv->tv_sec, tv->tv_usec);
|
||||
}
|
||||
return buf;
|
||||
}
|
|
@ -145,10 +145,7 @@ o/$(MODE)/libc/intrin/createfilemapping.o \
|
|||
o/$(MODE)/libc/intrin/createfilemappingnuma.o \
|
||||
o/$(MODE)/libc/intrin/waitformultipleobjects.o \
|
||||
o/$(MODE)/libc/intrin/generateconsolectrlevent.o \
|
||||
o/$(MODE)/libc/intrin/wsawaitformultipleevents.o \
|
||||
o/$(MODE)/libc/intrin/kstarttsc.o \
|
||||
o/$(MODE)/libc/intrin/nomultics.o \
|
||||
o/$(MODE)/libc/intrin/ntconsolemode.o: \
|
||||
o/$(MODE)/libc/intrin/wsawaitformultipleevents.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Os \
|
||||
-fwrapv \
|
||||
|
|
|
@ -22,17 +22,11 @@
|
|||
.privileged
|
||||
|
||||
// Asks kernel to let other threads be scheduled.
|
||||
//
|
||||
// @return 0 on success, or -1 w/ errno
|
||||
// @return 0 on success, or non-zero on failure
|
||||
// @norestart
|
||||
sched_yield:
|
||||
|
||||
#if SupportsXnu()
|
||||
testb IsXnu()
|
||||
jz 1f
|
||||
pause
|
||||
xor %eax,%eax
|
||||
ret
|
||||
#endif
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
||||
#if SupportsWindows()
|
||||
// Windows Support
|
||||
|
@ -46,32 +40,43 @@ sched_yield:
|
|||
// ──Quoth MSDN
|
||||
testb IsWindows()
|
||||
jz 1f
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
xor %ecx,%ecx
|
||||
xor %edx,%edx
|
||||
ntcall __imp_SleepEx
|
||||
xor %eax,%eax
|
||||
pop %rbp
|
||||
ret
|
||||
jmp 9f
|
||||
1:
|
||||
#endif
|
||||
|
||||
#if SupportsSystemv()
|
||||
// UNIX Support
|
||||
1: mov __NR_sched_yield,%eax
|
||||
#if SupportsBsd() && SupportsLinux()
|
||||
clc
|
||||
#endif
|
||||
// On XNU we polyfill sched_yield() using sleep() which'll
|
||||
// be polyfilled using select() with a zero timeout, which
|
||||
// means to wait zero microseconds and then returns a zero
|
||||
// and this hopefully will give other threads a chance too
|
||||
//
|
||||
// "If the readfds, writefds, and errorfds arguments are
|
||||
// all null pointers and the timeout argument is not a
|
||||
// null pointer, the pselect() or select() function shall
|
||||
// block for the time specified, or until interrupted by
|
||||
// a signal." ──Quoth IEEE 1003.1-2017 §functions/select
|
||||
//
|
||||
// On other platforms, sched_yield() takes no arguments.
|
||||
push $0 # timeout.tv_usec
|
||||
push $0 # timeout.tv_sec
|
||||
xor %edi,%edi # nfds
|
||||
xor %esi,%esi # readfds
|
||||
xor %edx,%edx # writefds
|
||||
xor %r10d,%r10d # exceptfds
|
||||
mov %rsp,%r8 # timeout
|
||||
mov __NR_sched_yield,%eax # ordinal
|
||||
clc # linux
|
||||
syscall
|
||||
#if SupportsBsd()
|
||||
jc systemfive_errno
|
||||
#endif
|
||||
#if SupportsLinux()
|
||||
cmp $-4095,%rax
|
||||
jae systemfive_error
|
||||
#endif
|
||||
// It should not be possible for this to fail so we don't
|
||||
// bother going through the errno ritual. If this somehow
|
||||
// fails a positive or negative errno might get returned.
|
||||
#endif
|
||||
|
||||
2: ret
|
||||
9: leave
|
||||
ret
|
||||
.endfn sched_yield,globl
|
||||
.previous
|
||||
|
|
45
libc/intrin/timespec2timeval.c
Normal file
45
libc/intrin/timespec2timeval.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- 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/struct/timespec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
|
||||
// we don't want instrumentation because:
|
||||
// - nanosleep() depends on this and ftrace can take microsecs
|
||||
|
||||
/**
|
||||
* Converts `struct timespec` to `struct timeval`.
|
||||
*
|
||||
* This divides ts.tv_nsec by 1000 with upward rounding and overflow
|
||||
* handling. Your ts.tv_nsec must be on the interval `[0,1000000000)`
|
||||
* otherwise `{-1, -1}` is returned.
|
||||
*
|
||||
* @return converted timeval whose tv_usec will be -1 on error
|
||||
*/
|
||||
noinstrument struct timeval _timespec2timeval(struct timespec ts) {
|
||||
if (0 <= ts.tv_nsec && ts.tv_nsec < 1000000000) {
|
||||
if (0 <= ts.tv_nsec && ts.tv_nsec < 1000000000 - 999) {
|
||||
return (struct timeval){ts.tv_sec, (ts.tv_nsec + 999) / 1000};
|
||||
} else {
|
||||
return (struct timeval){ts.tv_sec + 1, 0};
|
||||
}
|
||||
} else {
|
||||
return (struct timeval){-1, -1};
|
||||
}
|
||||
}
|
|
@ -92,9 +92,7 @@ privileged void __install_tls(char tib[64]) {
|
|||
assert(!__tls_enabled);
|
||||
assert(*(int *)(tib + 0x38) != -1);
|
||||
if (IsWindows()) {
|
||||
if (!__tls_index) {
|
||||
__tls_index = TlsAlloc();
|
||||
}
|
||||
asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tib));
|
||||
} else if (IsFreebsd()) {
|
||||
asm volatile("syscall"
|
||||
|
|
|
@ -42,6 +42,7 @@ static struct sigaltstack g_oldsigaltstack;
|
|||
static struct sigaction g_oldcrashacts[8];
|
||||
|
||||
static void InstallCrashHandlers(int extraflags) {
|
||||
int e;
|
||||
size_t i;
|
||||
struct sigaction sa;
|
||||
bzero(&sa, sizeof(sa));
|
||||
|
@ -53,19 +54,24 @@ static void InstallCrashHandlers(int extraflags) {
|
|||
for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) {
|
||||
if (kCrashSigs[i]) {
|
||||
sa.sa_sigaction = (sigaction_f)__oncrash_thunks[i];
|
||||
e = errno;
|
||||
sigaction(kCrashSigs[i], &sa, &g_oldcrashacts[i]);
|
||||
errno = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relegated void RestoreDefaultCrashSignalHandlers(void) {
|
||||
int e;
|
||||
size_t i;
|
||||
sigset_t ss;
|
||||
sigemptyset(&ss);
|
||||
sigprocmask(SIG_SETMASK, &ss, NULL);
|
||||
for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) {
|
||||
if (kCrashSigs[i]) {
|
||||
e = errno;
|
||||
sigaction(kCrashSigs[i], &g_oldcrashacts[i], NULL);
|
||||
errno = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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/strace.internal.h"
|
||||
#include "libc/calls/struct/bpf.h"
|
||||
|
@ -25,12 +26,16 @@
|
|||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/struct/sockaddr.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/audit.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/nrlinux.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
|
@ -38,9 +43,9 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define READONLY 0x8000
|
||||
#define ADDRLESS 0x8000
|
||||
#define INET 0x8000
|
||||
#define UNIX 0x4000
|
||||
#define ADDRLESS 0x2000
|
||||
#define LOCK 0x8000
|
||||
#define TTY 0x8000
|
||||
|
||||
|
@ -58,8 +63,9 @@ static const uint16_t kPledgeLinuxDefault[] = {
|
|||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxStdio[] = {
|
||||
__NR_linux_clock_gettime, //
|
||||
__NR_linux_clock_getres, //
|
||||
__NR_linux_clock_gettime, //
|
||||
__NR_linux_clock_nanosleep, //
|
||||
__NR_linux_close, //
|
||||
__NR_linux_write, //
|
||||
__NR_linux_writev, //
|
||||
|
@ -117,7 +123,6 @@ static const uint16_t kPledgeLinuxStdio[] = {
|
|||
__NR_linux_pipe2, //
|
||||
__NR_linux_poll, //
|
||||
__NR_linux_select, //
|
||||
__NR_linux_recvmsg, //
|
||||
__NR_linux_recvfrom, //
|
||||
__NR_linux_sendto | ADDRLESS, //
|
||||
__NR_linux_ioctl, //
|
||||
|
@ -131,6 +136,7 @@ static const uint16_t kPledgeLinuxStdio[] = {
|
|||
__NR_linux_umask, //
|
||||
__NR_linux_wait4, //
|
||||
__NR_linux_uname, //
|
||||
__NR_linux_prctl, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxFlock[] = {
|
||||
|
@ -151,9 +157,6 @@ static const uint16_t kPledgeLinuxRpath[] = {
|
|||
__NR_linux_faccessat, //
|
||||
__NR_linux_readlink, //
|
||||
__NR_linux_readlinkat, //
|
||||
__NR_linux_chmod, //
|
||||
__NR_linux_fchmod, //
|
||||
__NR_linux_fchmodat, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxWpath[] = {
|
||||
|
@ -167,6 +170,7 @@ static const uint16_t kPledgeLinuxWpath[] = {
|
|||
__NR_linux_access, //
|
||||
__NR_linux_faccessat, //
|
||||
__NR_linux_readlinkat, //
|
||||
__NR_linux_chmod, //
|
||||
__NR_linux_fchmod, //
|
||||
__NR_linux_fchmodat, //
|
||||
};
|
||||
|
@ -186,6 +190,11 @@ static const uint16_t kPledgeLinuxCpath[] = {
|
|||
__NR_linux_mkdirat, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxDpath[] = {
|
||||
__NR_linux_mknod, //
|
||||
__NR_linux_mknodat, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxFattr[] = {
|
||||
__NR_linux_chmod, //
|
||||
__NR_linux_fchmod, //
|
||||
|
@ -235,6 +244,10 @@ static const uint16_t kPledgeLinuxTty[] = {
|
|||
__NR_linux_ioctl | TTY, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxRecvfd[] = {
|
||||
__NR_linux_recvmsg, //
|
||||
};
|
||||
|
||||
static const uint16_t kPledgeLinuxProc[] = {
|
||||
__NR_linux_fork, //
|
||||
__NR_linux_vfork, //
|
||||
|
@ -282,12 +295,14 @@ static const struct Pledges {
|
|||
{"rpath", PLEDGE(kPledgeLinuxRpath)}, //
|
||||
{"wpath", PLEDGE(kPledgeLinuxWpath)}, //
|
||||
{"cpath", PLEDGE(kPledgeLinuxCpath)}, //
|
||||
{"dpath", PLEDGE(kPledgeLinuxDpath)}, //
|
||||
{"flock", PLEDGE(kPledgeLinuxFlock)}, //
|
||||
{"fattr", PLEDGE(kPledgeLinuxFattr)}, //
|
||||
{"inet", PLEDGE(kPledgeLinuxInet)}, //
|
||||
{"unix", PLEDGE(kPledgeLinuxUnix)}, //
|
||||
{"dns", PLEDGE(kPledgeLinuxDns)}, //
|
||||
{"tty", PLEDGE(kPledgeLinuxTty)}, //
|
||||
{"recvfd", PLEDGE(kPledgeLinuxRecvfd)}, //
|
||||
{"proc", PLEDGE(kPledgeLinuxProc)}, //
|
||||
{"thread", PLEDGE(kPledgeLinuxThread)}, //
|
||||
{"exec", PLEDGE(kPledgeLinuxExec)}, //
|
||||
|
@ -321,16 +336,20 @@ static bool AppendFilter(struct Filter *f, struct sock_filter *p, size_t n) {
|
|||
}
|
||||
|
||||
// SYSCALL is only allowed in the .privileged section
|
||||
// We assume program image is loaded in 32-bit spaces
|
||||
static bool AppendOriginVerification(struct Filter *f) {
|
||||
intptr_t x = (intptr_t)__privileged_start;
|
||||
intptr_t y = (intptr_t)__privileged_end;
|
||||
assert(0 < x && x < y && y < INT_MAX);
|
||||
struct sock_filter fragment[] = {
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer)),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, x, 0, 4 - 3),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, y, 0, 5 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
|
||||
/*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L6*/ /* next filter */
|
||||
/*L0*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer) + 4),
|
||||
/*L1*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 2),
|
||||
/*L2*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer)),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, x, 0, 5 - 4),
|
||||
/*L4*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, y, 0, 6 - 5),
|
||||
/*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
|
||||
/*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L7*/ /* next filter */
|
||||
};
|
||||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
@ -469,7 +488,7 @@ static bool AllowGetsockopt(struct Filter *f) {
|
|||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
||||
// The flags parameter must not have:
|
||||
// The flags parameter of mmap() must not have:
|
||||
//
|
||||
// - MAP_LOCKED (0x02000)
|
||||
// - MAP_POPULATE (0x08000)
|
||||
|
@ -477,24 +496,25 @@ static bool AllowGetsockopt(struct Filter *f) {
|
|||
// - MAP_HUGETLB (0x40000)
|
||||
//
|
||||
static bool AllowMmap(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 9 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), // prot
|
||||
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80), // lazy
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])), // flags
|
||||
/*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x5a000),
|
||||
/*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 7),
|
||||
/*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L9*/ /* next filter */
|
||||
intptr_t y = (intptr_t)__privileged_end;
|
||||
assert(0 < y && y < INT_MAX);
|
||||
struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 6 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])), // flags
|
||||
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x5a000),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L6*/ /* next filter */
|
||||
};
|
||||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
||||
// The prot parameter of mmap() must not have:
|
||||
// The prot parameter of mmap() may only have:
|
||||
//
|
||||
// - PROT_EXEC (4)
|
||||
// - PROT_NONE (0)
|
||||
// - PROT_READ (1)
|
||||
// - PROT_WRITE (2)
|
||||
//
|
||||
// The flags parameter must not have:
|
||||
//
|
||||
|
@ -507,7 +527,7 @@ static bool AllowMmapNoexec(struct Filter *f) {
|
|||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 9 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), // prot
|
||||
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, PROT_EXEC),
|
||||
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])), // flags
|
||||
/*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x5a000),
|
||||
|
@ -519,15 +539,17 @@ static bool AllowMmapNoexec(struct Filter *f) {
|
|||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
||||
// The prot parameter of mprotect() must not have:
|
||||
// The prot parameter of mprotect() may only have:
|
||||
//
|
||||
// - PROT_EXEC (4)
|
||||
// - PROT_NONE (0)
|
||||
// - PROT_READ (1)
|
||||
// - PROT_WRITE (2)
|
||||
//
|
||||
static bool AllowMprotectNoexec(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mprotect, 0, 6 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), // prot
|
||||
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, PROT_EXEC),
|
||||
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
|
@ -536,10 +558,9 @@ static bool AllowMprotectNoexec(struct Filter *f) {
|
|||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
||||
// The flags parameter of open() must not have:
|
||||
// The open() system call is permitted only when
|
||||
//
|
||||
// - O_WRONLY (1)
|
||||
// - O_RDWR (2)
|
||||
// - (flags & O_ACCMODE) == O_RDONLY
|
||||
//
|
||||
static bool AllowOpenReadonly(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
|
@ -677,11 +698,30 @@ static bool AllowFcntlLock(struct Filter *f) {
|
|||
//
|
||||
// - NULL
|
||||
//
|
||||
static bool AllowSendtoRestricted(struct Filter *f) {
|
||||
static bool AllowSendtoAddrless(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_sendto, 0, 5 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4])),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 4 - 3),
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_sendto, 0, 7 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4]) + 0),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 3),
|
||||
/*L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4]) + 4),
|
||||
/*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 3),
|
||||
/*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L7*/ /* next filter */
|
||||
};
|
||||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
||||
// The sig parameter of sigaction() must NOT be
|
||||
//
|
||||
// - SIGSYS (31)
|
||||
//
|
||||
static bool AllowSigaction(struct Filter *f) {
|
||||
static const int nr = __NR_linux_sigaction;
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 5 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 31, 4 - 3, 0),
|
||||
/*L3*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L5*/ /* next filter */
|
||||
|
@ -694,15 +734,39 @@ static bool AllowSendtoRestricted(struct Filter *f) {
|
|||
// - AF_INET (2)
|
||||
// - AF_INET6 (10)
|
||||
//
|
||||
// The type parameter of socket() will ignore:
|
||||
//
|
||||
// - SOCK_CLOEXEC (0x80000)
|
||||
// - SOCK_NONBLOCK (0x00800)
|
||||
//
|
||||
// The type parameter of socket() must be one of:
|
||||
//
|
||||
// - SOCK_STREAM (1)
|
||||
// - SOCK_DGRAM (2)
|
||||
//
|
||||
// The protocol parameter of socket() must be one of:
|
||||
//
|
||||
// - 0
|
||||
// - IPPROTO_TCP (6)
|
||||
// - IPPROTO_UDP (17)
|
||||
//
|
||||
static bool AllowSocketInet(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 6 - 1),
|
||||
/* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 14 - 1),
|
||||
/* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
||||
/* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 5 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L6*/ /* next filter */
|
||||
/* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4),
|
||||
/* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
|
||||
/* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800),
|
||||
/* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0),
|
||||
/* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8),
|
||||
/* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
|
||||
/* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0),
|
||||
/*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 12 - 11, 0),
|
||||
/*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 - 11),
|
||||
/*L12*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L14*/ /* next filter */
|
||||
};
|
||||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
@ -712,14 +776,60 @@ static bool AllowSocketInet(struct Filter *f) {
|
|||
// - AF_UNIX (1)
|
||||
// - AF_LOCAL (1)
|
||||
//
|
||||
// The type parameter of socket() will ignore:
|
||||
//
|
||||
// - SOCK_CLOEXEC (0x80000)
|
||||
// - SOCK_NONBLOCK (0x00800)
|
||||
//
|
||||
// The type parameter of socket() must be one of:
|
||||
//
|
||||
// - SOCK_STREAM (1)
|
||||
// - SOCK_DGRAM (2)
|
||||
//
|
||||
// The protocol parameter of socket() must be one of:
|
||||
//
|
||||
// - 0
|
||||
//
|
||||
static bool AllowSocketUnix(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 5 - 1),
|
||||
/* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 11 - 1),
|
||||
/* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 0, 4 - 3),
|
||||
/*L3*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L5*/ /* next filter */
|
||||
/* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 0, 10 - 3),
|
||||
/* L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
|
||||
/* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800),
|
||||
/* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 7 - 6, 0),
|
||||
/* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 10 - 7),
|
||||
/* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
|
||||
/* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 10 - 9),
|
||||
/* L9*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L10*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L11*/ /* next filter */
|
||||
};
|
||||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
||||
// The first parameter of prctl() can be any of
|
||||
//
|
||||
// - PR_SET_NO_NEW_PRIVS (38)
|
||||
// - PR_SET_SECCOMP (22)
|
||||
//
|
||||
// The second parameter of prctl() can be any of
|
||||
//
|
||||
// - true (1)
|
||||
// - SECCOMP_MODE_FILTER (2)
|
||||
//
|
||||
static bool AllowPrctl(struct Filter *f) {
|
||||
static const struct sock_filter fragment[] = {
|
||||
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prctl, 0, 9 - 1),
|
||||
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
||||
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 38, 4 - 3, 0),
|
||||
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 0, 8 - 4),
|
||||
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
|
||||
/*L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 7 - 6, 0),
|
||||
/*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 8 - 7),
|
||||
/*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
/*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||
/*L9*/ /* next filter */
|
||||
};
|
||||
return AppendFilter(f, PLEDGE(fragment));
|
||||
}
|
||||
|
@ -809,6 +919,12 @@ static bool AppendPledge(struct Filter *f, const uint16_t *p, size_t len,
|
|||
case __NR_linux_fchmodat:
|
||||
if (!AllowFchmodat(f)) return false;
|
||||
break;
|
||||
case __NR_linux_sigaction:
|
||||
if (!AllowSigaction(f)) return false;
|
||||
break;
|
||||
case __NR_linux_prctl:
|
||||
if (!AllowPrctl(f)) return false;
|
||||
break;
|
||||
case __NR_linux_open:
|
||||
if (!AllowOpen(f)) return false;
|
||||
break;
|
||||
|
@ -846,9 +962,10 @@ static bool AppendPledge(struct Filter *f, const uint16_t *p, size_t len,
|
|||
if (!AllowSocketUnix(f)) return false;
|
||||
break;
|
||||
case __NR_linux_sendto | ADDRLESS:
|
||||
if (!AllowSendtoRestricted(f)) return false;
|
||||
if (!AllowSendtoAddrless(f)) return false;
|
||||
break;
|
||||
default:
|
||||
assert(~p[i] & ~0xfff);
|
||||
if (!AllowSyscall(f, p[i])) return false;
|
||||
break;
|
||||
}
|
||||
|
@ -912,11 +1029,13 @@ static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
|||
*
|
||||
* pledge("stdio tty", 0);
|
||||
*
|
||||
* Pledging causes most system calls to become unavailable. On Linux the
|
||||
* disabled calls will return EPERM whereas OpenBSD kills the process.
|
||||
*
|
||||
* Using pledge is irreversible. On Linux it causes PR_SET_NO_NEW_PRIVS
|
||||
* to be set on your process.
|
||||
* Pledging causes most system calls to become unavailable. Your system
|
||||
* call policy is enforced by the kernel, which means it can propagate
|
||||
* across execve() if permitted. This system call is supported on
|
||||
* OpenBSD and Linux where it's polyfilled using SECCOMP BPF. The way it
|
||||
* works on Linux is verboten system calls will raise EPERM whereas
|
||||
* OpenBSD just kills the process while logging a helpful message to
|
||||
* /var/log/messages explaining which promise category you needed.
|
||||
*
|
||||
* By default exit and exit_group are always allowed. This is useful
|
||||
* for processes that perform pure computation and interface with the
|
||||
|
@ -926,9 +1045,8 @@ static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
|||
* permit the sticky/setuid/setgid bits to change. Linux will EPERM here
|
||||
* and OpenBSD should ignore those three bits rather than crashing.
|
||||
*
|
||||
* User and group IDs also can't be changed once pledge is in effect.
|
||||
* OpenBSD should ignore the chown functions without crashing. Linux
|
||||
* will just EPERM.
|
||||
* User and group IDs can't be changed once pledge is in effect. OpenBSD
|
||||
* should ignore chown without crashing; whereas Linux will just EPERM.
|
||||
*
|
||||
* Memory functions won't permit creating executable code after pledge.
|
||||
* Restrictions on origin of SYSCALL instructions will become enforced
|
||||
|
@ -937,26 +1055,40 @@ static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
|||
* exception is if the "exec" group is specified, in which case these
|
||||
* restrictions need to be loosened.
|
||||
*
|
||||
* Using pledge is irreversible. On Linux it causes PR_SET_NO_NEW_PRIVS
|
||||
* to be set on your process; however, if "id" or "recvfd" are allowed
|
||||
* then then they theoretically could permit the gaining of some new
|
||||
* privileges. You may call pledge() multiple times if "stdio" is
|
||||
* allowed. In that case, the process can only move towards a more
|
||||
* restrictive state.
|
||||
*
|
||||
* pledge() can't filter file system paths or internet addresses. For
|
||||
* example, if you enable a category like "inet" then your process will
|
||||
* be able to talk to any internet address. The same applies to
|
||||
* categories like "wpath" and "cpath"; if enabled, any path the
|
||||
* effective user id is permitted to change will be changeable.
|
||||
*
|
||||
* `promises` is a string that may include any of the following groups
|
||||
* delimited by spaces.
|
||||
*
|
||||
* - "stdio" allows clock_getres, clock_gettime, close, dup, dup2, dup3,
|
||||
* fchdir, fstat, fsync, fdatasync, ftruncate, getdents, getegid,
|
||||
* getrandom, geteuid, getgid, getgroups, getitimer, getpgid, getpgrp,
|
||||
* getpid, getppid, getresgid, getresuid, getrlimit, getsid,
|
||||
* gettimeofday, getuid, lseek, madvise, brk, arch_prctl, uname,
|
||||
* set_tid_address, mmap (PROT_EXEC and weird flags aren't allowed),
|
||||
* mprotect (PROT_EXEC isn't allowed), msync, munmap, nanosleep, pipe,
|
||||
* pipe2, read, readv, pread, recv, recvmsg, poll, recvfrom, preadv,
|
||||
* write, writev, pwrite, pwritev, select, send, sendto (only if addr
|
||||
* is null), setitimer, shutdown, sigaction, sigaltstack, sigprocmask,
|
||||
* sigreturn, sigsuspend, umask socketpair, wait4, ioctl(FIONREAD),
|
||||
* ioctl(FIONBIO), ioctl(FIOCLEX), ioctl(FIONCLEX), fcntl(F_GETFD),
|
||||
* fcntl(F_SETFD), fcntl(F_GETFL), fcntl(F_SETFL).
|
||||
* - "stdio" allows close, dup, dup2, dup3, fchdir, fstat, fsync,
|
||||
* fdatasync, ftruncate, getdents, getegid, getrandom, geteuid,
|
||||
* getgid, getgroups, getitimer, getpgid, getpgrp, getpid, getppid,
|
||||
* getresgid, getresuid, getrlimit, getsid, wait4, gettimeofday,
|
||||
* getuid, lseek, madvise, brk, arch_prctl, uname, set_tid_address,
|
||||
* clock_getres, clock_gettime, clock_nanosleep, mmap (PROT_EXEC and
|
||||
* weird flags aren't allowed), mprotect (PROT_EXEC isn't allowed),
|
||||
* msync, munmap, nanosleep, pipe, pipe2, read, readv, pread, recv,
|
||||
* poll, recvfrom, preadv, write, writev, pwrite, pwritev, select,
|
||||
* send, sendto (only if addr is null), setitimer, shutdown, sigaction
|
||||
* (but SIGSYS is forbidden), sigaltstack, sigprocmask, sigreturn,
|
||||
* sigsuspend, umask, socketpair, ioctl(FIONREAD), ioctl(FIONBIO),
|
||||
* ioctl(FIOCLEX), ioctl(FIONCLEX), fcntl(F_GETFD), fcntl(F_SETFD),
|
||||
* fcntl(F_GETFL), fcntl(F_SETFL).
|
||||
*
|
||||
* - "rpath" (read-only path ops) allows chdir, getcwd, open(O_RDONLY),
|
||||
* openat(O_RDONLY), stat, fstat, lstat, fstatat, access, faccessat,
|
||||
* readlink, readlinkat, chmod, fchmod, fchmodat.
|
||||
* readlink, readlinkat.
|
||||
*
|
||||
* - "wpath" (write path ops) allows getcwd, open, openat, stat, fstat,
|
||||
* lstat, fstatat, access, faccessat, readlink, readlinkat, chmod,
|
||||
|
@ -966,12 +1098,16 @@ static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
|||
* linkat, symlink, symlinkat, unlink, rmdir, unlinkat, mkdir,
|
||||
* mkdirat.
|
||||
*
|
||||
* - "dpath" (create special path ops) allows mknod, mknodat, mkfifo.
|
||||
*
|
||||
* - "flock" allows flock, fcntl(F_GETLK), fcntl(F_SETLK),
|
||||
* fcntl(F_SETLKW).
|
||||
*
|
||||
* - "tty" allows ioctl(TIOCGWINSZ), ioctl(TCGETS), ioctl(TCSETS),
|
||||
* ioctl(TCSETSW), ioctl(TCSETSF).
|
||||
*
|
||||
* - "recvfd" allows recvmsg(SCM_RIGHTS).
|
||||
*
|
||||
* - "fattr" allows chmod, fchmod, fchmodat, utime, utimes, futimens,
|
||||
* utimensat.
|
||||
*
|
||||
|
@ -998,6 +1134,7 @@ static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
|||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @raise ENOSYS if host os isn't Linux or OpenBSD
|
||||
* @raise EINVAL if `execpromises` is used on Linux
|
||||
*/
|
||||
int pledge(const char *promises, const char *execpromises) {
|
||||
int rc;
|
||||
|
|
|
@ -117,6 +117,7 @@ unsigned char *GetFirstInstruction(void);
|
|||
unsigned char *GetInstructionLengths(void);
|
||||
void __print_maps(void);
|
||||
void __warn_if_powersave(void);
|
||||
const char *__describe_os(void);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/select.h"
|
||||
|
||||
|
@ -30,9 +32,15 @@
|
|||
*/
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
struct timeval *timeout) {
|
||||
int rc;
|
||||
POLLTRACE("select(%d, %p, %p, %p, %s) → ...", nfds, readfds, writefds,
|
||||
exceptfds, DescribeTimeval(0, timeout));
|
||||
if (!IsWindows()) {
|
||||
return sys_select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
rc = sys_select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
} else {
|
||||
return sys_select_nt(nfds, readfds, writefds, exceptfds, timeout);
|
||||
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, timeout);
|
||||
}
|
||||
POLLTRACE("select(%d, %p, %p, %p, [%s]) → %d% m", nfds, readfds, writefds,
|
||||
exceptfds, DescribeTimeval(rc, timeout), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -15,15 +15,6 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
#define INET_ADDRSTRLEN 22
|
||||
|
||||
#define NI_NUMERICHOST 0x01
|
||||
#define NI_NUMERICSERV 0x02
|
||||
#define NI_NOFQDN 0x04
|
||||
#define NI_NAMEREQD 0x08
|
||||
#define NI_DGRAM 0x10
|
||||
|
||||
#define NI_MAXHOST 0xff
|
||||
#define NI_MAXSERV 0x20
|
||||
|
||||
#define htons(u16) bswap_16(u16)
|
||||
#define ntohs(u16) bswap_16(u16)
|
||||
#define htonl(u32) bswap_32(u32)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/scheduler.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/scheduler.h"
|
||||
#include "libc/stdio/spawn.h"
|
||||
#include "libc/stdio/spawna.internal.h"
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall clock_getres,0x1ad0590eaffff0e5,globl
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sched_get_priority_max,0xffffff14cffff092,globl
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sched_get_priority_min,0xffffff14dffff093,globl
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sched_getparam,0xffffff148ffff08f,globl
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sched_getscheduler,0xffffff14affff091,globl
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sched_setparam,0xffffff147ffff08e,globl
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sched_setscheduler,0xffffff149ffff090,globl
|
2
libc/sysv/calls/sys_clock_getres.s
Normal file
2
libc/sysv/calls/sys_clock_getres.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_clock_getres,0x1ad0590eaffff0e5,globl,hidden
|
2
libc/sysv/calls/sys_sched_get_priority_max.s
Normal file
2
libc/sysv/calls/sys_sched_get_priority_max.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_get_priority_max,0xffffff14cffff092,globl,hidden
|
2
libc/sysv/calls/sys_sched_get_priority_min.s
Normal file
2
libc/sysv/calls/sys_sched_get_priority_min.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_get_priority_min,0xffffff14dffff093,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_getaffinity,0xfffffffffffff0cc,globl,hidden
|
||||
.scall sys_sched_getaffinity,0x15dffffffffff0cc,globl,hidden
|
||||
|
|
2
libc/sysv/calls/sys_sched_getparam.s
Normal file
2
libc/sysv/calls/sys_sched_getparam.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_getparam,0x15bfff148ffff08f,globl,hidden
|
2
libc/sysv/calls/sys_sched_getscheduler.s
Normal file
2
libc/sysv/calls/sys_sched_getscheduler.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_getscheduler,0xffffff14affff091,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_setaffinity,0xfffffffffffff0cb,globl,hidden
|
||||
.scall sys_sched_setaffinity,0x15cffffffffff0cb,globl,hidden
|
||||
|
|
2
libc/sysv/calls/sys_sched_setparam.s
Normal file
2
libc/sysv/calls/sys_sched_setparam.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_setparam,0x15afff147ffff08e,globl,hidden
|
2
libc/sysv/calls/sys_sched_setscheduler.s
Normal file
2
libc/sysv/calls/sys_sched_setscheduler.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_setscheduler,0xffffff149ffff090,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_sched_yield,0x15e12a14bffff018,globl,hidden
|
||||
.scall sys_sched_yield,0x15e12a14bf25d018,globl,hidden
|
||||
|
|
|
@ -589,25 +589,25 @@ syscon ss SS_DISABLE 2 4 4 4 4 2 # bsd consensus
|
|||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon clock CLOCK_REALTIME 0 0 0 0 0 0 # consensus
|
||||
syscon clock CLOCK_REALTIME_PRECISE 0 0 9 0 0 0 #
|
||||
syscon clock CLOCK_REALTIME_FAST 0 0 10 0 0 0 #
|
||||
syscon clock CLOCK_REALTIME_COARSE 5 0 10 0 0 0 # Linux 2.6.32+; bsd consensus; not available on RHEL5
|
||||
syscon clock CLOCK_MONOTONIC 1 1 4 3 3 1 # XNU/NT faked; could move backwards if NTP introduces negative leap second
|
||||
syscon clock CLOCK_MONOTONIC_PRECISE 1 1 11 3 3 1 #
|
||||
syscon clock CLOCK_MONOTONIC_FAST 1 1 12 3 3 1 #
|
||||
syscon clock CLOCK_PROCESS_CPUTIME_ID 2 -1 15 2 0x40000000 -1 #
|
||||
syscon clock CLOCK_THREAD_CPUTIME_ID 3 -1 14 4 0x20000000 -1 #
|
||||
syscon clock CLOCK_MONOTONIC_RAW 4 4 0x4000 0x4000 0x4000 4 # actually monotonic; not subject to NTP adjustments; Linux 2.6.28+; XNU/NT/FreeBSD/OpenBSD faked; not available on RHEL5
|
||||
syscon clock CLOCK_REALTIME_COARSE 5 -1 -1 -1 -1 -1 # Linux 2.6.32+; bsd consensus; not available on RHEL5
|
||||
syscon clock CLOCK_MONOTONIC_COARSE 6 -1 -1 -1 -1 -1 # Linux 2.6.32+; bsd consensus; not available on RHEL5
|
||||
syscon clock CLOCK_PROF -1 -1 2 -1 2 -1 #
|
||||
syscon clock CLOCK_BOOTTIME 7 -1 -1 6 -1 -1 #
|
||||
syscon clock CLOCK_REALTIME_ALARM 8 -1 -1 -1 -1 -1 #
|
||||
syscon clock CLOCK_BOOTTIME_ALARM 9 -1 -1 -1 -1 -1 #
|
||||
syscon clock CLOCK_TAI 11 -1 -1 -1 -1 -1 #
|
||||
syscon clock CLOCK_UPTIME -1 -1 5 5 -1 -1 #
|
||||
syscon clock CLOCK_UPTIME_PRECISE -1 -1 7 -1 -1 -1 #
|
||||
syscon clock CLOCK_UPTIME_FAST -1 -1 8 -1 -1 -1 #
|
||||
syscon clock CLOCK_REALTIME_PRECISE -1 -1 9 -1 -1 -1 #
|
||||
syscon clock CLOCK_MONOTONIC_PRECISE -1 -1 11 -1 -1 -1 #
|
||||
syscon clock CLOCK_SECOND -1 -1 13 -1 -1 -1 #
|
||||
syscon clock CLOCK_MONOTONIC_COARSE 6 1 12 3 3 1 # Linux 2.6.32+; bsd consensus; not available on RHEL5
|
||||
syscon clock CLOCK_MONOTONIC_RAW 4 127 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 127 15 2 0x40000000 127 #
|
||||
syscon clock CLOCK_THREAD_CPUTIME_ID 3 127 14 4 0x20000000 127 #
|
||||
syscon clock CLOCK_PROF 127 127 2 127 2 127 #
|
||||
syscon clock CLOCK_BOOTTIME 7 127 127 6 127 127 #
|
||||
syscon clock CLOCK_REALTIME_ALARM 8 127 127 127 127 127 #
|
||||
syscon clock CLOCK_BOOTTIME_ALARM 9 127 127 127 127 127 #
|
||||
syscon clock CLOCK_TAI 11 127 127 127 127 127 #
|
||||
syscon clock CLOCK_UPTIME 127 127 5 5 127 127 #
|
||||
syscon clock CLOCK_UPTIME_PRECISE 127 127 7 127 127 127 #
|
||||
syscon clock CLOCK_UPTIME_FAST 127 127 8 127 127 127 #
|
||||
syscon clock CLOCK_SECOND 127 127 13 127 127 127 #
|
||||
|
||||
# poll()
|
||||
#
|
||||
|
@ -793,6 +793,16 @@ syscon tcp TCP_REPAIR_OPTIONS 22 0 0 0 0 0 # what is it
|
|||
syscon tcp TCP_REPAIR_QUEUE 20 0 0 0 0 0 # what is it
|
||||
syscon tcp TCP_THIN_LINEAR_TIMEOUTS 16 0 0 0 0 0 # what is it
|
||||
|
||||
# https://blog.cloudflare.com/know-your-scm_rights/
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon scm SCM_RIGHTS 1 1 1 1 1 1 # unix consensus; faked nt
|
||||
syscon scm SCM_TIMESTAMP 29 2 2 4 8 0
|
||||
syscon scm SCM_CREDENTIALS 2 0 0 0 0 0
|
||||
syscon scm SCM_TIMESTAMPING 37 0 0 0 0 0
|
||||
syscon scm SCM_TIMESTAMPNS 35 0 0 0 0 0
|
||||
syscon scm SCM_WIFI_STATUS 41 0 0 0 0 0
|
||||
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon ip IP_TOS 1 3 3 3 3 8 # bsd consensus
|
||||
syscon ip IP_TTL 2 4 4 4 4 7 # bsd consensus
|
||||
|
@ -1306,6 +1316,26 @@ syscon futex FUTEX_WAKE 1 0 0 2 0 0
|
|||
syscon futex FUTEX_REQUEUE 3 0 0 3 0 0
|
||||
syscon futex FUTEX_PRIVATE_FLAG 128 0 0 128 0 0
|
||||
|
||||
# lio_listio() magnums
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon lio LIO_WRITE 127 2 1 127 1 127
|
||||
syscon lio LIO_NOWAIT 127 1 0 127 0 127
|
||||
syscon lio LIO_READ 127 1 2 127 2 127
|
||||
syscon lio LIO_WAIT 127 2 1 127 1 127
|
||||
syscon lio LIO_NOP 127 0 0 127 0 127
|
||||
|
||||
# posix scheduling
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon sched SCHED_OTHER 0 127 2 127 0 127 # standard round-robin time-sharing policy
|
||||
syscon sched SCHED_FIFO 1 127 1 127 1 127 # [real-time] first-in, first-out policy
|
||||
syscon sched SCHED_RR 2 127 3 127 2 127 # [real-time] round-robin policy
|
||||
syscon sched SCHED_BATCH 3 127 2 127 0 127 # for "batch" style execution of processes; polyfilled as SCHED_OTHER on non-Linux
|
||||
syscon sched SCHED_IDLE 5 127 2 127 0 127 # for running very low priority background jobs; polyfilled as SCHED_OTHER on non-Linux
|
||||
syscon sched SCHED_DEADLINE 6 127 127 127 127 127 # can only be set by sched_setattr()
|
||||
syscon sched SCHED_RESET_ON_FORK 0x40000000 0 0 0 0 0 # Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork(); no-op on non-Linux
|
||||
|
||||
# Teletypewriter Control, e.g.
|
||||
#
|
||||
# TCSETS → About 70,800 results (0.31 seconds)
|
||||
|
@ -1616,14 +1646,6 @@ syscon shm SHM_LOCKED 0x0400 0 0 0 0 0
|
|||
syscon shm SHM_NORESERVE 0x1000 0 0 0 0 0
|
||||
syscon shm SHM_REMAP 0x4000 0 0 0 0 0
|
||||
|
||||
syscon misc TCPOPT_EOL 0 0 0 0 0 0 # consensus
|
||||
syscon misc TCPOPT_MAXSEG 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc TCPOPT_NOP 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc TCPOPT_SACK 5 5 5 5 5 0 # unix consensus
|
||||
syscon misc TCPOPT_SACK_PERMITTED 4 4 4 4 4 0 # unix consensus
|
||||
syscon misc TCPOPT_TIMESTAMP 8 8 8 8 8 0 # unix consensus
|
||||
syscon misc TCPOPT_WINDOW 3 3 3 3 3 0 # unix consensus
|
||||
|
||||
syscon lock LOCK_UNLOCK_CACHE 54 0 0 0 0 0 # wut
|
||||
|
||||
syscon misc IP6F_MORE_FRAG 0x0100 0x0100 0x0100 0x0100 0x0100 0x0100 # consensus
|
||||
|
@ -1632,37 +1654,6 @@ syscon misc IP6F_RESERVED_MASK 0x0600 0x0600 0x0600 0x0600 0x0600 0x
|
|||
|
||||
syscon misc NO_SENSE 0 0 0 0 0 0 # consensus
|
||||
syscon misc NO_ADDRESS 4 4 4 4 4 0x2afc # unix consensus
|
||||
syscon misc NO_DATA 4 4 4 4 4 0x2afc # unix consensus
|
||||
syscon misc NO_RECOVERY 3 3 3 3 3 0x2afb # unix consensus
|
||||
|
||||
syscon misc NI_DGRAM 0x10 0x10 0x10 0x10 0x10 0x10 # consensus
|
||||
syscon misc NI_MAXSERV 0x20 0x20 0x20 0x20 0x20 0x20 # consensus
|
||||
syscon misc NI_MAXHOST 0x0401 0x0401 0x0401 0x0100 0x0100 0x0401
|
||||
syscon misc NI_NAMEREQD 8 4 4 8 8 4
|
||||
syscon misc NI_NOFQDN 4 1 1 4 4 1
|
||||
syscon misc NI_NUMERICHOST 1 2 2 1 1 2
|
||||
syscon misc NI_NUMERICSERV 2 8 8 2 2 8
|
||||
syscon misc NI_NUMERICSCOPE 0 0 0x20 0 0 0
|
||||
|
||||
syscon misc TCPOLEN_MAXSEG 4 4 4 4 4 0 # unix consensus
|
||||
syscon misc TCPOLEN_SACK_PERMITTED 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc TCPOLEN_TIMESTAMP 10 10 10 10 10 0 # unix consensus
|
||||
syscon misc TCPOLEN_WINDOW 3 3 3 3 3 0 # unix consensus
|
||||
|
||||
syscon misc TELOPT_NAOL 8 8 8 8 8 0 # unix consensus
|
||||
syscon misc TELOPT_NAOP 9 9 9 9 9 0 # unix consensus
|
||||
syscon misc TELOPT_NEW_ENVIRON 39 39 39 39 39 0 # unix consensus
|
||||
syscon misc TELOPT_OLD_ENVIRON 36 36 36 36 36 0 # unix consensus
|
||||
|
||||
syscon misc EXTENDED_MODIFY_DATA_POINTER 0 0 0 0 0 0 # consensus
|
||||
syscon misc EXTENDED_EXTENDED_IDENTIFY 2 0 0 0 0 0
|
||||
syscon misc EXTENDED_MESSAGE 1 0 0 0 0 0
|
||||
syscon misc EXTENDED_SDTR 1 0 0 0 0 0
|
||||
syscon misc EXTENDED_WDTR 3 0 0 0 0 0
|
||||
|
||||
syscon misc ITIMER_REAL 0 0 0 0 0 0 # consensus
|
||||
syscon misc ITIMER_VIRTUAL 1 1 1 1 1 1 # unix consensus (force win)
|
||||
syscon misc ITIMER_PROF 2 2 2 2 2 2 # unix consensus (force win)
|
||||
|
||||
syscon misc L_SET 0 0 0 0 0 0 # consensus
|
||||
syscon misc L_INCR 1 1 1 1 1 0 # unix consensus
|
||||
|
@ -1681,36 +1672,10 @@ syscon misc Q_GETFMT 0x800004 0 0 0 0 0
|
|||
syscon misc Q_GETINFO 0x800005 0 0 0 0 0
|
||||
syscon misc Q_SETINFO 0x800006 0 0 0 0 0
|
||||
|
||||
syscon misc SCM_RIGHTS 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc SCM_TIMESTAMP 29 2 2 4 8 0
|
||||
syscon misc SCM_CREDENTIALS 2 0 0 0 0 0
|
||||
syscon misc SCM_TIMESTAMPING 37 0 0 0 0 0
|
||||
syscon misc SCM_TIMESTAMPNS 35 0 0 0 0 0
|
||||
syscon misc SCM_WIFI_STATUS 41 0 0 0 0 0
|
||||
|
||||
syscon misc FORM_C 3 3 3 3 3 0 # unix consensus
|
||||
syscon misc FORM_N 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc FORM_T 2 2 2 2 2 0 # unix consensus
|
||||
|
||||
syscon misc REC_EOF 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc REC_EOR 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc REC_ESC -1 -1 -1 -1 -1 0 # unix consensus
|
||||
|
||||
syscon misc RPM_PCO_ADD 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc RPM_PCO_CHANGE 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc RPM_PCO_SETGLOBAL 3 3 3 3 3 0 # unix consensus
|
||||
|
||||
syscon misc SEARCH_EQUAL 49 0 0 0 0 0
|
||||
syscon misc SEARCH_EQUAL_12 177 0 0 0 0 0
|
||||
syscon misc SEARCH_HIGH 48 0 0 0 0 0
|
||||
syscon misc SEARCH_HIGH_12 176 0 0 0 0 0
|
||||
syscon misc SEARCH_LOW 50 0 0 0 0 0
|
||||
syscon misc SEARCH_LOW_12 178 0 0 0 0 0
|
||||
|
||||
syscon misc STRU_F 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc STRU_P 3 3 3 3 3 0 # unix consensus
|
||||
syscon misc STRU_R 2 2 2 2 2 0 # unix consensus
|
||||
|
||||
syscon misc _XOPEN_IOV_MAX 0x10 0x10 0x10 0x10 0x10 0 # unix consensus
|
||||
syscon misc _XOPEN_ENH_I18N 1 1 -1 -1 -1 0
|
||||
syscon misc _XOPEN_UNIX 1 1 -1 -1 -1 0
|
||||
|
@ -1740,26 +1705,6 @@ syscon mlock MCL_CURRENT 1 1 1 1 1 0 # unix consensus
|
|||
syscon mlock MCL_FUTURE 2 2 2 2 2 0 # unix consensus
|
||||
syscon mlock MCL_ONFAULT 4 0 0 0 0 0
|
||||
|
||||
syscon misc NS_DSA_MAX_BYTES 405 405 405 0 0 0
|
||||
syscon misc NS_DSA_MIN_SIZE 213 213 213 0 0 0
|
||||
syscon misc NS_DSA_SIG_SIZE 41 41 41 0 0 0
|
||||
syscon misc NS_KEY_PROT_DNSSEC 3 3 3 0 0 0
|
||||
syscon misc NS_KEY_PROT_EMAIL 2 2 2 0 0 0
|
||||
syscon misc NS_KEY_PROT_IPSEC 4 4 4 0 0 0
|
||||
syscon misc NS_KEY_PROT_TLS 1 1 1 0 0 0
|
||||
syscon misc NS_KEY_RESERVED_BITMASK2 0xffff 0xffff 0xffff 0 0 0
|
||||
syscon misc NS_NXT_MAX 127 127 127 0 0 0
|
||||
syscon misc NS_OPT_DNSSEC_OK 0x8000 0x8000 0x8000 0 0 0
|
||||
syscon misc NS_TSIG_ERROR_FORMERR -12 -12 -12 0 0 0
|
||||
syscon misc NS_TSIG_ERROR_NO_SPACE -11 -11 -11 0 0 0
|
||||
syscon misc NS_TSIG_ERROR_NO_TSIG -10 -10 -10 0 0 0
|
||||
syscon misc NS_TSIG_FUDGE 300 300 300 0 0 0
|
||||
syscon misc NS_TSIG_TCP_COUNT 100 100 100 0 0 0
|
||||
|
||||
syscon misc _IOC_NONE 0 0 0 0 0 0 # consensus
|
||||
syscon misc _IOC_READ 2 0 0 0 0 0
|
||||
syscon misc _IOC_WRITE 1 0 0 0 0 0
|
||||
|
||||
syscon misc MLD_LISTENER_QUERY 130 130 130 130 130 0 # unix consensus
|
||||
syscon misc MLD_LISTENER_REPORT 131 131 131 131 131 0 # unix consensus
|
||||
syscon misc MLD_LISTENER_REDUCTION 132 132 132 0 0 0
|
||||
|
@ -1781,13 +1726,6 @@ syscon select FD_SETSIZE 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400
|
|||
syscon misc MATH_ERREXCEPT 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc MATH_ERRNO 1 1 1 1 1 0 # unix consensus
|
||||
|
||||
syscon misc SCHED_FIFO 1 4 1 1 1 0
|
||||
syscon misc SCHED_RR 2 2 3 3 3 0
|
||||
syscon misc SCHED_OTHER 0 1 2 2 2 0
|
||||
syscon misc SCHED_BATCH 3 0 0 0 0 0
|
||||
syscon misc SCHED_IDLE 5 0 0 0 0 0
|
||||
syscon misc SCHED_RESET_ON_FORK 0x40000000 0 0 0 0 0
|
||||
|
||||
syscon misc MCAST_BLOCK_SOURCE 43 84 84 0 0 43
|
||||
syscon misc MCAST_JOIN_GROUP 42 80 80 0 0 41
|
||||
syscon misc MCAST_JOIN_SOURCE_GROUP 46 82 82 0 0 45
|
||||
|
@ -1804,12 +1742,7 @@ syscon misc EFD_CLOEXEC 0x080000 0 0 0 0 0
|
|||
syscon misc EFD_NONBLOCK 0x0800 0 0 0 0 0
|
||||
syscon misc EFD_SEMAPHORE 1 0 0 0 0 0
|
||||
|
||||
syscon misc GOOD 0 0 0 0 0 0 # consensus
|
||||
syscon misc IPPORT_RESERVED 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400 # consensus
|
||||
syscon misc MTRESET 0 0 0 0 0 0 # consensus
|
||||
syscon misc MT_ST_CAN_PARTITIONS 0x0400 0 0 0 0 0
|
||||
syscon misc MT_ST_HPLOADER_OFFSET 0x2710 0 0 0 0 0
|
||||
syscon misc MT_ST_SCSI2LOGICAL 0x0800 0 0 0 0 0
|
||||
|
||||
syscon misc SYNC_FILE_RANGE_WAIT_AFTER 4 0 0 0 0 0
|
||||
syscon misc SYNC_FILE_RANGE_WAIT_BEFORE 1 0 0 0 0 0
|
||||
|
@ -1822,31 +1755,8 @@ syscon misc TFD_TIMER_ABSTIME 1 0 0 0 0 0
|
|||
|
||||
syscon misc USRQUOTA 0 0 0 0 0 0
|
||||
|
||||
syscon misc ABDAY_1 0x020000 14 14 13 13 0
|
||||
syscon misc ABDAY_2 0x020001 15 15 14 14 0
|
||||
syscon misc ABDAY_3 0x020002 0x10 0x10 15 15 0
|
||||
syscon misc ABDAY_4 0x020003 17 17 0x10 0x10 0
|
||||
syscon misc ABDAY_5 0x020004 18 18 17 17 0
|
||||
syscon misc ABDAY_6 0x020005 19 19 18 18 0
|
||||
syscon misc ABDAY_7 0x020006 20 20 19 19 0
|
||||
|
||||
syscon misc DAY_1 0x020007 7 7 6 6 0
|
||||
syscon misc DAY_2 0x020008 8 8 7 7 0
|
||||
syscon misc DAY_3 0x020009 9 9 8 8 0
|
||||
syscon misc DAY_4 0x02000a 10 10 9 9 0
|
||||
syscon misc DAY_5 0x02000b 11 11 10 10 0
|
||||
syscon misc DAY_6 0x02000c 12 12 11 11 0
|
||||
syscon misc DAY_7 0x02000d 13 13 12 12 0
|
||||
|
||||
syscon misc HOST_NOT_FOUND 1 1 1 1 1 0x2af9 # unix consensus
|
||||
syscon misc HOST_NAME_MAX 0x40 0 0 255 255 0
|
||||
|
||||
syscon misc LIO_WRITE 1 2 1 0 0 0
|
||||
syscon misc LIO_NOWAIT 1 1 0 0 0 0
|
||||
syscon misc LIO_READ 0 1 2 0 0 0
|
||||
syscon misc LIO_WAIT 0 2 1 0 0 0
|
||||
syscon misc LIO_NOP 2 0 0 0 0 0
|
||||
|
||||
syscon misc UDP_ENCAP_ESPINUDP_NON_IKE 1 0 1 0 0 0
|
||||
syscon misc UDP_NO_CHECK6_RX 102 0 0 0 0 0
|
||||
syscon misc UDP_NO_CHECK6_TX 101 0 0 0 0 0
|
||||
|
@ -1921,7 +1831,7 @@ syscon nr __NR_pipe 0x0016 0x200002a 0x021e 0x0107 0x02a 0xfff
|
|||
syscon nr __NR_select 0x0017 0x200005d 0x005d 0x0047 0x1a1 0xfff
|
||||
syscon nr __NR_pselect 0xfff 0x200018a 0x020a 0x006e 0x1b4 0xfff
|
||||
syscon nr __NR_pselect6 0x010e 0xfff 0xfff 0xfff 0xfff 0xfff
|
||||
syscon nr __NR_sched_yield 0x0018 0x010003c 0x014b 0x012a 0x15e 0xfff
|
||||
syscon nr __NR_sched_yield 0x0018 0x200005d 0x014b 0x012a 0x15e 0xfff # select() on XNU (previously swtch() but removed in 12.4)
|
||||
syscon nr __NR_mremap 0x0019 0xfff 0xfff 0xfff 0x19b 0xfff
|
||||
syscon nr __NR_mincore 0x001b 0x200004e 0x004e 0x004e 0x04e 0xfff
|
||||
syscon nr __NR_madvise 0x001c 0x200004b 0x004b 0x004b 0x04b 0xfff
|
||||
|
@ -2889,7 +2799,6 @@ syscon misc TOEXEC 1 1 1 1 1 0 # unix consensus
|
|||
syscon misc TOREAD 4 4 4 4 4 0 # unix consensus
|
||||
syscon misc TOWRITE 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc TRANSIENT 4 4 4 4 4 0 # unix consensus
|
||||
syscon misc TRY_AGAIN 2 2 2 2 2 0x2afa # unix consensus
|
||||
syscon misc TSGID 0x0400 0x0400 0x0400 0x0400 0x0400 0 # unix consensus
|
||||
syscon misc TSUID 0x0800 0x0800 0x0800 0x0800 0x0800 0 # unix consensus
|
||||
syscon misc TSVTX 0x0200 0x0200 0x0200 0x0200 0x0200 0 # unix consensus
|
||||
|
@ -3094,7 +3003,6 @@ syscon misc RUN_LVL 1 1 0 0 0 0
|
|||
syscon misc STA_RONLY 0xff00 0 0xff00 0 0 0
|
||||
syscon misc SYMLOOP_MAX 0 0 0 0x20 0x20 0
|
||||
syscon misc THOUSEP 0x010001 51 51 45 45 0
|
||||
syscon misc TIMER_ABSTIME 1 0 1 1 1 0
|
||||
syscon misc TIME_UTC 1 0 1 0 0 0
|
||||
syscon misc TMP_MAX 0x03a2f8 0x1269ae40 0x1269ae40 0x7fffffff 0x7fffffff 0
|
||||
syscon misc TSS_DTOR_ITERATIONS 0 0 4 0 0 0
|
||||
|
@ -3133,21 +3041,6 @@ syscon in IN_OPEN 0x20 0 0 0 0 0
|
|||
syscon in IN_Q_OVERFLOW 0x4000 0 0 0 0 0
|
||||
syscon in IN_UNMOUNT 0x2000 0 0 0 0 0
|
||||
|
||||
syscon misc TYPE_DISK 0 0 0 0 0 0 # consensus
|
||||
syscon misc TYPE_A 1 1 1 1 1 0 # unix consensus
|
||||
syscon misc TYPE_E 2 2 2 2 2 0 # unix consensus
|
||||
syscon misc TYPE_I 3 3 3 3 3 0 # unix consensus
|
||||
syscon misc TYPE_L 4 4 4 4 4 0 # unix consensus
|
||||
syscon misc TYPE_ENCLOSURE 13 0 0 0 0 0
|
||||
syscon misc TYPE_MEDIUM_CHANGER 8 0 0 0 0 0
|
||||
syscon misc TYPE_MOD 7 0 0 0 0 0
|
||||
syscon misc TYPE_NO_LUN 127 0 0 0 0 0
|
||||
syscon misc TYPE_PROCESSOR 3 0 0 0 0 0
|
||||
syscon misc TYPE_ROM 5 0 0 0 0 0
|
||||
syscon misc TYPE_SCANNER 6 0 0 0 0 0
|
||||
syscon misc TYPE_TAPE 1 0 0 0 0 0
|
||||
syscon misc TYPE_WORM 4 0 0 0 0 0
|
||||
|
||||
syscon nd ND_RA_FLAG_MANAGED 0x80 0x80 0x80 0x80 0x80 0x80 # consensus
|
||||
syscon nd ND_RA_FLAG_OTHER 0x40 0x40 0x40 0x40 0x40 0x40 # consensus
|
||||
syscon nd ND_NA_FLAG_OVERRIDE 0x20 0x20 0x20 0x20 0x20 0x20000000 # unix consensus
|
||||
|
@ -3160,36 +3053,4 @@ syscon nd ND_ROUTER_ADVERT 134 134 134 134 134 0 # unix consensus
|
|||
syscon nd ND_ROUTER_SOLICIT 133 133 133 133 133 0 # unix consensus
|
||||
syscon nd ND_RA_FLAG_HOME_AGENT 0x20 0 0 0 0 0x20 # bsd consensus
|
||||
|
||||
syscon misc N_TTY 0 0 0 0 0 0 # consensus
|
||||
syscon misc N_6PACK 7 0 0 0 0 0
|
||||
syscon misc N_AX25 5 0 0 0 0 0
|
||||
syscon misc N_HCI 15 0 0 0 0 0
|
||||
syscon misc N_HDLC 13 0 0 0 0 0
|
||||
syscon misc N_IRDA 11 0 0 0 0 0
|
||||
syscon misc N_MASC 8 0 0 0 0 0
|
||||
syscon misc N_MOUSE 2 0 0 0 0 0
|
||||
syscon misc N_PPP 3 0 0 0 0 0
|
||||
syscon misc N_PROFIBUS_FDL 10 0 0 0 0 0
|
||||
syscon misc N_R3964 9 0 0 0 0 0
|
||||
syscon misc N_SLIP 1 0 0 0 0 0
|
||||
syscon misc N_SMSBLOCK 12 0 0 0 0 0
|
||||
syscon misc N_STRIP 4 0 0 0 0 0
|
||||
syscon misc N_SYNC_PPP 14 0 0 0 0 0
|
||||
syscon misc N_X25 6 0 0 0 0 0
|
||||
|
||||
syscon misc ETH_P_CUST 0x6006 0 0 0 0 0
|
||||
syscon misc ETH_P_DDCMP 6 0 0 0 0 0
|
||||
syscon misc ETH_P_DEC 0x6000 0 0 0 0 0
|
||||
syscon misc ETH_P_DIAG 0x6005 0 0 0 0 0
|
||||
syscon misc ETH_P_DNA_DL 0x6001 0 0 0 0 0
|
||||
syscon misc ETH_P_DNA_RC 0x6002 0 0 0 0 0
|
||||
syscon misc ETH_P_DNA_RT 0x6003 0 0 0 0 0
|
||||
syscon misc ETH_P_IEEE802154 246 0 0 0 0 0
|
||||
syscon misc ETH_P_LAT 0x6004 0 0 0 0 0
|
||||
syscon misc ETH_P_LOCALTALK 9 0 0 0 0 0
|
||||
syscon misc ETH_P_PPP_MP 8 0 0 0 0 0
|
||||
syscon misc ETH_P_RARP 0x8035 0 0 0 0 0
|
||||
syscon misc ETH_P_SCA 0x6007 0 0 0 0 0
|
||||
syscon misc ETH_P_WAN_PPP 7 0 0 0 0 0
|
||||
|
||||
# https://youtu.be/GUQUD3IMbb4?t=85
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_1,0x020000,14,14,13,13,0
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_2,0x020001,15,15,14,14,0
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_3,0x020002,0x10,0x10,15,15,0
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_4,0x020003,17,17,0x10,0x10,0
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_5,0x020004,18,18,17,17,0
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_6,0x020005,19,19,18,18,0
|
|
@ -1,2 +0,0 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABDAY_7,0x020006,20,20,19,19,0
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_BOOTTIME,7,-1,-1,6,-1,-1
|
||||
.syscon clock,CLOCK_BOOTTIME,7,127,127,6,127,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_BOOTTIME_ALARM,9,-1,-1,-1,-1,-1
|
||||
.syscon clock,CLOCK_BOOTTIME_ALARM,9,127,127,127,127,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_MONOTONIC_COARSE,6,-1,-1,-1,-1,-1
|
||||
.syscon clock,CLOCK_MONOTONIC_COARSE,6,1,12,3,3,1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_MONOTONIC_PRECISE,-1,-1,11,-1,-1,-1
|
||||
.syscon clock,CLOCK_MONOTONIC_PRECISE,1,1,11,3,3,1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_MONOTONIC_RAW,4,4,0x4000,0x4000,0x4000,4
|
||||
.syscon clock,CLOCK_MONOTONIC_RAW,4,127,127,127,127,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_PROCESS_CPUTIME_ID,2,-1,15,2,0x40000000,-1
|
||||
.syscon clock,CLOCK_PROCESS_CPUTIME_ID,2,127,15,2,0x40000000,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_PROF,-1,-1,2,-1,2,-1
|
||||
.syscon clock,CLOCK_PROF,127,127,2,127,2,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_REALTIME_ALARM,8,-1,-1,-1,-1,-1
|
||||
.syscon clock,CLOCK_REALTIME_ALARM,8,127,127,127,127,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_REALTIME_COARSE,5,-1,-1,-1,-1,-1
|
||||
.syscon clock,CLOCK_REALTIME_COARSE,5,0,10,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_REALTIME_PRECISE,-1,-1,9,-1,-1,-1
|
||||
.syscon clock,CLOCK_REALTIME_PRECISE,0,0,9,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_SECOND,-1,-1,13,-1,-1,-1
|
||||
.syscon clock,CLOCK_SECOND,127,127,13,127,127,127
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon clock,CLOCK_TAI,11,-1,-1,-1,-1,-1
|
||||
.syscon clock,CLOCK_TAI,11,127,127,127,127,127
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue