11496ba7bSLoGin use core::ffi::c_void; 2ab5c8ca4Slogin 3971462beSGnoCiYeH use alloc::{ 4971462beSGnoCiYeH string::{String, ToString}, 5971462beSGnoCiYeH sync::Arc, 6971462beSGnoCiYeH vec::Vec, 7971462beSGnoCiYeH }; 81496ba7bSLoGin 9971462beSGnoCiYeH use super::{ 10971462beSGnoCiYeH abi::WaitOption, 11*bf4a4899SLoGin exit::kernel_wait4, 12971462beSGnoCiYeH fork::{CloneFlags, KernelCloneArgs}, 130d9b7d92SLoGin resource::{RLimit64, RLimitID, RUsage, RUsageWho}, 14*bf4a4899SLoGin KernelStack, Pid, ProcessManager, 15971462beSGnoCiYeH }; 16ab5c8ca4Slogin use crate::{ 17*bf4a4899SLoGin arch::{interrupt::TrapFrame, MMArch}, 180d9b7d92SLoGin filesystem::{ 190d9b7d92SLoGin procfs::procfs_register_pid, 200d9b7d92SLoGin vfs::{file::FileDescriptorVec, MAX_PATHLEN}, 210d9b7d92SLoGin }, 22971462beSGnoCiYeH include::bindings::bindings::verify_area, 230d9b7d92SLoGin mm::{ucontext::UserStack, MemoryManagementArch, VirtAddr}, 241496ba7bSLoGin process::ProcessControlBlock, 25971462beSGnoCiYeH sched::completion::Completion, 261496ba7bSLoGin syscall::{ 27*bf4a4899SLoGin user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter}, 281496ba7bSLoGin Syscall, SystemError, 291496ba7bSLoGin }, 30ab5c8ca4Slogin }; 31ab5c8ca4Slogin 32ab5c8ca4Slogin impl Syscall { 331496ba7bSLoGin pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 341496ba7bSLoGin let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()); 351496ba7bSLoGin return r; 36ab5c8ca4Slogin } 37ab5c8ca4Slogin 381496ba7bSLoGin pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> { 39*bf4a4899SLoGin // 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit), 40*bf4a4899SLoGin // 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的) 41*bf4a4899SLoGin Self::fork(frame) 42*bf4a4899SLoGin 43*bf4a4899SLoGin // 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏 44*bf4a4899SLoGin // ProcessManager::fork( 45*bf4a4899SLoGin // frame, 46*bf4a4899SLoGin // CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 47*bf4a4899SLoGin // ) 48*bf4a4899SLoGin // .map(|pid| pid.into()) 49ab5c8ca4Slogin } 50ab5c8ca4Slogin 51ab5c8ca4Slogin pub fn execve( 521496ba7bSLoGin path: *const u8, 531496ba7bSLoGin argv: *const *const u8, 541496ba7bSLoGin envp: *const *const u8, 551496ba7bSLoGin frame: &mut TrapFrame, 561496ba7bSLoGin ) -> Result<(), SystemError> { 571496ba7bSLoGin // kdebug!( 581496ba7bSLoGin // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 591496ba7bSLoGin // path, 601496ba7bSLoGin // argv, 611496ba7bSLoGin // envp 621496ba7bSLoGin // ); 63971462beSGnoCiYeH // kdebug!( 64971462beSGnoCiYeH // "before execve: strong count: {}", 65971462beSGnoCiYeH // Arc::strong_count(&ProcessManager::current_pcb()) 66971462beSGnoCiYeH // ); 67971462beSGnoCiYeH 681496ba7bSLoGin if path.is_null() { 691496ba7bSLoGin return Err(SystemError::EINVAL); 701496ba7bSLoGin } 711496ba7bSLoGin 721496ba7bSLoGin let x = || { 731496ba7bSLoGin let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 741496ba7bSLoGin let argv: Vec<String> = check_and_clone_cstr_array(argv)?; 751496ba7bSLoGin let envp: Vec<String> = check_and_clone_cstr_array(envp)?; 761496ba7bSLoGin Ok((path, argv, envp)) 771496ba7bSLoGin }; 781496ba7bSLoGin let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x(); 791496ba7bSLoGin if let Err(e) = r { 801496ba7bSLoGin panic!("Failed to execve: {:?}", e); 811496ba7bSLoGin } 821496ba7bSLoGin let (path, argv, envp) = r.unwrap(); 831496ba7bSLoGin ProcessManager::current_pcb() 841496ba7bSLoGin .basic_mut() 851496ba7bSLoGin .set_name(ProcessControlBlock::generate_name(&path, &argv)); 861496ba7bSLoGin 87876cb89eSGnoCiYeH Self::do_execve(path, argv, envp, frame)?; 88876cb89eSGnoCiYeH 89876cb89eSGnoCiYeH // 关闭设置了O_CLOEXEC的文件描述符 90876cb89eSGnoCiYeH let fd_table = ProcessManager::current_pcb().fd_table(); 91876cb89eSGnoCiYeH fd_table.write().close_on_exec(); 92971462beSGnoCiYeH // kdebug!( 93971462beSGnoCiYeH // "after execve: strong count: {}", 94971462beSGnoCiYeH // Arc::strong_count(&ProcessManager::current_pcb()) 95971462beSGnoCiYeH // ); 96876cb89eSGnoCiYeH 97876cb89eSGnoCiYeH return Ok(()); 98ab5c8ca4Slogin } 99ab5c8ca4Slogin 100ab5c8ca4Slogin pub fn wait4( 1011496ba7bSLoGin pid: i64, 1021496ba7bSLoGin wstatus: *mut i32, 1031496ba7bSLoGin options: i32, 104ab5c8ca4Slogin rusage: *mut c_void, 105ab5c8ca4Slogin ) -> Result<usize, SystemError> { 106*bf4a4899SLoGin let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?; 107*bf4a4899SLoGin 108*bf4a4899SLoGin let wstatus_buf = if wstatus.is_null() { 109*bf4a4899SLoGin None 110*bf4a4899SLoGin } else { 111*bf4a4899SLoGin Some(UserBufferWriter::new( 112*bf4a4899SLoGin wstatus, 113*bf4a4899SLoGin core::mem::size_of::<i32>(), 114*bf4a4899SLoGin true, 115*bf4a4899SLoGin )?) 116b7b843beSGnoCiYeH }; 117b7b843beSGnoCiYeH 118*bf4a4899SLoGin let mut tmp_rusage = if rusage.is_null() { 119*bf4a4899SLoGin None 120*bf4a4899SLoGin } else { 121*bf4a4899SLoGin Some(RUsage::default()) 122*bf4a4899SLoGin }; 1231496ba7bSLoGin 124*bf4a4899SLoGin let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?; 1251496ba7bSLoGin 126*bf4a4899SLoGin if !rusage.is_null() { 127*bf4a4899SLoGin let mut rusage_buf = UserBufferWriter::new::<RUsage>( 128*bf4a4899SLoGin rusage as *mut RUsage, 129*bf4a4899SLoGin core::mem::size_of::<RUsage>(), 130*bf4a4899SLoGin true, 131b7b843beSGnoCiYeH )?; 132*bf4a4899SLoGin rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?; 1331496ba7bSLoGin } 134*bf4a4899SLoGin return Ok(r); 135ab5c8ca4Slogin } 136ab5c8ca4Slogin 137ab5c8ca4Slogin /// # 退出进程 138ab5c8ca4Slogin /// 139ab5c8ca4Slogin /// ## 参数 140ab5c8ca4Slogin /// 141ab5c8ca4Slogin /// - status: 退出状态 142ab5c8ca4Slogin pub fn exit(status: usize) -> ! { 1431496ba7bSLoGin ProcessManager::exit(status); 144ab5c8ca4Slogin } 145ab5c8ca4Slogin 1461496ba7bSLoGin /// @brief 获取当前进程的pid 1471496ba7bSLoGin pub fn getpid() -> Result<Pid, SystemError> { 1481496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 149393f6915SLoGin return Ok(current_pcb.tgid()); 1501496ba7bSLoGin } 1511496ba7bSLoGin 1521496ba7bSLoGin /// @brief 获取指定进程的pgid 1531496ba7bSLoGin /// 1541496ba7bSLoGin /// @param pid 指定一个进程号 1551496ba7bSLoGin /// 1561496ba7bSLoGin /// @return 成功,指定进程的进程组id 1571496ba7bSLoGin /// @return 错误,不存在该进程 1581496ba7bSLoGin pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 1591496ba7bSLoGin if pid == Pid(0) { 1601496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1611496ba7bSLoGin pid = current_pcb.pid(); 1621496ba7bSLoGin } 1631496ba7bSLoGin let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 1641496ba7bSLoGin return Ok(target_proc.basic().pgid()); 1651496ba7bSLoGin } 1661496ba7bSLoGin /// @brief 获取当前进程的父进程id 1671496ba7bSLoGin 1681496ba7bSLoGin /// 若为initproc则ppid设置为0 1691496ba7bSLoGin pub fn getppid() -> Result<Pid, SystemError> { 1701496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 1711496ba7bSLoGin return Ok(current_pcb.basic().ppid()); 172ab5c8ca4Slogin } 173971462beSGnoCiYeH 174971462beSGnoCiYeH pub fn clone( 175971462beSGnoCiYeH current_trapframe: &mut TrapFrame, 176971462beSGnoCiYeH clone_args: KernelCloneArgs, 177971462beSGnoCiYeH ) -> Result<usize, SystemError> { 178971462beSGnoCiYeH let flags = clone_args.flags; 179971462beSGnoCiYeH 180971462beSGnoCiYeH let vfork = Arc::new(Completion::new()); 181971462beSGnoCiYeH 182971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_PIDFD) 183971462beSGnoCiYeH && flags.contains(CloneFlags::CLONE_PARENT_SETTID) 184971462beSGnoCiYeH { 185971462beSGnoCiYeH return Err(SystemError::EINVAL); 186971462beSGnoCiYeH } 187971462beSGnoCiYeH 188971462beSGnoCiYeH let current_pcb = ProcessManager::current_pcb(); 189971462beSGnoCiYeH let new_kstack = KernelStack::new()?; 190971462beSGnoCiYeH let name = current_pcb.basic().name().to_string(); 191971462beSGnoCiYeH let pcb = ProcessControlBlock::new(name, new_kstack); 192971462beSGnoCiYeH // 克隆pcb 193971462beSGnoCiYeH ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?; 194971462beSGnoCiYeH ProcessManager::add_pcb(pcb.clone()); 195971462beSGnoCiYeH 196971462beSGnoCiYeH // 向procfs注册进程 197971462beSGnoCiYeH procfs_register_pid(pcb.pid()).unwrap_or_else(|e| { 198971462beSGnoCiYeH panic!( 199971462beSGnoCiYeH "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}", 200971462beSGnoCiYeH pcb.pid(), 201971462beSGnoCiYeH e 202971462beSGnoCiYeH ) 203971462beSGnoCiYeH }); 204971462beSGnoCiYeH 205971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_VFORK) { 206971462beSGnoCiYeH pcb.thread.write().vfork_done = Some(vfork.clone()); 207971462beSGnoCiYeH } 208971462beSGnoCiYeH 209971462beSGnoCiYeH if pcb.thread.read().set_child_tid.is_some() { 210971462beSGnoCiYeH let addr = pcb.thread.read().set_child_tid.unwrap(); 211971462beSGnoCiYeH let mut writer = 212971462beSGnoCiYeH UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 213971462beSGnoCiYeH writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; 214971462beSGnoCiYeH } 215971462beSGnoCiYeH 216971462beSGnoCiYeH ProcessManager::wakeup(&pcb).unwrap_or_else(|e| { 217971462beSGnoCiYeH panic!( 218971462beSGnoCiYeH "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}", 219971462beSGnoCiYeH pcb.pid(), 220971462beSGnoCiYeH e 221971462beSGnoCiYeH ) 222971462beSGnoCiYeH }); 223971462beSGnoCiYeH 224971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_VFORK) { 225971462beSGnoCiYeH // 等待子进程结束或者exec; 226971462beSGnoCiYeH vfork.wait_for_completion_interruptible()?; 227971462beSGnoCiYeH } 228971462beSGnoCiYeH 229971462beSGnoCiYeH return Ok(pcb.pid().0); 230971462beSGnoCiYeH } 231971462beSGnoCiYeH 232971462beSGnoCiYeH /// 设置线程地址 233971462beSGnoCiYeH pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> { 234971462beSGnoCiYeH if !unsafe { verify_area(ptr as u64, core::mem::size_of::<i32>() as u64) } { 235971462beSGnoCiYeH return Err(SystemError::EFAULT); 236971462beSGnoCiYeH } 237971462beSGnoCiYeH 238971462beSGnoCiYeH let pcb = ProcessManager::current_pcb(); 239971462beSGnoCiYeH pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr)); 240971462beSGnoCiYeH Ok(pcb.pid.0) 241971462beSGnoCiYeH } 242393f6915SLoGin 243393f6915SLoGin pub fn gettid() -> Result<Pid, SystemError> { 244393f6915SLoGin let pcb = ProcessManager::current_pcb(); 245393f6915SLoGin Ok(pcb.pid) 246393f6915SLoGin } 24702e249f3SLoGin 24802e249f3SLoGin pub fn getuid() -> Result<usize, SystemError> { 24902e249f3SLoGin // todo: 增加credit功能之后,需要修改 25002e249f3SLoGin return Ok(0); 25102e249f3SLoGin } 25202e249f3SLoGin 25302e249f3SLoGin pub fn getgid() -> Result<usize, SystemError> { 25402e249f3SLoGin // todo: 增加credit功能之后,需要修改 25502e249f3SLoGin return Ok(0); 25602e249f3SLoGin } 25702e249f3SLoGin 25802e249f3SLoGin pub fn geteuid() -> Result<usize, SystemError> { 25902e249f3SLoGin // todo: 增加credit功能之后,需要修改 26002e249f3SLoGin return Ok(0); 26102e249f3SLoGin } 26202e249f3SLoGin 26302e249f3SLoGin pub fn getegid() -> Result<usize, SystemError> { 26402e249f3SLoGin // todo: 增加credit功能之后,需要修改 26502e249f3SLoGin return Ok(0); 26602e249f3SLoGin } 267be8cdf4bSLoGin 268be8cdf4bSLoGin pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> { 269be8cdf4bSLoGin let who = RUsageWho::try_from(who)?; 270be8cdf4bSLoGin let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?; 271be8cdf4bSLoGin let pcb = ProcessManager::current_pcb(); 272be8cdf4bSLoGin let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?; 273be8cdf4bSLoGin 274be8cdf4bSLoGin let ubuf = writer.buffer::<RUsage>(0).unwrap(); 275be8cdf4bSLoGin ubuf.copy_from_slice(&[rusage]); 276be8cdf4bSLoGin 277be8cdf4bSLoGin return Ok(0); 278be8cdf4bSLoGin } 2790d9b7d92SLoGin 2800d9b7d92SLoGin /// # 设置资源限制 2810d9b7d92SLoGin /// 2820d9b7d92SLoGin /// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能 2830d9b7d92SLoGin /// 2840d9b7d92SLoGin /// ## 参数 2850d9b7d92SLoGin /// 2860d9b7d92SLoGin /// - pid: 进程号 2870d9b7d92SLoGin /// - resource: 资源类型 2880d9b7d92SLoGin /// - new_limit: 新的资源限制 2890d9b7d92SLoGin /// - old_limit: 旧的资源限制 2900d9b7d92SLoGin /// 2910d9b7d92SLoGin /// ## 返回值 2920d9b7d92SLoGin /// 2930d9b7d92SLoGin /// - 成功,0 2940d9b7d92SLoGin /// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit 2950d9b7d92SLoGin /// 2960d9b7d92SLoGin pub fn prlimit64( 2970d9b7d92SLoGin _pid: Pid, 2980d9b7d92SLoGin resource: usize, 299*bf4a4899SLoGin _new_limit: *const RLimit64, 3000d9b7d92SLoGin old_limit: *mut RLimit64, 3010d9b7d92SLoGin ) -> Result<usize, SystemError> { 3020d9b7d92SLoGin let resource = RLimitID::try_from(resource)?; 3030d9b7d92SLoGin let mut writer = None; 3040d9b7d92SLoGin 3050d9b7d92SLoGin if !old_limit.is_null() { 3060d9b7d92SLoGin writer = Some(UserBufferWriter::new( 3070d9b7d92SLoGin old_limit, 3080d9b7d92SLoGin core::mem::size_of::<RLimit64>(), 3090d9b7d92SLoGin true, 3100d9b7d92SLoGin )?); 3110d9b7d92SLoGin } 3120d9b7d92SLoGin 3130d9b7d92SLoGin match resource { 3140d9b7d92SLoGin RLimitID::Stack => { 3150d9b7d92SLoGin if let Some(mut writer) = writer { 3160d9b7d92SLoGin let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 3170d9b7d92SLoGin rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64; 3180d9b7d92SLoGin rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64; 3190d9b7d92SLoGin } 3200d9b7d92SLoGin return Ok(0); 3210d9b7d92SLoGin } 3220d9b7d92SLoGin 3230d9b7d92SLoGin RLimitID::Nofile => { 3240d9b7d92SLoGin if let Some(mut writer) = writer { 3250d9b7d92SLoGin let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 3260d9b7d92SLoGin rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64; 3270d9b7d92SLoGin rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64; 3280d9b7d92SLoGin } 3290d9b7d92SLoGin return Ok(0); 3300d9b7d92SLoGin } 3310d9b7d92SLoGin 3320d9b7d92SLoGin RLimitID::As | RLimitID::Rss => { 3330d9b7d92SLoGin if let Some(mut writer) = writer { 3340d9b7d92SLoGin let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 3350d9b7d92SLoGin rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64; 3360d9b7d92SLoGin rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64; 3370d9b7d92SLoGin } 3380d9b7d92SLoGin return Ok(0); 3390d9b7d92SLoGin } 3400d9b7d92SLoGin 3410d9b7d92SLoGin _ => { 3420d9b7d92SLoGin return Err(SystemError::ENOSYS); 3430d9b7d92SLoGin } 3440d9b7d92SLoGin } 3450d9b7d92SLoGin } 346ab5c8ca4Slogin } 347