#include "syscall/process.h" #include "capability/capability.h" #include "debug/debug.h" #include "scheduler/cleanup.h" #include "scheduler/process_manager.h" #include "scheduler/scheduler.h" z_err_t ProcessExit(ZProcessExitReq* req) { auto curr_thread = gScheduler->CurrentThread(); dbgln("Exit code: {}", static_cast(req->code)); curr_thread->process().Exit(req->code); panic("Returned from thread exit"); return glcr::UNIMPLEMENTED; } z_err_t ProcessSpawn(ZProcessSpawnReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto cap = curr_proc.GetCapability(req->proc_cap); RET_ERR(ValidateCapability(cap, kZionPerm_SpawnProcess)); glcr::RefPtr proc = Process::Create(); gProcMan->InsertProcess(proc); *req->new_proc_cap = curr_proc.AddNewCapability(proc); *req->new_vmas_cap = curr_proc.AddNewCapability(proc->vmas()); if (req->bootstrap_cap != 0) { auto cap = curr_proc.GetCapability(req->bootstrap_cap); if (!cap) { return glcr::CAP_NOT_FOUND; } if (!(cap->HasPermissions(kZionPerm_Transmit))) { return glcr::CAP_PERMISSION_DENIED; } *req->new_bootstrap_cap = proc->AddExistingCapability( curr_proc.ReleaseCapability(req->bootstrap_cap)); } return glcr::OK; } z_err_t ProcessWait(ZProcessWaitReq* req) { auto& curr_proc = gScheduler->CurrentProcess(); auto cap = curr_proc.GetCapability(req->proc_cap); RET_ERR(ValidateCapability(cap, kZionPerm_Read)); auto proc = cap->obj(); if (proc->id() == curr_proc.id()) { return glcr::INVALID_ARGUMENT; } proc->GetThread(0)->Wait(); *req->exit_code = proc->exit_code(); return glcr::OK; }