1 use core::ffi::c_void; 2 3 use alloc::{string::String, vec::Vec}; 4 5 use super::{abi::WaitOption, 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 ret = WaitOption::from_bits(options as u32); 80 let options = match ret { 81 Some(options) => options, 82 None => { 83 return Err(SystemError::EINVAL); 84 } 85 }; 86 87 let mut _rusage_buf = 88 UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?; 89 90 let mut wstatus_buf = 91 UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?; 92 93 let cur_pcb = ProcessManager::current_pcb(); 94 let rd_childen = cur_pcb.children.read(); 95 96 if pid > 0 { 97 let pid = Pid(pid as usize); 98 let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone(); 99 drop(rd_childen); 100 101 loop { 102 // 获取退出码 103 match child_pcb.sched_info().state() { 104 ProcessState::Runnable => { 105 if options.contains(WaitOption::WNOHANG) 106 || options.contains(WaitOption::WNOWAIT) 107 { 108 if !wstatus.is_null() { 109 wstatus_buf.copy_one_to_user(&WaitOption::WCONTINUED.bits(), 0)?; 110 } 111 return Ok(0); 112 } 113 } 114 ProcessState::Blocked(_) => { 115 // 指定WUNTRACED则等待暂停的进程,不指定则返回0 116 if !options.contains(WaitOption::WUNTRACED) 117 || options.contains(WaitOption::WNOWAIT) 118 { 119 if !wstatus.is_null() { 120 wstatus_buf.copy_one_to_user(&WaitOption::WSTOPPED.bits(), 0)?; 121 } 122 return Ok(0); 123 } 124 } 125 ProcessState::Exited(status) => { 126 if !wstatus.is_null() { 127 wstatus_buf.copy_one_to_user( 128 &(status | WaitOption::WEXITED.bits() as usize), 129 0, 130 )?; 131 } 132 return Ok(pid.into()); 133 } 134 }; 135 136 // 等待指定进程 137 child_pcb.wait_queue.sleep(); 138 } 139 } else if pid < -1 { 140 // TODO 判断是否pgid == -pid(等待指定组任意进程) 141 // 暂时不支持 142 return Err(SystemError::EINVAL); 143 } else if pid == 0 { 144 // TODO 判断是否pgid == current_pgid(等待当前组任意进程) 145 // 暂时不支持 146 return Err(SystemError::EINVAL); 147 } else { 148 // 等待任意子进程(这两) 149 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 150 for (pid, pcb) in rd_childen.iter() { 151 if pcb.sched_info().state().is_exited() { 152 if !wstatus.is_null() { 153 wstatus_buf.copy_one_to_user(&0, 0)?; 154 } 155 return Ok(pid.clone().into()); 156 } else { 157 unsafe { pcb.wait_queue.sleep_without_schedule() }; 158 } 159 } 160 drop(irq_guard); 161 sched(); 162 } 163 164 return Ok(0); 165 } 166 167 /// # 退出进程 168 /// 169 /// ## 参数 170 /// 171 /// - status: 退出状态 172 pub fn exit(status: usize) -> ! { 173 ProcessManager::exit(status); 174 } 175 176 /// @brief 获取当前进程的pid 177 pub fn getpid() -> Result<Pid, SystemError> { 178 let current_pcb = ProcessManager::current_pcb(); 179 return Ok(current_pcb.pid()); 180 } 181 182 /// @brief 获取指定进程的pgid 183 /// 184 /// @param pid 指定一个进程号 185 /// 186 /// @return 成功,指定进程的进程组id 187 /// @return 错误,不存在该进程 188 pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 189 if pid == Pid(0) { 190 let current_pcb = ProcessManager::current_pcb(); 191 pid = current_pcb.pid(); 192 } 193 let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 194 return Ok(target_proc.basic().pgid()); 195 } 196 /// @brief 获取当前进程的父进程id 197 198 /// 若为initproc则ppid设置为0 199 pub fn getppid() -> Result<Pid, SystemError> { 200 let current_pcb = ProcessManager::current_pcb(); 201 return Ok(current_pcb.basic().ppid()); 202 } 203 } 204