#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" void __mlibc_signal_restore(); namespace mlibc { int sys_sigprocmask(int how, const sigset_t *set, sigset_t *retrieve) { // This implementation is inherently signal-safe. uint64_t former, unused; if(set) { HEL_CHECK(helSyscall2_2(kHelObserveSuperCall + posix::superSigMask, how, *set, &former, &unused)); }else{ HEL_CHECK(helSyscall2_2(kHelObserveSuperCall + posix::superSigMask, 0, 0, &former, &unused)); } if(retrieve) *retrieve = former; return 0; } int sys_sigaction(int number, const struct sigaction *__restrict action, struct sigaction *__restrict saved_action) { SignalGuard sguard; // TODO: Respect restorer. __ensure(!(action->sa_flags & SA_RESTORER)); managarm::posix::CntRequest req(getSysdepsAllocator()); req.set_request_type(managarm::posix::CntReqType::SIG_ACTION); req.set_sig_number(number); if(action) { req.set_mode(1); req.set_flags(action->sa_flags); req.set_sig_mask(action->sa_mask); if(action->sa_flags & SA_SIGINFO) { req.set_sig_handler(reinterpret_cast(action->sa_sigaction)); }else{ req.set_sig_handler(reinterpret_cast(action->sa_handler)); } req.set_sig_restorer(reinterpret_cast(&__mlibc_signal_restore)); } else { req.set_mode(0); } auto [offer, send_req, recv_resp] = exchangeMsgsSync( getPosixLane(), helix_ng::offer( helix_ng::sendBragiHeadOnly(req, getSysdepsAllocator()), helix_ng::recvInline()) ); HEL_CHECK(offer.error()); HEL_CHECK(send_req.error()); HEL_CHECK(recv_resp.error()); managarm::posix::SvrResponse resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); if(resp.error() == managarm::posix::Errors::ILLEGAL_REQUEST) { // This is only returned for servers, not for normal userspace. return ENOSYS; }else if(resp.error() == managarm::posix::Errors::ILLEGAL_ARGUMENTS) { return EINVAL; } __ensure(resp.error() == managarm::posix::Errors::SUCCESS); if(saved_action) { saved_action->sa_flags = resp.flags(); saved_action->sa_mask = resp.sig_mask(); if(resp.flags() & SA_SIGINFO) { saved_action->sa_sigaction = reinterpret_cast(resp.sig_handler()); }else{ saved_action->sa_handler = reinterpret_cast(resp.sig_handler()); } // TODO: saved_action->sa_restorer = resp.sig_restorer; } return 0; } int sys_kill(int pid, int number) { // This implementation is inherently signal-safe. HEL_CHECK(helSyscall2(kHelObserveSuperCall + posix::superSigKill, pid, number)); return 0; } int sys_tgkill(int, int tid, int number) { return sys_kill(tid, number); } int sys_sigaltstack(const stack_t *ss, stack_t *oss) { HelWord out; // This implementation is inherently signal-safe. HEL_CHECK(helSyscall2_1(kHelObserveSuperCall + posix::superSigAltStack, reinterpret_cast(ss), reinterpret_cast(oss), &out)); return out; } int sys_sigsuspend(const sigset_t *set) { //SignalGuard sguard; uint64_t former, seq, unused; HEL_CHECK(helSyscall2_2(kHelObserveSuperCall + posix::superSigMask, SIG_SETMASK, *set, &former, &seq)); HEL_CHECK(helSyscall1(kHelObserveSuperCall + posix::superSigSuspend, seq)); HEL_CHECK(helSyscall2_2(kHelObserveSuperCall + posix::superSigMask, SIG_SETMASK, former, &unused, &unused)); return EINTR; } int sys_sigpending(sigset_t *set) { uint64_t pendingMask; HEL_CHECK(helSyscall0_1(kHelObserveSuperCall + posix::superSigGetPending, &pendingMask)); *set = pendingMask; return 0; } } //namespace mlibc