wait4系统调用支持options字段 (#398)

This commit is contained in:
GnoCiYeH
2023-10-09 00:58:08 +08:00
committed by GitHub
parent 2dbef7859f
commit b7b843bedd
5 changed files with 69 additions and 28 deletions

View File

@ -84,3 +84,17 @@ impl TryFrom<u32> for AtType {
}
}
}
bitflags! {
pub struct WaitOption: u32{
const WNOHANG = 0x00000001;
const WUNTRACED = 0x00000002;
const WSTOPPED = 0x00000002;
const WEXITED = 0x00000004;
const WCONTINUED = 0x00000008;
const WNOWAIT = 0x01000000;
const WNOTHREAD = 0x20000000;
const WALL = 0x40000000;
const WCLONE = 0x80000000;
}
}

View File

@ -2,7 +2,7 @@ use core::ffi::c_void;
use alloc::{string::String, vec::Vec};
use super::{fork::CloneFlags, Pid, ProcessManager, ProcessState};
use super::{abi::WaitOption, fork::CloneFlags, Pid, ProcessManager, ProcessState};
use crate::{
arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch},
exception::InterruptArch,
@ -76,17 +76,20 @@ impl Syscall {
options: i32,
rusage: *mut c_void,
) -> Result<usize, SystemError> {
let ret = WaitOption::from_bits(options as u32);
let options = match ret {
Some(options) => options,
None => {
return Err(SystemError::EINVAL);
}
};
let mut _rusage_buf =
UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?;
let mut wstatus_buf =
UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?;
// 暂时不支持options选项
if options != 0 {
return Err(SystemError::EINVAL);
}
let cur_pcb = ProcessManager::current_pcb();
let rd_childen = cur_pcb.children.read();
@ -95,15 +98,44 @@ impl Syscall {
let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone();
drop(rd_childen);
// 获取退出码
if let ProcessState::Exited(status) = child_pcb.sched_info().state() {
if !wstatus.is_null() {
wstatus_buf.copy_one_to_user(&status, 0)?;
}
return Ok(pid.into());
loop {
// 获取退出码
match child_pcb.sched_info().state() {
ProcessState::Runnable => {
if options.contains(WaitOption::WNOHANG)
|| options.contains(WaitOption::WNOWAIT)
{
if !wstatus.is_null() {
wstatus_buf.copy_one_to_user(&WaitOption::WCONTINUED.bits(), 0)?;
}
return Ok(0);
}
}
ProcessState::Blocked(_) => {
// 指定WUNTRACED则等待暂停的进程不指定则返回0
if !options.contains(WaitOption::WUNTRACED)
|| options.contains(WaitOption::WNOWAIT)
{
if !wstatus.is_null() {
wstatus_buf.copy_one_to_user(&WaitOption::WSTOPPED.bits(), 0)?;
}
return Ok(0);
}
}
ProcessState::Exited(status) => {
if !wstatus.is_null() {
wstatus_buf.copy_one_to_user(
&(status | WaitOption::WEXITED.bits() as usize),
0,
)?;
}
return Ok(pid.into());
}
};
// 等待指定进程
child_pcb.wait_queue.sleep();
}
// 等待指定进程
child_pcb.wait_queue.sleep();
} else if pid < -1 {
// TODO 判断是否pgid == -pid等待指定组任意进程
// 暂时不支持