#include "memory/MemoryManager.h" #include "sys/Syscall.h" #include "thread/Scheduler.h" #include Result 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(); Thread* thread; if (pid > 0) { thread = TRY(Result::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) { if (!Scheduler::has_children((pid_t)current->id)) return err(ECHILD); Option 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(); } else return err(ENOTSUP); int status = (int)thread->status; u64 id = thread->id; thread->state = ThreadState::Dying; if (status_ptr) if (!MemoryManager::copy_to_user_typed(status_ptr, &status)) return err(EFAULT); return id; }