#include "KernelContext.hpp" #include "sys/sysproto.hpp" #include "thread/Process.hpp" #include "thread/Thread.hpp" #include "ucontext.hpp" #include "utils/Logs.hpp" #include orbis::SysResult orbis::sys_sigaction(Thread *thread, sint sig, ptr act, ptr oact) { ORBIS_LOG_WARNING(__FUNCTION__, sig, act, oact); auto &sigAct = thread->tproc->sigActions[sig]; if (oact != nullptr) { if (auto errc = uwrite(oact, sigAct); errc != orbis::ErrorCode{}) { return errc; } } if (act != nullptr) { if (auto errc = uread(sigAct, act); errc != ErrorCode{}) { return errc; } ORBIS_LOG_WARNING(__FUNCTION__, sigAct.handler, sigAct.flags, sigAct.mask.bits[0], sigAct.mask.bits[1], sigAct.mask.bits[2], sigAct.mask.bits[3]); } return {}; } orbis::SysResult orbis::sys_sigprocmask(Thread *thread, sint how, ptr set, ptr oset) { std::lock_guard lock(thread->mtx); if (oset) { ORBIS_RET_ON_ERROR(uwrite(oset, thread->sigMask)); } if (set) { SigSet _set; ORBIS_RET_ON_ERROR(uread(_set, set)); auto newSigMask = thread->sigMask; auto oldSigMask = newSigMask; switch (how) { case 1: // block for (std::size_t i = 0; i < 4; ++i) { newSigMask.bits[i] |= _set.bits[i]; } break; case 2: // unblock for (std::size_t i = 0; i < 4; ++i) { newSigMask.bits[i] &= ~_set.bits[i]; } break; case 3: // set newSigMask = _set; break; default: ORBIS_LOG_ERROR("sys_sigprocmask: unimplemented how", how); thread->where(); return ErrorCode::INVAL; } newSigMask.clear(kSigKill); newSigMask.clear(kSigStop); thread->sigMask = newSigMask; for (std::size_t word = 0; word < std::size(newSigMask.bits); ++word) { auto unblockedBits = ~oldSigMask.bits[word] & newSigMask.bits[word]; std::uint32_t offset = word * 32 + 1; for (std::uint32_t i = std::countr_zero(unblockedBits); i < 32; i += std::countr_zero(unblockedBits >> (i + 1)) + 1) { thread->notifyUnblockedSignal(offset + i); } } } return {}; } orbis::SysResult orbis::sys_sigwait(Thread *thread, ptr set, ptr sig) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigtimedwait(Thread *thread, ptr set, ptr info, ptr timeout) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigwaitinfo(Thread *thread, ptr set, ptr info) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigpending(Thread *thread, ptr set) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigsuspend(Thread *thread, ptr set) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigaltstack(Thread *thread, ptr ss, ptr oss) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_kill(Thread *thread, sint pid, sint signum) { ORBIS_LOG_WARNING(__FUNCTION__, pid, signum); int hostPid = pid; if (pid > 0) { auto process = g_context.findProcessById(pid); if (process == nullptr) { return ErrorCode::SRCH; } hostPid = process->hostPid; } // TODO: wrap signal // int result = ::kill(hostPid, signum); // if (result < 0) { // return static_cast(errno); // } return {}; } orbis::SysResult orbis::sys_pdkill(Thread *thread, sint fd, sint signum) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigqueue(Thread *thread, pid_t pid, sint signum, ptr value) { return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_sigreturn(Thread *thread, ptr sigcntxp) { ORBIS_LOG_WARNING(__FUNCTION__, sigcntxp); // auto sigRet = thread->sigReturns.front(); // thread->sigReturns.erase(thread->sigReturns.begin(), thread->sigReturns.begin() + 1); // writeRegister(thread->context, RegisterId::rip, sigRet.rip); // writeRegister(thread->context, RegisterId::rsp, sigRet.rsp); // ORBIS_LOG_ERROR(__FUNCTION__, sigRet.rip, sigRet.rsp); return {}; } orbis::SysResult orbis::nosys(Thread *thread) { thread->sendSignal(kSigSys); return{}; }