11496ba7bSLoGin use core::ffi::c_void; 2ab5c8ca4Slogin 3*971462beSGnoCiYeH use alloc::{ 4*971462beSGnoCiYeH string::{String, ToString}, 5*971462beSGnoCiYeH sync::Arc, 6*971462beSGnoCiYeH vec::Vec, 7*971462beSGnoCiYeH }; 81496ba7bSLoGin 9*971462beSGnoCiYeH use super::{ 10*971462beSGnoCiYeH abi::WaitOption, 11*971462beSGnoCiYeH fork::{CloneFlags, KernelCloneArgs}, 12*971462beSGnoCiYeH KernelStack, Pid, ProcessManager, ProcessState, 13*971462beSGnoCiYeH }; 14ab5c8ca4Slogin use crate::{ 151496ba7bSLoGin arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch}, 161496ba7bSLoGin exception::InterruptArch, 17*971462beSGnoCiYeH filesystem::{procfs::procfs_register_pid, vfs::MAX_PATHLEN}, 18*971462beSGnoCiYeH include::bindings::bindings::verify_area, 19*971462beSGnoCiYeH mm::VirtAddr, 201496ba7bSLoGin process::ProcessControlBlock, 21*971462beSGnoCiYeH sched::completion::Completion, 221496ba7bSLoGin syscall::{ 231496ba7bSLoGin user_access::{ 241496ba7bSLoGin check_and_clone_cstr, check_and_clone_cstr_array, UserBufferReader, UserBufferWriter, 251496ba7bSLoGin }, 261496ba7bSLoGin Syscall, SystemError, 271496ba7bSLoGin }, 28ab5c8ca4Slogin }; 29ab5c8ca4Slogin 30ab5c8ca4Slogin impl Syscall { 311496ba7bSLoGin pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 321496ba7bSLoGin let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()); 331496ba7bSLoGin return r; 34ab5c8ca4Slogin } 35ab5c8ca4Slogin 361496ba7bSLoGin pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 371496ba7bSLoGin ProcessManager::fork( 381496ba7bSLoGin frame, 391496ba7bSLoGin CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 401496ba7bSLoGin ) 411496ba7bSLoGin .map(|pid| pid.into()) 42ab5c8ca4Slogin } 43ab5c8ca4Slogin 44ab5c8ca4Slogin pub fn execve( 451496ba7bSLoGin path: *const u8, 461496ba7bSLoGin argv: *const *const u8, 471496ba7bSLoGin envp: *const *const u8, 481496ba7bSLoGin frame: &mut TrapFrame, 491496ba7bSLoGin ) -> Result<(), SystemError> { 501496ba7bSLoGin // kdebug!( 511496ba7bSLoGin // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 521496ba7bSLoGin // path, 531496ba7bSLoGin // argv, 541496ba7bSLoGin // envp 551496ba7bSLoGin // ); 56*971462beSGnoCiYeH // kdebug!( 57*971462beSGnoCiYeH // "before execve: strong count: {}", 58*971462beSGnoCiYeH // Arc::strong_count(&ProcessManager::current_pcb()) 59*971462beSGnoCiYeH // ); 60*971462beSGnoCiYeH 611496ba7bSLoGin if path.is_null() { 621496ba7bSLoGin return Err(SystemError::EINVAL); 631496ba7bSLoGin } 641496ba7bSLoGin 651496ba7bSLoGin let x = || { 661496ba7bSLoGin let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 671496ba7bSLoGin let argv: Vec<String> = check_and_clone_cstr_array(argv)?; 681496ba7bSLoGin let envp: Vec<String> = check_and_clone_cstr_array(envp)?; 691496ba7bSLoGin Ok((path, argv, envp)) 701496ba7bSLoGin }; 711496ba7bSLoGin let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x(); 721496ba7bSLoGin if let Err(e) = r { 731496ba7bSLoGin panic!("Failed to execve: {:?}", e); 741496ba7bSLoGin } 751496ba7bSLoGin let (path, argv, envp) = r.unwrap(); 761496ba7bSLoGin ProcessManager::current_pcb() 771496ba7bSLoGin .basic_mut() 781496ba7bSLoGin .set_name(ProcessControlBlock::generate_name(&path, &argv)); 791496ba7bSLoGin 80876cb89eSGnoCiYeH Self::do_execve(path, argv, envp, frame)?; 81876cb89eSGnoCiYeH 82876cb89eSGnoCiYeH // 关闭设置了O_CLOEXEC的文件描述符 83876cb89eSGnoCiYeH let fd_table = ProcessManager::current_pcb().fd_table(); 84876cb89eSGnoCiYeH fd_table.write().close_on_exec(); 85*971462beSGnoCiYeH // kdebug!( 86*971462beSGnoCiYeH // "after execve: strong count: {}", 87*971462beSGnoCiYeH // Arc::strong_count(&ProcessManager::current_pcb()) 88*971462beSGnoCiYeH // ); 89876cb89eSGnoCiYeH 90876cb89eSGnoCiYeH return Ok(()); 91ab5c8ca4Slogin } 92ab5c8ca4Slogin 93ab5c8ca4Slogin pub fn wait4( 941496ba7bSLoGin pid: i64, 951496ba7bSLoGin wstatus: *mut i32, 961496ba7bSLoGin options: i32, 97ab5c8ca4Slogin rusage: *mut c_void, 98ab5c8ca4Slogin ) -> Result<usize, SystemError> { 99b7b843beSGnoCiYeH let ret = WaitOption::from_bits(options as u32); 100b7b843beSGnoCiYeH let options = match ret { 101b7b843beSGnoCiYeH Some(options) => options, 102b7b843beSGnoCiYeH None => { 103b7b843beSGnoCiYeH return Err(SystemError::EINVAL); 104b7b843beSGnoCiYeH } 105b7b843beSGnoCiYeH }; 106b7b843beSGnoCiYeH 1071496ba7bSLoGin let mut _rusage_buf = 1081496ba7bSLoGin UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?; 1091496ba7bSLoGin 1101496ba7bSLoGin let mut wstatus_buf = 1111496ba7bSLoGin UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?; 1121496ba7bSLoGin 1131496ba7bSLoGin let cur_pcb = ProcessManager::current_pcb(); 1141496ba7bSLoGin let rd_childen = cur_pcb.children.read(); 1151496ba7bSLoGin 1161496ba7bSLoGin if pid > 0 { 1171496ba7bSLoGin let pid = Pid(pid as usize); 118*971462beSGnoCiYeH let child_pcb = ProcessManager::find(pid).ok_or(SystemError::ECHILD)?; 1191496ba7bSLoGin drop(rd_childen); 1201496ba7bSLoGin 121b7b843beSGnoCiYeH loop { 122*971462beSGnoCiYeH let state = child_pcb.sched_info().state(); 1231496ba7bSLoGin // 获取退出码 124*971462beSGnoCiYeH match state { 125b7b843beSGnoCiYeH ProcessState::Runnable => { 126b7b843beSGnoCiYeH if options.contains(WaitOption::WNOHANG) 127b7b843beSGnoCiYeH || options.contains(WaitOption::WNOWAIT) 128b7b843beSGnoCiYeH { 1291496ba7bSLoGin if !wstatus.is_null() { 130b7b843beSGnoCiYeH wstatus_buf.copy_one_to_user(&WaitOption::WCONTINUED.bits(), 0)?; 131b7b843beSGnoCiYeH } 132b7b843beSGnoCiYeH return Ok(0); 133b7b843beSGnoCiYeH } 134b7b843beSGnoCiYeH } 1353c82aa56SChiichen ProcessState::Blocked(_) | ProcessState::Stopped => { 136b7b843beSGnoCiYeH // 指定WUNTRACED则等待暂停的进程,不指定则返回0 137b7b843beSGnoCiYeH if !options.contains(WaitOption::WUNTRACED) 138b7b843beSGnoCiYeH || options.contains(WaitOption::WNOWAIT) 139b7b843beSGnoCiYeH { 140b7b843beSGnoCiYeH if !wstatus.is_null() { 141b7b843beSGnoCiYeH wstatus_buf.copy_one_to_user(&WaitOption::WSTOPPED.bits(), 0)?; 142b7b843beSGnoCiYeH } 143b7b843beSGnoCiYeH return Ok(0); 144b7b843beSGnoCiYeH } 145b7b843beSGnoCiYeH } 146b7b843beSGnoCiYeH ProcessState::Exited(status) => { 147*971462beSGnoCiYeH // kdebug!("wait4: child exited, pid: {:?}, status: {status}\n", pid); 148b7b843beSGnoCiYeH if !wstatus.is_null() { 149b7b843beSGnoCiYeH wstatus_buf.copy_one_to_user( 150*971462beSGnoCiYeH &(status as u32 | WaitOption::WEXITED.bits()), 151b7b843beSGnoCiYeH 0, 152b7b843beSGnoCiYeH )?; 1531496ba7bSLoGin } 154*971462beSGnoCiYeH drop(child_pcb); 155*971462beSGnoCiYeH // kdebug!("wait4: to release {pid:?}"); 156*971462beSGnoCiYeH unsafe { ProcessManager::release(pid) }; 1571496ba7bSLoGin return Ok(pid.into()); 1581496ba7bSLoGin } 159b7b843beSGnoCiYeH }; 160b7b843beSGnoCiYeH 1611496ba7bSLoGin // 等待指定进程 1621496ba7bSLoGin child_pcb.wait_queue.sleep(); 163b7b843beSGnoCiYeH } 1641496ba7bSLoGin } else if pid < -1 { 1651496ba7bSLoGin // TODO 判断是否pgid == -pid(等待指定组任意进程) 1661496ba7bSLoGin // 暂时不支持 1671496ba7bSLoGin return Err(SystemError::EINVAL); 1681496ba7bSLoGin } else if pid == 0 { 1691496ba7bSLoGin // TODO 判断是否pgid == current_pgid(等待当前组任意进程) 1701496ba7bSLoGin // 暂时不支持 1711496ba7bSLoGin return Err(SystemError::EINVAL); 1721496ba7bSLoGin } else { 1731496ba7bSLoGin // 等待任意子进程(这两) 1741496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 175*971462beSGnoCiYeH for pid in rd_childen.iter() { 176*971462beSGnoCiYeH let pcb = ProcessManager::find(*pid).ok_or(SystemError::ECHILD)?; 1771496ba7bSLoGin if pcb.sched_info().state().is_exited() { 1781496ba7bSLoGin if !wstatus.is_null() { 1791496ba7bSLoGin wstatus_buf.copy_one_to_user(&0, 0)?; 1801496ba7bSLoGin } 1811496ba7bSLoGin return Ok(pid.clone().into()); 1821496ba7bSLoGin } else { 1831496ba7bSLoGin unsafe { pcb.wait_queue.sleep_without_schedule() }; 1841496ba7bSLoGin } 1851496ba7bSLoGin } 1861496ba7bSLoGin drop(irq_guard); 1871496ba7bSLoGin sched(); 1881496ba7bSLoGin } 1891496ba7bSLoGin 1901496ba7bSLoGin return Ok(0); 191ab5c8ca4Slogin } 192ab5c8ca4Slogin 193ab5c8ca4Slogin /// # 退出进程 194ab5c8ca4Slogin /// 195ab5c8ca4Slogin /// ## 参数 196ab5c8ca4Slogin /// 197ab5c8ca4Slogin /// - status: 退出状态 198ab5c8ca4Slogin pub fn exit(status: usize) -> ! { 1991496ba7bSLoGin ProcessManager::exit(status); 200ab5c8ca4Slogin } 201ab5c8ca4Slogin 2021496ba7bSLoGin /// @brief 获取当前进程的pid 2031496ba7bSLoGin pub fn getpid() -> Result<Pid, SystemError> { 2041496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 2051496ba7bSLoGin return Ok(current_pcb.pid()); 2061496ba7bSLoGin } 2071496ba7bSLoGin 2081496ba7bSLoGin /// @brief 获取指定进程的pgid 2091496ba7bSLoGin /// 2101496ba7bSLoGin /// @param pid 指定一个进程号 2111496ba7bSLoGin /// 2121496ba7bSLoGin /// @return 成功,指定进程的进程组id 2131496ba7bSLoGin /// @return 错误,不存在该进程 2141496ba7bSLoGin pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 2151496ba7bSLoGin if pid == Pid(0) { 2161496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 2171496ba7bSLoGin pid = current_pcb.pid(); 2181496ba7bSLoGin } 2191496ba7bSLoGin let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 2201496ba7bSLoGin return Ok(target_proc.basic().pgid()); 2211496ba7bSLoGin } 2221496ba7bSLoGin /// @brief 获取当前进程的父进程id 2231496ba7bSLoGin 2241496ba7bSLoGin /// 若为initproc则ppid设置为0 2251496ba7bSLoGin pub fn getppid() -> Result<Pid, SystemError> { 2261496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 2271496ba7bSLoGin return Ok(current_pcb.basic().ppid()); 228ab5c8ca4Slogin } 229*971462beSGnoCiYeH 230*971462beSGnoCiYeH pub fn clone( 231*971462beSGnoCiYeH current_trapframe: &mut TrapFrame, 232*971462beSGnoCiYeH clone_args: KernelCloneArgs, 233*971462beSGnoCiYeH ) -> Result<usize, SystemError> { 234*971462beSGnoCiYeH let flags = clone_args.flags; 235*971462beSGnoCiYeH 236*971462beSGnoCiYeH let vfork = Arc::new(Completion::new()); 237*971462beSGnoCiYeH 238*971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_PIDFD) 239*971462beSGnoCiYeH && flags.contains(CloneFlags::CLONE_PARENT_SETTID) 240*971462beSGnoCiYeH { 241*971462beSGnoCiYeH return Err(SystemError::EINVAL); 242*971462beSGnoCiYeH } 243*971462beSGnoCiYeH 244*971462beSGnoCiYeH let current_pcb = ProcessManager::current_pcb(); 245*971462beSGnoCiYeH let new_kstack = KernelStack::new()?; 246*971462beSGnoCiYeH let name = current_pcb.basic().name().to_string(); 247*971462beSGnoCiYeH let pcb = ProcessControlBlock::new(name, new_kstack); 248*971462beSGnoCiYeH // 克隆pcb 249*971462beSGnoCiYeH ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?; 250*971462beSGnoCiYeH ProcessManager::add_pcb(pcb.clone()); 251*971462beSGnoCiYeH 252*971462beSGnoCiYeH // 向procfs注册进程 253*971462beSGnoCiYeH procfs_register_pid(pcb.pid()).unwrap_or_else(|e| { 254*971462beSGnoCiYeH panic!( 255*971462beSGnoCiYeH "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}", 256*971462beSGnoCiYeH pcb.pid(), 257*971462beSGnoCiYeH e 258*971462beSGnoCiYeH ) 259*971462beSGnoCiYeH }); 260*971462beSGnoCiYeH 261*971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_VFORK) { 262*971462beSGnoCiYeH pcb.thread.write().vfork_done = Some(vfork.clone()); 263*971462beSGnoCiYeH } 264*971462beSGnoCiYeH 265*971462beSGnoCiYeH if pcb.thread.read().set_child_tid.is_some() { 266*971462beSGnoCiYeH let addr = pcb.thread.read().set_child_tid.unwrap(); 267*971462beSGnoCiYeH let mut writer = 268*971462beSGnoCiYeH UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 269*971462beSGnoCiYeH writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; 270*971462beSGnoCiYeH } 271*971462beSGnoCiYeH 272*971462beSGnoCiYeH ProcessManager::wakeup(&pcb).unwrap_or_else(|e| { 273*971462beSGnoCiYeH panic!( 274*971462beSGnoCiYeH "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}", 275*971462beSGnoCiYeH pcb.pid(), 276*971462beSGnoCiYeH e 277*971462beSGnoCiYeH ) 278*971462beSGnoCiYeH }); 279*971462beSGnoCiYeH 280*971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_VFORK) { 281*971462beSGnoCiYeH // 等待子进程结束或者exec; 282*971462beSGnoCiYeH vfork.wait_for_completion_interruptible()?; 283*971462beSGnoCiYeH } 284*971462beSGnoCiYeH 285*971462beSGnoCiYeH return Ok(pcb.pid().0); 286*971462beSGnoCiYeH } 287*971462beSGnoCiYeH 288*971462beSGnoCiYeH /// 设置线程地址 289*971462beSGnoCiYeH pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> { 290*971462beSGnoCiYeH if !unsafe { verify_area(ptr as u64, core::mem::size_of::<i32>() as u64) } { 291*971462beSGnoCiYeH return Err(SystemError::EFAULT); 292*971462beSGnoCiYeH } 293*971462beSGnoCiYeH 294*971462beSGnoCiYeH let pcb = ProcessManager::current_pcb(); 295*971462beSGnoCiYeH pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr)); 296*971462beSGnoCiYeH Ok(pcb.pid.0) 297*971462beSGnoCiYeH } 298ab5c8ca4Slogin } 299