From 64bc004cdb1eefa58bac9522fb2fff57c0295ef3 Mon Sep 17 00:00:00 2001 From: Matthew Leach Date: Sun, 11 Jan 2026 22:20:45 +0000 Subject: [PATCH] process: sys_wait4: return ECHILD with no children If the calling process has no children and no pending exit events to handle, return ECHILD instead of waiting forever. --- libkernel/src/error.rs | 3 +++ libkernel/src/error/syscall_error.rs | 1 + src/process/thread_group/wait.rs | 10 ++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libkernel/src/error.rs b/libkernel/src/error.rs index c51c82e..7f2776e 100644 --- a/libkernel/src/error.rs +++ b/libkernel/src/error.rs @@ -177,6 +177,9 @@ pub enum KernelError { #[error("No such process")] NoProcess, + #[error("No child process")] + NoChildProcess, + #[error("Operation timed out")] TimedOut, diff --git a/libkernel/src/error/syscall_error.rs b/libkernel/src/error/syscall_error.rs index 78b0152..d17f473 100644 --- a/libkernel/src/error/syscall_error.rs +++ b/libkernel/src/error/syscall_error.rs @@ -53,6 +53,7 @@ pub fn kern_err_to_syscall(err: KernelError) -> isize { KernelError::NotSupported => ENOSYS, KernelError::NoMemory => ENOMEM, KernelError::TimedOut => ETIMEDOUT, + KernelError::NoChildProcess => ECHILD, e => todo!("{e}"), } } diff --git a/src/process/thread_group/wait.rs b/src/process/thread_group/wait.rs index 59f5f62..b0e511a 100644 --- a/src/process/thread_group/wait.rs +++ b/src/process/thread_group/wait.rs @@ -170,7 +170,12 @@ pub async fn sys_wait4( let task = current_task_shared(); - let (tgid, child_state) = if flags.contains(WaitFlags::WNOHANG) { + let child_proc_count = task.process.children.lock_save_irq().iter().count(); + + let (tgid, child_state) = if child_proc_count == 0 || flags.contains(WaitFlags::WNOHANG) { + // Special case for no children. See if there are any pending child + // notification events without sleeping. If there are no children and no + // pending events, return ECHILD. let mut ret = None; task.process.child_notifiers.inner.update(|s| { ret = do_wait(s, pid, flags); @@ -178,8 +183,9 @@ pub async fn sys_wait4( }); match ret { - None => return Ok(0), Some(ret) => ret, + None if child_proc_count == 0 => return Err(KernelError::NoChildProcess), + None => return Ok(0), } } else { task.process