mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-03 19:22:27 +00:00
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:
parent
539bddce8c
commit
c995838e5c
107 changed files with 1085 additions and 492 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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(©, act, sizeof(copy));
|
||||
ap = ©
|
||||
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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
29
libc/calls/timeval_frommicros.c
Normal file
29
libc/calls/timeval_frommicros.c
Normal 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;
|
||||
}
|
29
libc/calls/timeval_frommillis.c
Normal file
29
libc/calls/timeval_frommillis.c
Normal 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;
|
||||
}
|
41
libc/calls/timeval_tomicros.c
Normal file
41
libc/calls/timeval_tomicros.c
Normal 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;
|
||||
}
|
||||
}
|
56
libc/calls/timeval_tomillis.c
Normal file
56
libc/calls/timeval_tomillis.c
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue