Make improvements

- Clean up sigaction() code
- Add a port scanner example
- Introduce a ParseCidr() API
- Clean up our futex abstraction code
- Fix a harmless integer overflow in ParseIp()
- Use kernel semaphores on NetBSD to make threads much faster
This commit is contained in:
Justine Tunney 2022-11-07 02:22:09 -08:00
parent 539bddce8c
commit c995838e5c
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
107 changed files with 1085 additions and 492 deletions

View file

@ -184,7 +184,10 @@ o/$(MODE)/libc/calls/timespec_tomicros.o \
o/$(MODE)/libc/calls/timespec_totimeval.o \
o/$(MODE)/libc/calls/timespec_fromnanos.o \
o/$(MODE)/libc/calls/timespec_frommillis.o \
o/$(MODE)/libc/calls/timespec_frommicros.o: private \
o/$(MODE)/libc/calls/timespec_frommicros.o \
o/$(MODE)/libc/calls/timeval_tomillis.o \
o/$(MODE)/libc/calls/timeval_frommillis.o \
o/$(MODE)/libc/calls/timeval_frommicros.o: private \
OVERRIDE_CFLAGS += \
-O2

View file

@ -22,11 +22,6 @@
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigaction-freebsd.internal.h"
#include "libc/calls/struct/sigaction-linux.internal.h"
#include "libc/calls/struct/sigaction-netbsd.h"
#include "libc/calls/struct/sigaction-openbsd.internal.h"
#include "libc/calls/struct/sigaction-xnu.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigaction.internal.h"
#include "libc/calls/struct/siginfo.internal.h"
@ -46,6 +41,7 @@
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/limits.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
@ -58,110 +54,111 @@ STATIC_YOINK("strsignal"); // for kprintf()
#define SA_RESTORER 0x04000000
#ifndef SWITCHEROO
#define SWITCHEROO(S1, S2, A, B, C, D) \
do { \
autotype((S2).A) a = (typeof((S2).A))(S1).A; \
autotype((S2).B) b = (typeof((S2).B))(S1).B; \
autotype((S2).C) c = (typeof((S2).C))(S1).C; \
typeof((S2).D) d; \
bzero(&d, sizeof(d)); \
memcpy(&d, &((S1).D), MIN(sizeof(d), sizeof((S1).D))); \
(S2).A = a; \
(S2).B = b; \
(S2).C = c; \
bzero(&((S2).D), sizeof((S2).D)); \
memcpy(&((S2).D), &d, MIN(sizeof(d), sizeof((S2).D))); \
} while (0);
#endif
union metasigaction {
struct sigaction cosmo;
struct sigaction_linux linux;
struct sigaction_freebsd freebsd;
struct sigaction_openbsd openbsd;
struct sigaction_netbsd netbsd;
struct sigaction_xnu_in xnu_in;
struct sigaction_xnu_out xnu_out;
};
void __sigenter_xnu(int, struct siginfo *, void *) hidden;
void __sigenter_linux(int, struct siginfo *, void *) hidden;
void __sigenter_netbsd(int, struct siginfo *, void *) hidden;
void __sigenter_freebsd(int, struct siginfo *, void *) hidden;
void __sigenter_openbsd(int, struct siginfo *, void *) hidden;
static void sigaction_cosmo2native(union metasigaction *sa) {
void *handler;
uint64_t flags;
void *restorer;
uint32_t mask[4];
if (!sa) return;
switch (__hostos) {
case _HOSTLINUX:
SWITCHEROO(sa->cosmo, sa->linux, sa_handler, sa_flags, sa_restorer,
sa_mask);
break;
case _HOSTXNU:
SWITCHEROO(sa->cosmo, sa->xnu_in, sa_handler, sa_flags, sa_restorer,
sa_mask);
break;
case _HOSTFREEBSD:
SWITCHEROO(sa->cosmo, sa->freebsd, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
case _HOSTOPENBSD:
SWITCHEROO(sa->cosmo, sa->openbsd, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
case _HOSTNETBSD:
SWITCHEROO(sa->cosmo, sa->netbsd, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
default:
break;
flags = sa->cosmo.sa_flags;
handler = sa->cosmo.sa_handler;
restorer = sa->cosmo.sa_restorer;
mask[0] = sa->cosmo.sa_mask.__bits[0];
mask[1] = sa->cosmo.sa_mask.__bits[0] >> 32;
mask[2] = sa->cosmo.sa_mask.__bits[1];
mask[3] = sa->cosmo.sa_mask.__bits[1] >> 32;
if (IsLinux()) {
sa->linux.sa_flags = flags;
sa->linux.sa_handler = handler;
sa->linux.sa_restorer = restorer;
sa->linux.sa_mask[0] = mask[0];
sa->linux.sa_mask[1] = mask[1];
} else if (IsXnu()) {
sa->xnu_in.sa_flags = flags;
sa->xnu_in.sa_handler = handler;
sa->xnu_in.sa_restorer = restorer;
sa->xnu_in.sa_mask[0] = mask[0];
} else if (IsFreebsd()) {
sa->freebsd.sa_flags = flags;
sa->freebsd.sa_handler = handler;
sa->freebsd.sa_mask[0] = mask[0];
sa->freebsd.sa_mask[1] = mask[1];
sa->freebsd.sa_mask[2] = mask[2];
sa->freebsd.sa_mask[3] = mask[3];
} else if (IsOpenbsd()) {
sa->openbsd.sa_flags = flags;
sa->openbsd.sa_handler = handler;
sa->openbsd.sa_mask[0] = mask[0];
} else if (IsNetbsd()) {
sa->netbsd.sa_flags = flags;
sa->netbsd.sa_handler = handler;
sa->netbsd.sa_mask[0] = mask[0];
sa->netbsd.sa_mask[1] = mask[1];
sa->netbsd.sa_mask[2] = mask[2];
sa->netbsd.sa_mask[3] = mask[3];
}
}
static void sigaction_native2cosmo(union metasigaction *sa) {
void *handler;
uint64_t flags;
void *restorer = 0;
uint32_t mask[4] = {0};
if (!sa) return;
switch (__hostos) {
case _HOSTLINUX:
SWITCHEROO(sa->linux, sa->cosmo, sa_handler, sa_flags, sa_restorer,
sa_mask);
break;
case _HOSTXNU:
SWITCHEROO(sa->xnu_out, sa->cosmo, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
case _HOSTFREEBSD:
SWITCHEROO(sa->freebsd, sa->cosmo, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
case _HOSTOPENBSD:
SWITCHEROO(sa->openbsd, sa->cosmo, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
case _HOSTNETBSD:
SWITCHEROO(sa->netbsd, sa->cosmo, sa_handler, sa_flags, sa_flags,
sa_mask);
break;
default:
break;
if (IsLinux()) {
flags = sa->linux.sa_flags;
handler = sa->linux.sa_handler;
restorer = sa->linux.sa_restorer;
mask[0] = sa->linux.sa_mask[0];
mask[1] = sa->linux.sa_mask[1];
} else if (IsXnu()) {
flags = sa->xnu_out.sa_flags;
handler = sa->xnu_out.sa_handler;
mask[0] = sa->xnu_out.sa_mask[0];
} else if (IsFreebsd()) {
flags = sa->freebsd.sa_flags;
handler = sa->freebsd.sa_handler;
mask[0] = sa->freebsd.sa_mask[0];
mask[1] = sa->freebsd.sa_mask[1];
mask[2] = sa->freebsd.sa_mask[2];
mask[3] = sa->freebsd.sa_mask[3];
} else if (IsOpenbsd()) {
flags = sa->openbsd.sa_flags;
handler = sa->openbsd.sa_handler;
mask[0] = sa->openbsd.sa_mask[0];
} else if (IsNetbsd()) {
flags = sa->netbsd.sa_flags;
handler = sa->netbsd.sa_handler;
mask[0] = sa->netbsd.sa_mask[0];
mask[1] = sa->netbsd.sa_mask[1];
mask[2] = sa->netbsd.sa_mask[2];
mask[3] = sa->netbsd.sa_mask[3];
} else {
return;
}
sa->cosmo.sa_flags = flags;
sa->cosmo.sa_handler = handler;
sa->cosmo.sa_restorer = restorer;
sa->cosmo.sa_mask.__bits[0] = mask[0] | (uint64_t)mask[1] << 32;
sa->cosmo.sa_mask.__bits[1] = mask[2] | (uint64_t)mask[3] << 32;
}
static int __sigaction(int sig, const struct sigaction *act,
struct sigaction *oldact) {
_Static_assert((sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd)),
"sigaction cosmo abi needs tuning");
_Static_assert(
(sizeof(struct sigaction) >= sizeof(struct sigaction_linux) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_xnu_in) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_xnu_out) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_freebsd) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_openbsd) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_netbsd)),
"sigaction cosmo abi needs tuning");
int64_t arg4, arg5;
int rc, rva, oldrva;
sigaction_f sigenter;
struct sigaction *ap, copy;
if (IsMetal()) return enosys(); /* TODO: Signals on Metal */
if (!(0 < sig && sig < NSIG)) return einval();
if (!(1 <= sig && sig <= _NSIG)) return einval();
if (sig == SIGKILL || sig == SIGSTOP) return einval();
if (IsAsan() && ((act && !__asan_is_valid(act, sizeof(*act))) ||
(oldact && !__asan_is_valid(oldact, sizeof(*oldact))))) {
@ -184,18 +181,23 @@ static int __sigaction(int sig, const struct sigaction *act,
if (act) {
memcpy(&copy, act, sizeof(copy));
ap = &copy;
if (IsXnu()) {
if (IsLinux()) {
if (!(ap->sa_flags & SA_RESTORER)) {
ap->sa_flags |= SA_RESTORER;
ap->sa_restorer = &__restore_rt;
}
if (IsWsl1()) {
sigenter = __sigenter_wsl;
} else {
sigenter = ap->sa_sigaction;
}
} else if (IsXnu()) {
ap->sa_restorer = (void *)&__sigenter_xnu;
sigenter = __sigenter_xnu;
// mitigate Rosetta signal handling strangeness
// https://github.com/jart/cosmopolitan/issues/455
ap->sa_flags |= SA_SIGINFO;
} else if (IsLinux()) {
if (!(ap->sa_flags & SA_RESTORER)) {
ap->sa_flags |= SA_RESTORER;
ap->sa_restorer = &__restore_rt;
}
sigenter = __sigenter_linux;
} else if (IsNetbsd()) {
sigenter = __sigenter_netbsd;
} else if (IsFreebsd()) {

View file

@ -20,7 +20,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigaction-freebsd.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo-freebsd.internal.h"
#include "libc/calls/struct/siginfo-meta.internal.h"
@ -51,7 +50,7 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
g.uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
g.uc.uc_stack.ss_size = ctx->uc_stack.ss_size;
g.uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
__repmovsb(&g.uc.uc_sigmask, &ctx->uc_sigmask,
__repmovsb(&g.uc.uc_sigmask, ctx->uc_sigmask,
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
g.uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8;
g.uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9;
@ -82,7 +81,7 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
ctx->uc_stack.ss_size = g.uc.uc_stack.ss_size;
ctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags;
ctx->uc_flags = g.uc.uc_flags;
__repmovsb(&ctx->uc_sigmask, &g.uc.uc_sigmask,
__repmovsb(ctx->uc_sigmask, &g.uc.uc_sigmask,
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
ctx->uc_mcontext.mc_rdi = g.uc.uc_mcontext.rdi;
ctx->uc_mcontext.mc_rsi = g.uc.uc_mcontext.rsi;

View file

@ -28,8 +28,7 @@
#include "libc/str/str.h"
#include "libc/sysv/consts/sa.h"
privileged void __sigenter_linux(int sig, struct siginfo *info,
ucontext_t *ctx) {
privileged void __sigenter_wsl(int sig, struct siginfo *info, ucontext_t *ctx) {
int i, rva, flags;
rva = __sighandrvas[sig & (NSIG - 1)];
if (rva >= kSigactionMinRva) {

View file

@ -20,7 +20,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigaction-freebsd.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo-meta.internal.h"
#include "libc/calls/struct/siginfo-netbsd.internal.h"

View file

@ -20,7 +20,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigaction-freebsd.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo-meta.internal.h"
#include "libc/calls/struct/siginfo-openbsd.internal.h"

View file

@ -1,16 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_FREEBSD_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_FREEBSD_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct sigset_freebsd {
uint32_t sig[4];
};
struct sigaction_freebsd {
intptr_t sa_handler;
uint32_t sa_flags;
struct sigset_freebsd sa_mask;
};
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_FREEBSD_H_ */

View file

@ -1,17 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_LINUX_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_LINUX_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct sigset_linux {
uint32_t sig[2];
};
struct sigaction_linux {
intptr_t sa_handler;
uint64_t sa_flags;
void (*sa_restorer)(void);
struct sigset_linux sa_mask;
};
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_LINUX_H_ */

View file

@ -1,18 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_NETBSD_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_NETBSD_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct sigset_netbsd {
uint32_t sig[4];
};
struct sigaction_netbsd {
intptr_t sa_handler;
struct sigset_netbsd sa_mask;
uint32_t sa_flags;
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_NETBSD_H_ */

View file

@ -1,16 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_OPENBSD_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_OPENBSD_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct sigset_openbsd {
uint32_t sig[1];
};
struct sigaction_openbsd {
intptr_t sa_handler;
struct sigset_openbsd sa_mask;
int32_t sa_flags;
};
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_OPENBSD_H_ */

View file

@ -1,27 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_XNU_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_XNU_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct __darwin_ucontext;
struct __darwin_siginfo;
struct sigset_xnu {
uint32_t sig[1];
};
struct sigaction_xnu_in {
intptr_t sa_handler;
void (*sa_restorer)(void *, int, int, const struct __darwin_siginfo *,
const struct __darwin_ucontext *);
struct sigset_xnu sa_mask;
int32_t sa_flags;
};
struct sigaction_xnu_out {
intptr_t sa_handler;
struct sigset_xnu sa_mask;
int32_t sa_flags;
};
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_XNU_H_ */

View file

@ -20,7 +20,6 @@ struct sigaction { /* cosmo abi */
uint64_t sa_flags;
void (*sa_restorer)(void);
struct sigset sa_mask;
int64_t __pad;
};
sighandler_t signal(int, sighandler_t);

View file

@ -1,10 +1,65 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_INTERNAL_H_
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/mem/alloca.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct sigaction_linux {
void *sa_handler;
uint64_t sa_flags;
void *sa_restorer;
uint32_t sa_mask[2];
};
struct sigaction_freebsd {
void *sa_handler;
uint32_t sa_flags;
uint32_t sa_mask[4];
};
struct sigaction_openbsd {
void *sa_handler;
uint32_t sa_mask[1];
uint32_t sa_flags;
};
struct sigaction_netbsd {
void *sa_handler;
uint32_t sa_mask[4];
uint32_t sa_flags;
};
struct sigaction_xnu_in {
void *sa_handler;
void *sa_restorer;
uint32_t sa_mask[1];
uint32_t sa_flags;
};
struct sigaction_xnu_out {
void *sa_handler;
uint32_t sa_mask[1];
uint32_t sa_flags;
};
union metasigaction {
struct sigaction cosmo;
struct sigaction_linux linux;
struct sigaction_freebsd freebsd;
struct sigaction_openbsd openbsd;
struct sigaction_netbsd netbsd;
struct sigaction_xnu_in xnu_in;
struct sigaction_xnu_out xnu_out;
};
void __sigenter_xnu(int, struct siginfo *, void *) hidden;
void __sigenter_wsl(int, struct siginfo *, void *) hidden;
void __sigenter_netbsd(int, struct siginfo *, void *) hidden;
void __sigenter_freebsd(int, struct siginfo *, void *) hidden;
void __sigenter_openbsd(int, struct siginfo *, void *) hidden;
const char *DescribeSigaction(char[256], int, const struct sigaction *);
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(256), rc, sa)

View file

@ -1,7 +1,5 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGINFO_INTERNAL_H_
#include "libc/calls/struct/sigaction-xnu.internal.h"
#include "libc/calls/struct/siginfo-xnu.internal.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/mem/alloca.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)

View file

@ -14,12 +14,13 @@ int sys_clock_gettime_nt(int, struct timespec *) hidden;
int sys_clock_gettime_xnu(int, struct timespec *) hidden;
int sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *) hidden;
int sys_futimens(int, const struct timespec[2]) hidden;
int sys_nanosleep(const struct timespec *, struct timespec *) hidden;
int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden;
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden;
int sys_sem_timedwait(int64_t, const struct timespec *) hidden;
int sys_utimensat(int, const char *, const struct timespec[2], int) hidden;
int sys_utimensat_nt(int, const char *, const struct timespec[2], int) hidden;
int sys_utimensat_xnu(int, const char *, const struct timespec[2], int) hidden;

View file

@ -17,6 +17,8 @@ int lutimes(const char *, const struct timeval[2]);
int utimes(const char *, const struct timeval[2]);
int timeval_cmp(struct timeval, struct timeval) pureconst;
struct timeval timeval_frommicros(int64_t) pureconst;
struct timeval timeval_frommillis(int64_t) pureconst;
struct timeval timeval_add(struct timeval, struct timeval) pureconst;
struct timeval timeval_sub(struct timeval, struct timeval) pureconst;
struct timeval timespec_totimeval(struct timespec) pureconst;

View file

@ -1,6 +1,5 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_FREEBSD_INTERNAL_H_
#include "libc/calls/struct/sigaction-freebsd.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -52,7 +51,7 @@ struct mcontext_freebsd {
};
struct ucontext_freebsd {
struct sigset_freebsd uc_sigmask;
uint32_t uc_sigmask[4];
struct mcontext_freebsd uc_mcontext;
struct ucontext_freebsd *uc_link;
struct stack_freebsd uc_stack;

View file

@ -83,6 +83,15 @@ i32 sys_pivot_root(const char *, const char *) 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_sem_close(i64) hidden;
i32 sys_sem_destroy(i64) hidden;
i32 sys_sem_getvalue(i64, u32 *) hidden;
i32 sys_sem_init(u32, i64 *) hidden;
i32 sys_sem_open(const char *, int, u32, i64 *) hidden;
i32 sys_sem_post(i64) hidden;
i32 sys_sem_trywait(i64) hidden;
i32 sys_sem_unlink(const char *) hidden;
i32 sys_sem_wait(i64) hidden;
i32 sys_setfsgid(i32) hidden;
i32 sys_setfsuid(i32) hidden;
i32 sys_setgid(i32) hidden;

View file

@ -22,8 +22,9 @@
/**
* Converts timespec to scalar.
*
* This function will detect overflow in which case `INT64_MAX` or
* `INT64_MIN` may be returned. The `errno` variable isn't changed.
. * This returns the absolute number of nanoseconds in a timespec. If
* overflow happens, then `INT64_MAX` or `INT64_MIN` is returned. The
* `errno` variable isn't changed.
*
* @return 64-bit integer holding nanoseconds since epoch
*/

View file

@ -0,0 +1,29 @@
/*-*- 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/timeval.h"
/**
* Converts timeval interval from microseconds.
*/
struct timeval timeval_frommicros(int64_t x) {
struct timeval tv;
tv.tv_sec = x / 1000000;
tv.tv_usec = x % 1000000;
return tv;
}

View file

@ -0,0 +1,29 @@
/*-*- 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/timeval.h"
/**
* Converts timeval interval from milliseconds.
*/
struct timeval timeval_frommillis(int64_t x) {
struct timeval tv;
tv.tv_sec = x / 1000;
tv.tv_usec = x % 1000 * 1000;
return tv;
}

View file

@ -0,0 +1,41 @@
/*-*- 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/timeval.h"
#include "libc/limits.h"
/**
* Converts timeval to scalar.
*
* This returns the absolute number of microseconds in a timeval. If
* overflow happens, then `INT64_MAX` or `INT64_MIN` is returned. The
* `errno` variable isn't changed.
*
* @return 64-bit integer holding microseconds since epoch
*/
int64_t timeval_tomicros(struct timeval x) {
int64_t ns;
if (!__builtin_mul_overflow(x.tv_sec, 1000000ul, &ns) &&
!__builtin_add_overflow(ns, x.tv_usec, &ns)) {
return ns;
} else if (x.tv_sec < 0) {
return INT64_MIN;
} else {
return INT64_MAX;
}
}

View file

@ -0,0 +1,56 @@
/*-*- 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/timeval.h"
#include "libc/limits.h"
/**
* Reduces `ts` from 1e-6 to 1e-3 granularity w/ ceil rounding.
*
* This function returns the absolute number of milliseconds in a
* timeval. Ceiling rounding is used. For example, if `ts` is one
* nanosecond, then one millisecond will be returned. Ceil rounding is
* needed by many interfaces, e.g. setitimer(), because the zero
* timestamp has a valial meaning.
*
* This function also detects overflow in which case `INT64_MAX` or
* `INT64_MIN` may be returned. The `errno` variable isn't changed.
*
* @return 64-bit scalar milliseconds since epoch
*/
int64_t timeval_tomillis(struct timeval ts) {
int64_t ms;
// reduce precision from micros to millis
if (ts.tv_usec <= 999000) {
ts.tv_usec = (ts.tv_usec + 999) / 1000;
} else {
ts.tv_usec = 0;
if (ts.tv_sec < INT64_MAX) {
ts.tv_sec += 1;
}
}
// convert to scalar result
if (!__builtin_mul_overflow(ts.tv_sec, 1000ul, &ms) &&
!__builtin_add_overflow(ms, ts.tv_usec, &ms)) {
return ms;
} else if (ts.tv_sec < 0) {
return INT64_MIN;
} else {
return INT64_MAX;
}
}