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