diff options
author | Jo-Philipp Wich <jo@mein.io> | 2023-07-14 10:54:38 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2023-08-09 01:03:21 +0200 |
commit | be071072115059726846163c6f28f62dc01573ec (patch) | |
tree | 1bbf6fe1140e6305c86b621d580b9999706e82b2 /platform.c | |
parent | a38315454add264a41094524e1fcf435acb85fe8 (diff) |
treewide: consolidate platform specific code in platform.c
Get rid of most __APPLE__ guards by introducing a central platform.c unit
providing drop-in replacements for missing APIs.
Also move system signal definitions into the new platform file to be able
to share them with the upcoming debug library.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'platform.c')
-rw-r--r-- | platform.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/platform.c b/platform.c new file mode 100644 index 0000000..63a79d4 --- /dev/null +++ b/platform.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2023 Jo-Philipp Wich <jo@mein.io> + * + * 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 <errno.h> + +#include "ucode/platform.h" + +const char *uc_system_signal_names[UC_SYSTEM_SIGNAL_COUNT] = { +#if defined(SIGINT) + [SIGINT] = "INT", +#endif +#if defined(SIGILL) + [SIGILL] = "ILL", +#endif +#if defined(SIGABRT) + [SIGABRT] = "ABRT", +#endif +#if defined(SIGFPE) + [SIGFPE] = "FPE", +#endif +#if defined(SIGSEGV) + [SIGSEGV] = "SEGV", +#endif +#if defined(SIGTERM) + [SIGTERM] = "TERM", +#endif +#if defined(SIGHUP) + [SIGHUP] = "HUP", +#endif +#if defined(SIGQUIT) + [SIGQUIT] = "QUIT", +#endif +#if defined(SIGTRAP) + [SIGTRAP] = "TRAP", +#endif +#if defined(SIGKILL) + [SIGKILL] = "KILL", +#endif +#if defined(SIGPIPE) + [SIGPIPE] = "PIPE", +#endif +#if defined(SIGALRM) + [SIGALRM] = "ALRM", +#endif +#if defined(SIGSTKFLT) + [SIGSTKFLT] = "STKFLT", +#endif +#if defined(SIGPWR) + [SIGPWR] = "PWR", +#endif +#if defined(SIGBUS) + [SIGBUS] = "BUS", +#endif +#if defined(SIGSYS) + [SIGSYS] = "SYS", +#endif +#if defined(SIGURG) + [SIGURG] = "URG", +#endif +#if defined(SIGSTOP) + [SIGSTOP] = "STOP", +#endif +#if defined(SIGTSTP) + [SIGTSTP] = "TSTP", +#endif +#if defined(SIGCONT) + [SIGCONT] = "CONT", +#endif +#if defined(SIGCHLD) + [SIGCHLD] = "CHLD", +#endif +#if defined(SIGTTIN) + [SIGTTIN] = "TTIN", +#endif +#if defined(SIGTTOU) + [SIGTTOU] = "TTOU", +#endif +#if defined(SIGPOLL) + [SIGPOLL] = "POLL", +#endif +#if defined(SIGXFSZ) + [SIGXFSZ] = "XFSZ", +#endif +#if defined(SIGXCPU) + [SIGXCPU] = "XCPU", +#endif +#if defined(SIGVTALRM) + [SIGVTALRM] = "VTALRM", +#endif +#if defined(SIGPROF) + [SIGPROF] = "PROF", +#endif +#if defined(SIGUSR1) + [SIGUSR1] = "USR1", +#endif +#if defined(SIGUSR2) + [SIGUSR2] = "USR2", +#endif +}; + + +#ifdef __APPLE__ +int +pipe2(int pipefd[2], int flags) +{ + if (pipe(pipefd) != 0) + return -1; + + if (flags & O_CLOEXEC) { + if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 || + fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) { + close(pipefd[0]); + close(pipefd[1]); + + return -1; + } + + flags &= ~O_CLOEXEC; + } + + if (fcntl(pipefd[0], F_SETFL, flags) != 0 || + fcntl(pipefd[1], F_SETFL, flags) != 0) { + close(pipefd[0]); + close(pipefd[1]); + + return -1; + } + + return 0; +} + +/* + * sigtimedwait() implementation based on + * https://comp.unix.programmer.narkive.com/rEDH0sPT/sigtimedwait-implementation + * and + * https://github.com/wahern/lunix/blob/master/src/unix.c + */ +static void +sigtimedwait_consume_signal(int signo) +{ +} + +int +sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) +{ + struct timespec elapsed = { 0, 0 }, sleep, rem; + sigset_t pending, unblock, omask; + struct sigaction sa, osa; + int signo; + bool lt; + + while (true) { + sigemptyset(&pending); + sigpending(&pending); + + for (signo = 1; signo < NSIG; signo++) { + if (!sigismember(set, signo) || !sigismember(&pending, signo)) + continue; + + sa.sa_handler = sigtimedwait_consume_signal; + sa.sa_flags = 0; + sigfillset(&sa.sa_mask); + + sigaction(signo, &sa, &osa); + + sigemptyset(&unblock); + sigaddset(&unblock, signo); + sigprocmask(SIG_UNBLOCK, &unblock, &omask); + sigprocmask(SIG_SETMASK, &omask, NULL); + + sigaction(signo, &osa, NULL); + + if (info) { + memset(info, 0, sizeof(*info)); + info->si_signo = signo; + } + + return signo; + } + + sleep.tv_sec = 0; + sleep.tv_nsec = 200000000L; /* 2/10th second */ + rem = sleep; + + if (nanosleep(&sleep, &rem) == 0) { + elapsed.tv_sec += sleep.tv_sec; + elapsed.tv_nsec += sleep.tv_nsec; + + if (elapsed.tv_nsec > 1000000000) { + elapsed.tv_sec++; + elapsed.tv_nsec -= 1000000000; + } + } + else if (errno == EINTR) { + sleep.tv_sec -= rem.tv_sec; + sleep.tv_nsec -= rem.tv_nsec; + + if (sleep.tv_nsec < 0) { + sleep.tv_sec--; + sleep.tv_nsec += 1000000000; + } + + elapsed.tv_sec += sleep.tv_sec; + elapsed.tv_nsec += sleep.tv_nsec; + + if (elapsed.tv_nsec > 1000000000) { + elapsed.tv_sec++; + elapsed.tv_nsec -= 1000000000; + } + } + else { + return errno; + } + + lt = timeout + ? ((elapsed.tv_sec == timeout->tv_sec) + ? (elapsed.tv_nsec < timeout->tv_nsec) + : (elapsed.tv_sec < timeout->tv_sec)) + : true; + + if (!lt) + break; + } + + errno = EAGAIN; + + return -1; +} +#endif |