1*1496ba7bSLoGin use core::ffi::c_void; 2ab5c8ca4Slogin 3*1496ba7bSLoGin use alloc::{string::String, vec::Vec}; 4*1496ba7bSLoGin 5*1496ba7bSLoGin use super::{fork::CloneFlags, Pid, ProcessManager, ProcessState}; 6ab5c8ca4Slogin use crate::{ 7*1496ba7bSLoGin arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch}, 8*1496ba7bSLoGin exception::InterruptArch, 9*1496ba7bSLoGin filesystem::vfs::MAX_PATHLEN, 10*1496ba7bSLoGin process::ProcessControlBlock, 11*1496ba7bSLoGin syscall::{ 12*1496ba7bSLoGin user_access::{ 13*1496ba7bSLoGin check_and_clone_cstr, check_and_clone_cstr_array, UserBufferReader, UserBufferWriter, 14*1496ba7bSLoGin }, 15*1496ba7bSLoGin Syscall, SystemError, 16*1496ba7bSLoGin }, 17ab5c8ca4Slogin }; 18ab5c8ca4Slogin 19ab5c8ca4Slogin impl Syscall { 20*1496ba7bSLoGin pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 21*1496ba7bSLoGin let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()); 22*1496ba7bSLoGin return r; 23ab5c8ca4Slogin } 24ab5c8ca4Slogin 25*1496ba7bSLoGin pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 26*1496ba7bSLoGin ProcessManager::fork( 27*1496ba7bSLoGin frame, 28*1496ba7bSLoGin CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 29*1496ba7bSLoGin ) 30*1496ba7bSLoGin .map(|pid| pid.into()) 31ab5c8ca4Slogin } 32ab5c8ca4Slogin 33ab5c8ca4Slogin pub fn execve( 34*1496ba7bSLoGin path: *const u8, 35*1496ba7bSLoGin argv: *const *const u8, 36*1496ba7bSLoGin envp: *const *const u8, 37*1496ba7bSLoGin frame: &mut TrapFrame, 38*1496ba7bSLoGin ) -> Result<(), SystemError> { 39*1496ba7bSLoGin // kdebug!( 40*1496ba7bSLoGin // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 41*1496ba7bSLoGin // path, 42*1496ba7bSLoGin // argv, 43*1496ba7bSLoGin // envp 44*1496ba7bSLoGin // ); 45*1496ba7bSLoGin if path.is_null() { 46*1496ba7bSLoGin return Err(SystemError::EINVAL); 47*1496ba7bSLoGin } 48*1496ba7bSLoGin 49*1496ba7bSLoGin let x = || { 50*1496ba7bSLoGin let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 51*1496ba7bSLoGin let argv: Vec<String> = check_and_clone_cstr_array(argv)?; 52*1496ba7bSLoGin let envp: Vec<String> = check_and_clone_cstr_array(envp)?; 53*1496ba7bSLoGin Ok((path, argv, envp)) 54*1496ba7bSLoGin }; 55*1496ba7bSLoGin let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x(); 56*1496ba7bSLoGin if let Err(e) = r { 57*1496ba7bSLoGin panic!("Failed to execve: {:?}", e); 58*1496ba7bSLoGin } 59*1496ba7bSLoGin let (path, argv, envp) = r.unwrap(); 60*1496ba7bSLoGin ProcessManager::current_pcb() 61*1496ba7bSLoGin .basic_mut() 62*1496ba7bSLoGin .set_name(ProcessControlBlock::generate_name(&path, &argv)); 63*1496ba7bSLoGin 64*1496ba7bSLoGin return Self::do_execve(path, argv, envp, frame); 65ab5c8ca4Slogin } 66ab5c8ca4Slogin 67ab5c8ca4Slogin pub fn wait4( 68*1496ba7bSLoGin pid: i64, 69*1496ba7bSLoGin wstatus: *mut i32, 70*1496ba7bSLoGin options: i32, 71ab5c8ca4Slogin rusage: *mut c_void, 72ab5c8ca4Slogin ) -> Result<usize, SystemError> { 73*1496ba7bSLoGin let mut _rusage_buf = 74*1496ba7bSLoGin UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?; 75*1496ba7bSLoGin 76*1496ba7bSLoGin let mut wstatus_buf = 77*1496ba7bSLoGin UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?; 78*1496ba7bSLoGin 79*1496ba7bSLoGin // 暂时不支持options选项 80*1496ba7bSLoGin if options != 0 { 81*1496ba7bSLoGin return Err(SystemError::EINVAL); 82ab5c8ca4Slogin } 83*1496ba7bSLoGin 84*1496ba7bSLoGin let cur_pcb = ProcessManager::current_pcb(); 85*1496ba7bSLoGin let rd_childen = cur_pcb.children.read(); 86*1496ba7bSLoGin 87*1496ba7bSLoGin if pid > 0 { 88*1496ba7bSLoGin let pid = Pid(pid as usize); 89*1496ba7bSLoGin let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone(); 90*1496ba7bSLoGin drop(rd_childen); 91*1496ba7bSLoGin 92*1496ba7bSLoGin // 获取退出码 93*1496ba7bSLoGin if let ProcessState::Exited(status) = child_pcb.sched_info().state() { 94*1496ba7bSLoGin if !wstatus.is_null() { 95*1496ba7bSLoGin wstatus_buf.copy_one_to_user(&status, 0)?; 96*1496ba7bSLoGin } 97*1496ba7bSLoGin return Ok(pid.into()); 98*1496ba7bSLoGin } 99*1496ba7bSLoGin // 等待指定进程 100*1496ba7bSLoGin child_pcb.wait_queue.sleep(); 101*1496ba7bSLoGin } else if pid < -1 { 102*1496ba7bSLoGin // TODO 判断是否pgid == -pid(等待指定组任意进程) 103*1496ba7bSLoGin // 暂时不支持 104*1496ba7bSLoGin return Err(SystemError::EINVAL); 105*1496ba7bSLoGin } else if pid == 0 { 106*1496ba7bSLoGin // TODO 判断是否pgid == current_pgid(等待当前组任意进程) 107*1496ba7bSLoGin // 暂时不支持 108*1496ba7bSLoGin return Err(SystemError::EINVAL); 109*1496ba7bSLoGin } else { 110*1496ba7bSLoGin // 等待任意子进程(这两) 111*1496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 112*1496ba7bSLoGin for (pid, pcb) in rd_childen.iter() { 113*1496ba7bSLoGin if pcb.sched_info().state().is_exited() { 114*1496ba7bSLoGin if !wstatus.is_null() { 115*1496ba7bSLoGin wstatus_buf.copy_one_to_user(&0, 0)?; 116*1496ba7bSLoGin } 117*1496ba7bSLoGin return Ok(pid.clone().into()); 118*1496ba7bSLoGin } else { 119*1496ba7bSLoGin unsafe { pcb.wait_queue.sleep_without_schedule() }; 120*1496ba7bSLoGin } 121*1496ba7bSLoGin } 122*1496ba7bSLoGin drop(irq_guard); 123*1496ba7bSLoGin sched(); 124*1496ba7bSLoGin } 125*1496ba7bSLoGin 126*1496ba7bSLoGin return Ok(0); 127ab5c8ca4Slogin } 128ab5c8ca4Slogin 129ab5c8ca4Slogin /// # 退出进程 130ab5c8ca4Slogin /// 131ab5c8ca4Slogin /// ## 参数 132ab5c8ca4Slogin /// 133ab5c8ca4Slogin /// - status: 退出状态 134ab5c8ca4Slogin pub fn exit(status: usize) -> ! { 135*1496ba7bSLoGin ProcessManager::exit(status); 136ab5c8ca4Slogin } 137ab5c8ca4Slogin 138*1496ba7bSLoGin /// @brief 获取当前进程的pid 139*1496ba7bSLoGin pub fn getpid() -> Result<Pid, SystemError> { 140*1496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 141*1496ba7bSLoGin return Ok(current_pcb.pid()); 142*1496ba7bSLoGin } 143*1496ba7bSLoGin 144*1496ba7bSLoGin /// @brief 获取指定进程的pgid 145*1496ba7bSLoGin /// 146*1496ba7bSLoGin /// @param pid 指定一个进程号 147*1496ba7bSLoGin /// 148*1496ba7bSLoGin /// @return 成功,指定进程的进程组id 149*1496ba7bSLoGin /// @return 错误,不存在该进程 150*1496ba7bSLoGin pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 151*1496ba7bSLoGin if pid == Pid(0) { 152*1496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 153*1496ba7bSLoGin pid = current_pcb.pid(); 154*1496ba7bSLoGin } 155*1496ba7bSLoGin let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 156*1496ba7bSLoGin return Ok(target_proc.basic().pgid()); 157*1496ba7bSLoGin } 158*1496ba7bSLoGin /// @brief 获取当前进程的父进程id 159*1496ba7bSLoGin 160*1496ba7bSLoGin /// 若为initproc则ppid设置为0 161*1496ba7bSLoGin pub fn getppid() -> Result<Pid, SystemError> { 162*1496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 163*1496ba7bSLoGin return Ok(current_pcb.basic().ppid()); 164ab5c8ca4Slogin } 165ab5c8ca4Slogin } 166