123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <AK/Format.h>
- #include <assert.h>
- #include <errno.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <string.h>
- #include <sys/select.h>
- #include <syscall.h>
- #include <unistd.h>
- extern "C" {
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html
- int kill(pid_t pid, int sig)
- {
- int rc = syscall(SC_kill, pid, sig);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html
- int killpg(int pgrp, int sig)
- {
- int rc = syscall(SC_killpg, pgrp, sig);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html
- int raise(int sig)
- {
- // FIXME: Support multi-threaded programs.
- return kill(getpid(), sig);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html
- sighandler_t signal(int signum, sighandler_t handler)
- {
- struct sigaction new_act;
- struct sigaction old_act;
- new_act.sa_handler = handler;
- new_act.sa_flags = 0;
- new_act.sa_mask = 0;
- int rc = sigaction(signum, &new_act, &old_act);
- if (rc < 0)
- return SIG_ERR;
- return old_act.sa_handler;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
- int sigaction(int signum, const struct sigaction* act, struct sigaction* old_act)
- {
- int rc = syscall(SC_sigaction, signum, act, old_act);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html
- int sigemptyset(sigset_t* set)
- {
- *set = 0;
- return 0;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigfillset.html
- int sigfillset(sigset_t* set)
- {
- *set = 0xffffffff;
- return 0;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html
- int sigaddset(sigset_t* set, int sig)
- {
- if (sig < 1 || sig > 32) {
- errno = EINVAL;
- return -1;
- }
- *set |= 1 << (sig - 1);
- return 0;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaltstack.html
- int sigaltstack(stack_t const* ss, stack_t* old_ss)
- {
- int rc = syscall(SC_sigaltstack, ss, old_ss);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigdelset.html
- int sigdelset(sigset_t* set, int sig)
- {
- if (sig < 1 || sig > 32) {
- errno = EINVAL;
- return -1;
- }
- *set &= ~(1 << (sig - 1));
- return 0;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigismember.html
- int sigismember(sigset_t const* set, int sig)
- {
- if (sig < 1 || sig > 32) {
- errno = EINVAL;
- return -1;
- }
- if (*set & (1 << (sig - 1)))
- return 1;
- return 0;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html
- int sigprocmask(int how, sigset_t const* set, sigset_t* old_set)
- {
- int rc = syscall(SC_sigprocmask, how, set, old_set);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
- int sigpending(sigset_t* set)
- {
- int rc = syscall(SC_sigpending, set);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- char const* sys_siglist[NSIG] = {
- "Invalid signal number",
- "Hangup",
- "Interrupt",
- "Quit",
- "Illegal instruction",
- "Trap",
- "Aborted",
- "Bus error",
- "Division by zero",
- "Killed",
- "User signal 1",
- "Segmentation violation",
- "User signal 2",
- "Broken pipe",
- "Alarm clock",
- "Terminated",
- "Stack fault",
- "Child exited",
- "Continued",
- "Stopped (signal)",
- "Stopped",
- "Stopped (tty input)",
- "Stopped (tty output)",
- "Urgent I/O condition)",
- "CPU limit exceeded",
- "File size limit exceeded",
- "Virtual timer expired",
- "Profiling timer expired",
- "Window changed",
- "I/O possible",
- "Power failure",
- "Bad system call",
- };
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/siglongjmp.html
- void siglongjmp(jmp_buf env, int val)
- {
- if (env->did_save_signal_mask) {
- int rc = sigprocmask(SIG_SETMASK, &env->saved_signal_mask, nullptr);
- assert(rc == 0);
- }
- longjmp(env, val);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html
- int sigsuspend(sigset_t const* set)
- {
- int rc = syscall(SC_sigsuspend, set);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- // https://pubs.opengroup.org/onlinepubs/009604499/functions/sigwait.html
- int sigwait(sigset_t const* set, int* sig)
- {
- int rc = syscall(Syscall::SC_sigtimedwait, set, nullptr, nullptr);
- VERIFY(rc != 0);
- if (rc < 0)
- return -rc;
- *sig = rc;
- return 0;
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigwaitinfo.html
- int sigwaitinfo(sigset_t const* set, siginfo_t* info)
- {
- return sigtimedwait(set, info, nullptr);
- }
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html
- int sigtimedwait(sigset_t const* set, siginfo_t* info, struct timespec const* timeout)
- {
- int rc = syscall(Syscall::SC_sigtimedwait, set, info, timeout);
- __RETURN_WITH_ERRNO(rc, rc, -1);
- }
- char const* sys_signame[] = {
- "INVAL",
- "HUP",
- "INT",
- "QUIT",
- "ILL",
- "TRAP",
- "ABRT",
- "BUS",
- "FPE",
- "KILL",
- "USR1",
- "SEGV",
- "USR2",
- "PIPE",
- "ALRM",
- "TERM",
- "STKFLT",
- "CHLD",
- "CONT",
- "STOP",
- "TSTP",
- "TTIN",
- "TTOU",
- "URG",
- "XCPU",
- "XFSZ",
- "VTALRM",
- "PROF",
- "WINCH",
- "IO",
- "INFO",
- "SYS",
- };
- static_assert(sizeof(sys_signame) == sizeof(char const*) * NSIG);
- int getsignalbyname(char const* name)
- {
- VERIFY(name);
- StringView name_sv { name, strlen(name) };
- for (size_t i = 0; i < NSIG; ++i) {
- StringView signal_name { sys_signame[i], sizeof(sys_signame[i]) - 1 };
- if (signal_name == name_sv || (name_sv.starts_with("SIG"sv) && signal_name == name_sv.substring_view(3)))
- return i;
- }
- errno = EINVAL;
- return -1;
- }
- char const* getsignalname(int signal)
- {
- if (signal < 0 || signal >= NSIG) {
- errno = EINVAL;
- return nullptr;
- }
- return sys_signame[signal];
- }
- }
|