11496ba7bSLoGin use core::ffi::c_void; 2ab5c8ca4Slogin 31496ba7bSLoGin use alloc::{string::String, vec::Vec}; 41496ba7bSLoGin 51496ba7bSLoGin use super::{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 64*876cb89eSGnoCiYeH Self::do_execve(path, argv, envp, frame)?; 65*876cb89eSGnoCiYeH 66*876cb89eSGnoCiYeH // 关闭设置了O_CLOEXEC的文件描述符 67*876cb89eSGnoCiYeH let fd_table = ProcessManager::current_pcb().fd_table(); 68*876cb89eSGnoCiYeH fd_table.write().close_on_exec(); 69*876cb89eSGnoCiYeH 70*876cb89eSGnoCiYeH 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> { 791496ba7bSLoGin let mut _rusage_buf = 801496ba7bSLoGin UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?; 811496ba7bSLoGin 821496ba7bSLoGin let mut wstatus_buf = 831496ba7bSLoGin UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?; 841496ba7bSLoGin 851496ba7bSLoGin // 暂时不支持options选项 861496ba7bSLoGin if options != 0 { 871496ba7bSLoGin return Err(SystemError::EINVAL); 88ab5c8ca4Slogin } 891496ba7bSLoGin 901496ba7bSLoGin let cur_pcb = ProcessManager::current_pcb(); 911496ba7bSLoGin let rd_childen = cur_pcb.children.read(); 921496ba7bSLoGin 931496ba7bSLoGin if pid > 0 { 941496ba7bSLoGin let pid = Pid(pid as usize); 951496ba7bSLoGin let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone(); 961496ba7bSLoGin drop(rd_childen); 971496ba7bSLoGin 981496ba7bSLoGin // 获取退出码 991496ba7bSLoGin if let ProcessState::Exited(status) = child_pcb.sched_info().state() { 1001496ba7bSLoGin if !wstatus.is_null() { 1011496ba7bSLoGin wstatus_buf.copy_one_to_user(&status, 0)?; 1021496ba7bSLoGin } 1031496ba7bSLoGin return Ok(pid.into()); 1041496ba7bSLoGin } 1051496ba7bSLoGin // 等待指定进程 1061496ba7bSLoGin child_pcb.wait_queue.sleep(); 1071496ba7bSLoGin } else if pid < -1 { 1081496ba7bSLoGin // TODO 判断是否pgid == -pid(等待指定组任意进程) 1091496ba7bSLoGin // 暂时不支持 1101496ba7bSLoGin return Err(SystemError::EINVAL); 1111496ba7bSLoGin } else if pid == 0 { 1121496ba7bSLoGin // TODO 判断是否pgid == current_pgid(等待当前组任意进程) 1131496ba7bSLoGin // 暂时不支持 1141496ba7bSLoGin return Err(SystemError::EINVAL); 1151496ba7bSLoGin } else { 1161496ba7bSLoGin // 等待任意子进程(这两) 1171496ba7bSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 1181496ba7bSLoGin for (pid, pcb) in rd_childen.iter() { 1191496ba7bSLoGin if pcb.sched_info().state().is_exited() { 1201496ba7bSLoGin if !wstatus.is_null() { 1211496ba7bSLoGin wstatus_buf.copy_one_to_user(&0, 0)?; 1221496ba7bSLoGin } 1231496ba7bSLoGin return Ok(pid.clone().into()); 1241496ba7bSLoGin } else { 1251496ba7bSLoGin unsafe { pcb.wait_queue.sleep_without_schedule() }; 1261496ba7bSLoGin } 1271496ba7bSLoGin } 1281496ba7bSLoGin drop(irq_guard); 1291496ba7bSLoGin sched(); 1301496ba7bSLoGin } 1311496ba7bSLoGin 1321496ba7bSLoGin return Ok(0); 133ab5c8ca4Slogin } 134ab5c8ca4Slogin 135ab5c8ca4Slogin /// # 退出进程 136ab5c8ca4Slogin /// 137ab5c8ca4Slogin /// ## 参数 138ab5c8ca4Slogin /// 139ab5c8ca4Slogin /// - status: 退出状态 140ab5c8ca4Slogin pub fn exit(status: usize) -> ! { 1411496ba7bSLoGin ProcessManager::exit(status); 142ab5c8ca4Slogin } 143ab5c8ca4Slogin 1441496ba7bSLoGin /// @brief 获取当前进程的pid 1451496ba7bSLoGin pub fn getpid() -> Result<Pid, SystemError> { 1461496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1471496ba7bSLoGin return Ok(current_pcb.pid()); 1481496ba7bSLoGin } 1491496ba7bSLoGin 1501496ba7bSLoGin /// @brief 获取指定进程的pgid 1511496ba7bSLoGin /// 1521496ba7bSLoGin /// @param pid 指定一个进程号 1531496ba7bSLoGin /// 1541496ba7bSLoGin /// @return 成功,指定进程的进程组id 1551496ba7bSLoGin /// @return 错误,不存在该进程 1561496ba7bSLoGin pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 1571496ba7bSLoGin if pid == Pid(0) { 1581496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1591496ba7bSLoGin pid = current_pcb.pid(); 1601496ba7bSLoGin } 1611496ba7bSLoGin let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 1621496ba7bSLoGin return Ok(target_proc.basic().pgid()); 1631496ba7bSLoGin } 1641496ba7bSLoGin /// @brief 获取当前进程的父进程id 1651496ba7bSLoGin 1661496ba7bSLoGin /// 若为initproc则ppid设置为0 1671496ba7bSLoGin pub fn getppid() -> Result<Pid, SystemError> { 1681496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1691496ba7bSLoGin return Ok(current_pcb.basic().ppid()); 170ab5c8ca4Slogin } 171ab5c8ca4Slogin } 172