Skip to content

Commit 64bc004

Browse files
hexagonal-sunarihant2math
authored andcommitted
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.
1 parent a003ab8 commit 64bc004

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

libkernel/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ pub enum KernelError {
177177
#[error("No such process")]
178178
NoProcess,
179179

180+
#[error("No child process")]
181+
NoChildProcess,
182+
180183
#[error("Operation timed out")]
181184
TimedOut,
182185

libkernel/src/error/syscall_error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub fn kern_err_to_syscall(err: KernelError) -> isize {
5353
KernelError::NotSupported => ENOSYS,
5454
KernelError::NoMemory => ENOMEM,
5555
KernelError::TimedOut => ETIMEDOUT,
56+
KernelError::NoChildProcess => ECHILD,
5657
e => todo!("{e}"),
5758
}
5859
}

src/process/thread_group/wait.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,22 @@ pub async fn sys_wait4(
170170

171171
let task = current_task_shared();
172172

173-
let (tgid, child_state) = if flags.contains(WaitFlags::WNOHANG) {
173+
let child_proc_count = task.process.children.lock_save_irq().iter().count();
174+
175+
let (tgid, child_state) = if child_proc_count == 0 || flags.contains(WaitFlags::WNOHANG) {
176+
// Special case for no children. See if there are any pending child
177+
// notification events without sleeping. If there are no children and no
178+
// pending events, return ECHILD.
174179
let mut ret = None;
175180
task.process.child_notifiers.inner.update(|s| {
176181
ret = do_wait(s, pid, flags);
177182
WakeupType::None
178183
});
179184

180185
match ret {
181-
None => return Ok(0),
182186
Some(ret) => ret,
187+
None if child_proc_count == 0 => return Err(KernelError::NoChildProcess),
188+
None => return Ok(0),
183189
}
184190
} else {
185191
task.process

0 commit comments

Comments
 (0)