Luna/kernel/src/sys/waitpid.cpp

55 lines
1.3 KiB
C++
Raw Normal View History

2023-03-23 21:42:24 +00:00
#include "memory/MemoryManager.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/waitpid.h>
Result<u64> sys_waitpid(Registers*, SyscallArgs args)
{
pid_t pid = (pid_t)args[0];
int* status_ptr = (int*)args[1];
int options = (int)args[2];
Thread* current = Scheduler::current();
2023-03-23 21:42:24 +00:00
Thread* thread;
if (pid > 0)
{
thread = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH));
if (thread->parent_id != current->id) return err(ECHILD);
while (thread->state != ThreadState::Exited)
{
if (options & WNOHANG) return err(EAGAIN);
kernel_sleep(10);
}
}
else if (pid == -1)
2023-03-23 21:42:24 +00:00
{
if (!Scheduler::has_children((pid_t)current->id)) return err(ECHILD);
Option<Thread*> child;
while (child = Scheduler::find_exited_child((pid_t)current->id), !child.has_value())
{
if (options & WNOHANG) return err(EAGAIN);
kernel_sleep(10);
}
thread = child.value();
2023-03-23 21:42:24 +00:00
}
else
return err(ENOTSUP);
2023-03-23 21:42:24 +00:00
int status = (int)thread->status;
u64 id = thread->id;
2023-03-23 21:42:24 +00:00
thread->state = ThreadState::Dying;
if (status_ptr)
if (!MemoryManager::copy_to_user_typed(status_ptr, &status)) return err(EFAULT);
return id;
2023-03-23 21:42:24 +00:00
}