[orbis-kernel] implement sys_wait4 and sys_kill

This commit is contained in:
DH 2023-12-31 18:58:02 +03:00
parent f5c8fce5aa
commit ebe051f6fb
8 changed files with 100 additions and 13 deletions

View file

@ -54,6 +54,7 @@ public:
Process *createProcess(pid_t pid);
void deleteProcess(Process *proc);
Process *findProcessById(pid_t pid) const;
Process *findProcessByHostId(std::uint64_t pid) const;
utils::LinkedNode<Process> *getProcessList() { return m_processes; }

View file

@ -45,6 +45,7 @@ struct NamedMemoryRange {
struct Process final {
KernelContext *context = nullptr;
pid_t pid = -1;
std::uint64_t hostPid = -1;
sysentvec *sysent = nullptr;
ProcessState state = ProcessState::NEW;
Process *parentProcess = nullptr;

View file

@ -2,8 +2,10 @@
#include "orbis/thread/Process.hpp"
#include "orbis/thread/ProcessOps.hpp"
#include "orbis/utils/Logs.hpp"
#include <chrono>
#include <sys/mman.h>
#include <sys/unistd.h>
#include <thread>
namespace orbis {
thread_local Thread *g_currentThread;
@ -69,11 +71,32 @@ void KernelContext::deleteProcess(Process *proc) {
}
Process *KernelContext::findProcessById(pid_t pid) const {
std::lock_guard lock(m_proc_mtx);
for (auto proc = m_processes; proc != nullptr; proc = proc->next) {
if (proc->object.pid == pid) {
return &proc->object;
for (std::size_t i = 0; i < 5; ++i) {
{
std::lock_guard lock(m_proc_mtx);
for (auto proc = m_processes; proc != nullptr; proc = proc->next) {
if (proc->object.pid == pid) {
return &proc->object;
}
}
}
std::this_thread::sleep_for(std::chrono::microseconds(50));
}
return nullptr;
}
Process *KernelContext::findProcessByHostId(std::uint64_t pid) const {
for (std::size_t i = 0; i < 5; ++i) {
{
std::lock_guard lock(m_proc_mtx);
for (auto proc = m_processes; proc != nullptr; proc = proc->next) {
if (proc->object.hostPid == pid) {
return &proc->object;
}
}
}
std::this_thread::sleep_for(std::chrono::microseconds(50));
}
return nullptr;

View file

@ -1,7 +1,11 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <chrono>
#include <sys/wait.h>
#include <thread>
#include <unistd.h>
#include <sys/resource.h>
orbis::SysResult orbis::sys_exit(Thread *thread, sint status) {
if (auto exit = thread->tproc->ops->exit) {
@ -18,6 +22,33 @@ orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
sint options, ptr<struct rusage> rusage) {
// TODO
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage);
std::this_thread::sleep_for(std::chrono::days(1));
int hostPid = pid;
if (pid > 0) {
auto process = g_context.findProcessById(pid);
if (process == nullptr) {
return ErrorCode::SRCH;
}
hostPid = process->hostPid;
}
::rusage hostUsage;
int stat;
int result = ::wait4(hostPid, &stat, options, &hostUsage);
if (result < 0) {
return static_cast<ErrorCode>(errno);
}
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
auto process = g_context.findProcessByHostId(result);
if (process == nullptr) {
std::abort();
}
if (status != nullptr) {
ORBIS_RET_ON_ERROR(uwrite(status, stat));
}
thread->retval[0] = process->pid;
return {};
}

View file

@ -29,6 +29,10 @@ orbis::SysResult orbis::sys_read(Thread *thread, sint fd, ptr<void> buf,
auto error = read(file.get(), &io, thread);
if (error != ErrorCode{} && error != ErrorCode::AGAIN) {
if (error == ErrorCode::BUSY) {
return SysResult::notAnError(error);
}
return error;
}
@ -286,6 +290,7 @@ orbis::SysResult orbis::sys_ftruncate(Thread *thread, sint fd, off_t length) {
return ErrorCode::NOTSUP;
}
ORBIS_LOG_WARNING(__FUNCTION__, fd, length);
std::lock_guard lock(file->mtx);
return truncate(file.get(), length, thread);
}

View file

@ -1,5 +1,7 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <csignal>
orbis::SysResult orbis::sys_sigaction(Thread *thread, sint sig,
ptr<struct sigaction> act,
@ -67,8 +69,26 @@ orbis::SysResult orbis::sys_sigaltstack(Thread *thread, ptr<struct stack_t> ss,
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_kill(Thread *thread, sint pid, sint signum) {
return ErrorCode::NOSYS;
ORBIS_LOG_ERROR(__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<ErrorCode>(errno);
}
return {};
}
orbis::SysResult orbis::sys_pdkill(Thread *thread, sint fd, sint signum) {
return ErrorCode::NOSYS;
}