11496ba7bSLoGin use core::ffi::c_void; 2ab5c8ca4Slogin 31496ba7bSLoGin use alloc::{string::String, vec::Vec}; 41496ba7bSLoGin 5*b7b843beSGnoCiYeH use super::{abi::WaitOption, fork::CloneFlags, Pid, ProcessManager, ProcessState}; 6ab5c8ca4Slogin use crate::{ 71496ba7bSLoGin arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch}, 81496ba7bSLoGin exception::InterruptArch, 91496ba7bSLoGin filesystem::vfs::MAX_PATHLEN, 101496ba7bSLoGin process::ProcessControlBlock, 111496ba7bSLoGin syscall::{ 121496ba7bSLoGin user_access::{ 131496ba7bSLoGin check_and_clone_cstr, check_and_clone_cstr_array, UserBufferReader, UserBufferWriter, 141496ba7bSLoGin }, 151496ba7bSLoGin Syscall, SystemError, 161496ba7bSLoGin }, 17ab5c8ca4Slogin }; 18ab5c8ca4Slogin 19ab5c8ca4Slogin impl Syscall { 201496ba7bSLoGin pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 211496ba7bSLoGin let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()); 221496ba7bSLoGin return r; 23ab5c8ca4Slogin } 24ab5c8ca4Slogin 251496ba7bSLoGin pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 261496ba7bSLoGin ProcessManager::fork( 271496ba7bSLoGin frame, 281496ba7bSLoGin CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 291496ba7bSLoGin ) 301496ba7bSLoGin .map(|pid| pid.into()) 31ab5c8ca4Slogin } 32ab5c8ca4Slogin 33ab5c8ca4Slogin pub fn execve( 341496ba7bSLoGin path: *const u8, 351496ba7bSLoGin argv: *const *const u8, 361496ba7bSLoGin envp: *const *const u8, 371496ba7bSLoGin frame: &mut TrapFrame, 381496ba7bSLoGin ) -> Result<(), SystemError> { 391496ba7bSLoGin // kdebug!( 401496ba7bSLoGin // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 411496ba7bSLoGin // path, 421496ba7bSLoGin // argv, 431496ba7bSLoGin // envp 441496ba7bSLoGin // ); 451496ba7bSLoGin if path.is_null() { 461496ba7bSLoGin return Err(SystemError::EINVAL); 471496ba7bSLoGin } 481496ba7bSLoGin 491496ba7bSLoGin let x = || { 501496ba7bSLoGin let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 511496ba7bSLoGin let argv: Vec<String> = check_and_clone_cstr_array(argv)?; 521496ba7bSLoGin let envp: Vec<String> = check_and_clone_cstr_array(envp)?; 531496ba7bSLoGin Ok((path, argv, envp)) 541496ba7bSLoGin }; 551496ba7bSLoGin let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x(); 561496ba7bSLoGin if let Err(e) = r { 571496ba7bSLoGin panic!("Failed to execve: {:?}", e); 581496ba7bSLoGin } 591496ba7bSLoGin let (path, argv, envp) = r.unwrap(); 601496ba7bSLoGin ProcessManager::current_pcb() 611496ba7bSLoGin .basic_mut() 621496ba7bSLoGin .set_name(ProcessControlBlock::generate_name(&path, &argv)); 631496ba7bSLoGin 64876cb89eSGnoCiYeH Self::do_execve(path, argv, envp, frame)?; 65876cb89eSGnoCiYeH 66876cb89eSGnoCiYeH // 关闭设置了O_CLOEXEC的文件描述符 67876cb89eSGnoCiYeH let fd_table = ProcessManager::current_pcb().fd_table(); 68876cb89eSGnoCiYeH fd_table.write().close_on_exec(); 69876cb89eSGnoCiYeH 70876cb89eSGnoCiYeH return Ok(()); 71ab5c8ca4Slogin } 72ab5c8ca4Slogin 73ab5c8ca4Slogin pub fn wait4( 741496ba7bSLoGin pid: i64, 751496ba7bSLoGin wstatus: *mut i32, 761496ba7bSLoGin options: i32, 77ab5c8ca4Slogin rusage: *mut c_void, 78ab5c8ca4Slogin ) -> Result<usize, SystemError> { 79*b7b843beSGnoCiYeH let ret = WaitOption::from_bits(options as u32); 80*b7b843beSGnoCiYeH let options = match ret { 81*b7b843beSGnoCiYeH Some(options) => options, 82*b7b843beSGnoCiYeH None => { 83*b7b843beSGnoCiYeH return Err(SystemError::EINVAL); 84*b7b843beSGnoCiYeH } 85*b7b843beSGnoCiYeH }; 86*b7b843beSGnoCiYeH 871496ba7bSLoGin let mut _rusage_buf = 881496ba7bSLoGin UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?; 891496ba7bSLoGin 901496ba7bSLoGin let mut wstatus_buf = 911496ba7bSLoGin UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?; 921496ba7bSLoGin 931496ba7bSLoGin let cur_pcb = ProcessManager::current_pcb(); 941496ba7bSLoGin let rd_childen = cur_pcb.children.read(); 951496ba7bSLoGin 961496ba7bSLoGin if pid > 0 { 971496ba7bSLoGin let pid = Pid(pid as usize); 981496ba7bSLoGin let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone(); 991496ba7bSLoGin drop(rd_childen); 1001496ba7bSLoGin 101*b7b843beSGnoCiYeH loop { 1021496ba7bSLoGin // 获取退出码 103*b7b843beSGnoCiYeH match child_pcb.sched_info().state() { 104*b7b843beSGnoCiYeH ProcessState::Runnable => { 105*b7b843beSGnoCiYeH if options.contains(WaitOption::WNOHANG) 106*b7b843beSGnoCiYeH || options.contains(WaitOption::WNOWAIT) 107*b7b843beSGnoCiYeH { 1081496ba7bSLoGin if !wstatus.is_null() { 109*b7b843beSGnoCiYeH wstatus_buf.copy_one_to_user(&WaitOption::WCONTINUED.bits(), 0)?; 110*b7b843beSGnoCiYeH } 111*b7b843beSGnoCiYeH return Ok(0); 112*b7b843beSGnoCiYeH } 113*b7b843beSGnoCiYeH } 114*b7b843beSGnoCiYeH ProcessState::Blocked(_) => { 115*b7b843beSGnoCiYeH // 指定WUNTRACED则等待暂停的进程,不指定则返回0 116*b7b843beSGnoCiYeH if !options.contains(WaitOption::WUNTRACED) 117*b7b843beSGnoCiYeH || options.contains(WaitOption::WNOWAIT) 118*b7b843beSGnoCiYeH { 119*b7b843beSGnoCiYeH if !wstatus.is_null() { 120*b7b843beSGnoCiYeH wstatus_buf.copy_one_to_user(&WaitOption::WSTOPPED.bits(), 0)?; 121*b7b843beSGnoCiYeH } 122*b7b843beSGnoCiYeH return Ok(0); 123*b7b843beSGnoCiYeH } 124*b7b843beSGnoCiYeH } 125*b7b843beSGnoCiYeH ProcessState::Exited(status) => { 126*b7b843beSGnoCiYeH if !wstatus.is_null() { 127*b7b843beSGnoCiYeH wstatus_buf.copy_one_to_user( 128*b7b843beSGnoCiYeH &(status | WaitOption::WEXITED.bits() as usize), 129*b7b843beSGnoCiYeH 0, 130*b7b843beSGnoCiYeH )?; 1311496ba7bSLoGin } 1321496ba7bSLoGin return Ok(pid.into()); 1331496ba7bSLoGin } 134*b7b843beSGnoCiYeH }; 135*b7b843beSGnoCiYeH 1361496ba7bSLoGin // 等待指定进程 1371496ba7bSLoGin child_pcb.wait_queue.sleep(); 138*b7b843beSGnoCiYeH } 1391496ba7bSLoGin } else if pid < -1 { 1401496ba7bSLoGin // TODO 判断是否pgid == -pid(等待指定组任意进程) 1411496ba7bSLoGin // 暂时不支持 1421496ba7bSLoGin return Err(SystemError::EINVAL); 1431496ba7bSLoGin } else if pid == 0 { 1441496ba7bSLoGin // TODO 判断是否pgid == current_pgid(等待当前组任意进程) 1451496ba7bSLoGin // 暂时不支持 1461496ba7bSLoGin return Err(SystemError::EINVAL); 1471496ba7bSLoGin } else { 1481496ba7bSLoGin // 等待任意子进程(这两) 1491496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1501496ba7bSLoGin for (pid, pcb) in rd_childen.iter() { 1511496ba7bSLoGin if pcb.sched_info().state().is_exited() { 1521496ba7bSLoGin if !wstatus.is_null() { 1531496ba7bSLoGin wstatus_buf.copy_one_to_user(&0, 0)?; 1541496ba7bSLoGin } 1551496ba7bSLoGin return Ok(pid.clone().into()); 1561496ba7bSLoGin } else { 1571496ba7bSLoGin unsafe { pcb.wait_queue.sleep_without_schedule() }; 1581496ba7bSLoGin } 1591496ba7bSLoGin } 1601496ba7bSLoGin drop(irq_guard); 1611496ba7bSLoGin sched(); 1621496ba7bSLoGin } 1631496ba7bSLoGin 1641496ba7bSLoGin return Ok(0); 165ab5c8ca4Slogin } 166ab5c8ca4Slogin 167ab5c8ca4Slogin /// # 退出进程 168ab5c8ca4Slogin /// 169ab5c8ca4Slogin /// ## 参数 170ab5c8ca4Slogin /// 171ab5c8ca4Slogin /// - status: 退出状态 172ab5c8ca4Slogin pub fn exit(status: usize) -> ! { 1731496ba7bSLoGin ProcessManager::exit(status); 174ab5c8ca4Slogin } 175ab5c8ca4Slogin 1761496ba7bSLoGin /// @brief 获取当前进程的pid 1771496ba7bSLoGin pub fn getpid() -> Result<Pid, SystemError> { 1781496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1791496ba7bSLoGin return Ok(current_pcb.pid()); 1801496ba7bSLoGin } 1811496ba7bSLoGin 1821496ba7bSLoGin /// @brief 获取指定进程的pgid 1831496ba7bSLoGin /// 1841496ba7bSLoGin /// @param pid 指定一个进程号 1851496ba7bSLoGin /// 1861496ba7bSLoGin /// @return 成功,指定进程的进程组id 1871496ba7bSLoGin /// @return 错误,不存在该进程 1881496ba7bSLoGin pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 1891496ba7bSLoGin if pid == Pid(0) { 1901496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1911496ba7bSLoGin pid = current_pcb.pid(); 1921496ba7bSLoGin } 1931496ba7bSLoGin let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 1941496ba7bSLoGin return Ok(target_proc.basic().pgid()); 1951496ba7bSLoGin } 1961496ba7bSLoGin /// @brief 获取当前进程的父进程id 1971496ba7bSLoGin 1981496ba7bSLoGin /// 若为initproc则ppid设置为0 1991496ba7bSLoGin pub fn getppid() -> Result<Pid, SystemError> { 2001496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 2011496ba7bSLoGin return Ok(current_pcb.basic().ppid()); 202ab5c8ca4Slogin } 203ab5c8ca4Slogin } 204