11496ba7bSLoGin use core::ffi::c_void; 2ab5c8ca4Slogin 3*703ce5a7SLoGin use alloc::{ffi::CString, string::ToString, sync::Arc, vec::Vec}; 4*703ce5a7SLoGin use log::error; 591e9d4abSLoGin use system_error::SystemError; 61496ba7bSLoGin 7971462beSGnoCiYeH use super::{ 8971462beSGnoCiYeH abi::WaitOption, 9bf4a4899SLoGin exit::kernel_wait4, 10971462beSGnoCiYeH fork::{CloneFlags, KernelCloneArgs}, 110d9b7d92SLoGin resource::{RLimit64, RLimitID, RUsage, RUsageWho}, 12bf4a4899SLoGin KernelStack, Pid, ProcessManager, 13971462beSGnoCiYeH }; 14ab5c8ca4Slogin use crate::{ 15bf4a4899SLoGin arch::{interrupt::TrapFrame, MMArch}, 160d9b7d92SLoGin filesystem::{ 170d9b7d92SLoGin procfs::procfs_register_pid, 180d9b7d92SLoGin vfs::{file::FileDescriptorVec, MAX_PATHLEN}, 190d9b7d92SLoGin }, 204fda81ceSLoGin mm::{ucontext::UserStack, verify_area, MemoryManagementArch, VirtAddr}, 211496ba7bSLoGin process::ProcessControlBlock, 22971462beSGnoCiYeH sched::completion::Completion, 231496ba7bSLoGin syscall::{ 24bf4a4899SLoGin user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter}, 2591e9d4abSLoGin Syscall, 261496ba7bSLoGin }, 27ab5c8ca4Slogin }; 28ab5c8ca4Slogin 298c6f2184Ssspphh //参考资料:https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17 308c6f2184Ssspphh #[repr(C)] 318c6f2184Ssspphh #[derive(Debug, Clone, Copy)] 328c6f2184Ssspphh pub struct PosixOldUtsName { 338c6f2184Ssspphh pub sysname: [u8; 65], 348c6f2184Ssspphh pub nodename: [u8; 65], 358c6f2184Ssspphh pub release: [u8; 65], 368c6f2184Ssspphh pub version: [u8; 65], 378c6f2184Ssspphh pub machine: [u8; 65], 388c6f2184Ssspphh } 398c6f2184Ssspphh 408c6f2184Ssspphh impl PosixOldUtsName { 418c6f2184Ssspphh pub fn new() -> Self { 428c6f2184Ssspphh const SYS_NAME: &[u8] = b"DragonOS"; 438c6f2184Ssspphh const NODENAME: &[u8] = b"DragonOS"; 448c6f2184Ssspphh const RELEASE: &[u8] = env!("CARGO_PKG_VERSION").as_bytes(); 458c6f2184Ssspphh const VERSION: &[u8] = env!("CARGO_PKG_VERSION").as_bytes(); 468c6f2184Ssspphh 478c6f2184Ssspphh #[cfg(target_arch = "x86_64")] 488c6f2184Ssspphh const MACHINE: &[u8] = b"x86_64"; 498c6f2184Ssspphh 508c6f2184Ssspphh #[cfg(target_arch = "aarch64")] 518c6f2184Ssspphh const MACHINE: &[u8] = b"aarch64"; 528c6f2184Ssspphh 538c6f2184Ssspphh #[cfg(target_arch = "riscv64")] 548c6f2184Ssspphh const MACHINE: &[u8] = b"riscv64"; 558c6f2184Ssspphh 568c6f2184Ssspphh let mut r = Self { 578c6f2184Ssspphh sysname: [0; 65], 588c6f2184Ssspphh nodename: [0; 65], 598c6f2184Ssspphh release: [0; 65], 608c6f2184Ssspphh version: [0; 65], 618c6f2184Ssspphh machine: [0; 65], 628c6f2184Ssspphh }; 638c6f2184Ssspphh 648c6f2184Ssspphh r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME); 658c6f2184Ssspphh r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME); 668c6f2184Ssspphh r.release[0..RELEASE.len()].copy_from_slice(RELEASE); 678c6f2184Ssspphh r.version[0..VERSION.len()].copy_from_slice(VERSION); 688c6f2184Ssspphh r.machine[0..MACHINE.len()].copy_from_slice(MACHINE); 698c6f2184Ssspphh 708c6f2184Ssspphh return r; 718c6f2184Ssspphh } 728c6f2184Ssspphh } 738c6f2184Ssspphh 74ab5c8ca4Slogin impl Syscall { 75840045afSLoGin pub fn fork(frame: &TrapFrame) -> Result<usize, SystemError> { 764ad52e57S裕依2439 ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()) 77ab5c8ca4Slogin } 78ab5c8ca4Slogin 79840045afSLoGin pub fn vfork(frame: &TrapFrame) -> Result<usize, SystemError> { 80bf4a4899SLoGin // 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit), 81bf4a4899SLoGin // 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的) 82bf4a4899SLoGin Self::fork(frame) 83bf4a4899SLoGin 84bf4a4899SLoGin // 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏 85bf4a4899SLoGin // ProcessManager::fork( 86bf4a4899SLoGin // frame, 87bf4a4899SLoGin // CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 88bf4a4899SLoGin // ) 89bf4a4899SLoGin // .map(|pid| pid.into()) 90ab5c8ca4Slogin } 91ab5c8ca4Slogin 92ab5c8ca4Slogin pub fn execve( 931496ba7bSLoGin path: *const u8, 941496ba7bSLoGin argv: *const *const u8, 951496ba7bSLoGin envp: *const *const u8, 961496ba7bSLoGin frame: &mut TrapFrame, 971496ba7bSLoGin ) -> Result<(), SystemError> { 982eab6dd7S曾俊 // debug!( 991496ba7bSLoGin // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 1001496ba7bSLoGin // path, 1011496ba7bSLoGin // argv, 1021496ba7bSLoGin // envp 1031496ba7bSLoGin // ); 1042eab6dd7S曾俊 // debug!( 105971462beSGnoCiYeH // "before execve: strong count: {}", 106971462beSGnoCiYeH // Arc::strong_count(&ProcessManager::current_pcb()) 107971462beSGnoCiYeH // ); 108971462beSGnoCiYeH 1091496ba7bSLoGin if path.is_null() { 1101496ba7bSLoGin return Err(SystemError::EINVAL); 1111496ba7bSLoGin } 1121496ba7bSLoGin 1131496ba7bSLoGin let x = || { 114*703ce5a7SLoGin let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 115*703ce5a7SLoGin let argv: Vec<CString> = check_and_clone_cstr_array(argv)?; 116*703ce5a7SLoGin let envp: Vec<CString> = check_and_clone_cstr_array(envp)?; 1171496ba7bSLoGin Ok((path, argv, envp)) 1181496ba7bSLoGin }; 119*703ce5a7SLoGin let (path, argv, envp) = x().inspect_err(|e: &SystemError| { 120*703ce5a7SLoGin error!("Failed to execve: {:?}", e); 121*703ce5a7SLoGin })?; 122*703ce5a7SLoGin 123*703ce5a7SLoGin let path = path.into_string().map_err(|_| SystemError::EINVAL)?; 1241496ba7bSLoGin ProcessManager::current_pcb() 1251496ba7bSLoGin .basic_mut() 1261496ba7bSLoGin .set_name(ProcessControlBlock::generate_name(&path, &argv)); 1271496ba7bSLoGin 128876cb89eSGnoCiYeH Self::do_execve(path, argv, envp, frame)?; 129876cb89eSGnoCiYeH 130876cb89eSGnoCiYeH // 关闭设置了O_CLOEXEC的文件描述符 131876cb89eSGnoCiYeH let fd_table = ProcessManager::current_pcb().fd_table(); 132876cb89eSGnoCiYeH fd_table.write().close_on_exec(); 1332eab6dd7S曾俊 // debug!( 134971462beSGnoCiYeH // "after execve: strong count: {}", 135971462beSGnoCiYeH // Arc::strong_count(&ProcessManager::current_pcb()) 136971462beSGnoCiYeH // ); 137876cb89eSGnoCiYeH 138876cb89eSGnoCiYeH return Ok(()); 139ab5c8ca4Slogin } 140ab5c8ca4Slogin 141ab5c8ca4Slogin pub fn wait4( 1421496ba7bSLoGin pid: i64, 1431496ba7bSLoGin wstatus: *mut i32, 1441496ba7bSLoGin options: i32, 145ab5c8ca4Slogin rusage: *mut c_void, 146ab5c8ca4Slogin ) -> Result<usize, SystemError> { 147bf4a4899SLoGin let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?; 148bf4a4899SLoGin 149bf4a4899SLoGin let wstatus_buf = if wstatus.is_null() { 150bf4a4899SLoGin None 151bf4a4899SLoGin } else { 152bf4a4899SLoGin Some(UserBufferWriter::new( 153bf4a4899SLoGin wstatus, 154bf4a4899SLoGin core::mem::size_of::<i32>(), 155bf4a4899SLoGin true, 156bf4a4899SLoGin )?) 157b7b843beSGnoCiYeH }; 158b7b843beSGnoCiYeH 159bf4a4899SLoGin let mut tmp_rusage = if rusage.is_null() { 160bf4a4899SLoGin None 161bf4a4899SLoGin } else { 162bf4a4899SLoGin Some(RUsage::default()) 163bf4a4899SLoGin }; 1641496ba7bSLoGin 165bf4a4899SLoGin let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?; 1661496ba7bSLoGin 167bf4a4899SLoGin if !rusage.is_null() { 168bf4a4899SLoGin let mut rusage_buf = UserBufferWriter::new::<RUsage>( 169bf4a4899SLoGin rusage as *mut RUsage, 170bf4a4899SLoGin core::mem::size_of::<RUsage>(), 171bf4a4899SLoGin true, 172b7b843beSGnoCiYeH )?; 173bf4a4899SLoGin rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?; 1741496ba7bSLoGin } 175bf4a4899SLoGin return Ok(r); 176ab5c8ca4Slogin } 177ab5c8ca4Slogin 178ab5c8ca4Slogin /// # 退出进程 179ab5c8ca4Slogin /// 180ab5c8ca4Slogin /// ## 参数 181ab5c8ca4Slogin /// 182ab5c8ca4Slogin /// - status: 退出状态 183ab5c8ca4Slogin pub fn exit(status: usize) -> ! { 1841496ba7bSLoGin ProcessManager::exit(status); 185ab5c8ca4Slogin } 186ab5c8ca4Slogin 1871496ba7bSLoGin /// @brief 获取当前进程的pid 1881496ba7bSLoGin pub fn getpid() -> Result<Pid, SystemError> { 1891496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 190393f6915SLoGin return Ok(current_pcb.tgid()); 1911496ba7bSLoGin } 1921496ba7bSLoGin 1931496ba7bSLoGin /// @brief 获取指定进程的pgid 1941496ba7bSLoGin /// 1951496ba7bSLoGin /// @param pid 指定一个进程号 1961496ba7bSLoGin /// 1971496ba7bSLoGin /// @return 成功,指定进程的进程组id 1981496ba7bSLoGin /// @return 错误,不存在该进程 1991496ba7bSLoGin pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 2001496ba7bSLoGin if pid == Pid(0) { 2011496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 2021496ba7bSLoGin pid = current_pcb.pid(); 2031496ba7bSLoGin } 2041496ba7bSLoGin let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 2051496ba7bSLoGin return Ok(target_proc.basic().pgid()); 2061496ba7bSLoGin } 2071496ba7bSLoGin /// @brief 获取当前进程的父进程id 2081496ba7bSLoGin 2091496ba7bSLoGin /// 若为initproc则ppid设置为0 2101496ba7bSLoGin pub fn getppid() -> Result<Pid, SystemError> { 2111496ba7bSLoGin let current_pcb = ProcessManager::current_pcb(); 2121496ba7bSLoGin return Ok(current_pcb.basic().ppid()); 213ab5c8ca4Slogin } 214971462beSGnoCiYeH 215971462beSGnoCiYeH pub fn clone( 216840045afSLoGin current_trapframe: &TrapFrame, 217971462beSGnoCiYeH clone_args: KernelCloneArgs, 218971462beSGnoCiYeH ) -> Result<usize, SystemError> { 219971462beSGnoCiYeH let flags = clone_args.flags; 220971462beSGnoCiYeH 221971462beSGnoCiYeH let vfork = Arc::new(Completion::new()); 222971462beSGnoCiYeH 223971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_PIDFD) 224971462beSGnoCiYeH && flags.contains(CloneFlags::CLONE_PARENT_SETTID) 225971462beSGnoCiYeH { 226971462beSGnoCiYeH return Err(SystemError::EINVAL); 227971462beSGnoCiYeH } 228971462beSGnoCiYeH 229971462beSGnoCiYeH let current_pcb = ProcessManager::current_pcb(); 230971462beSGnoCiYeH let new_kstack = KernelStack::new()?; 231971462beSGnoCiYeH let name = current_pcb.basic().name().to_string(); 232971462beSGnoCiYeH let pcb = ProcessControlBlock::new(name, new_kstack); 233971462beSGnoCiYeH // 克隆pcb 234971462beSGnoCiYeH ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?; 235971462beSGnoCiYeH ProcessManager::add_pcb(pcb.clone()); 236971462beSGnoCiYeH 237971462beSGnoCiYeH // 向procfs注册进程 238971462beSGnoCiYeH procfs_register_pid(pcb.pid()).unwrap_or_else(|e| { 239971462beSGnoCiYeH panic!( 240971462beSGnoCiYeH "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}", 241971462beSGnoCiYeH pcb.pid(), 242971462beSGnoCiYeH e 243971462beSGnoCiYeH ) 244971462beSGnoCiYeH }); 245971462beSGnoCiYeH 246971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_VFORK) { 24752bcb59eSGnoCiYeH pcb.thread.write_irqsave().vfork_done = Some(vfork.clone()); 248971462beSGnoCiYeH } 249971462beSGnoCiYeH 25052bcb59eSGnoCiYeH if pcb.thread.read_irqsave().set_child_tid.is_some() { 25152bcb59eSGnoCiYeH let addr = pcb.thread.read_irqsave().set_child_tid.unwrap(); 252971462beSGnoCiYeH let mut writer = 253971462beSGnoCiYeH UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 254971462beSGnoCiYeH writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; 255971462beSGnoCiYeH } 256971462beSGnoCiYeH 257971462beSGnoCiYeH ProcessManager::wakeup(&pcb).unwrap_or_else(|e| { 258971462beSGnoCiYeH panic!( 259971462beSGnoCiYeH "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}", 260971462beSGnoCiYeH pcb.pid(), 261971462beSGnoCiYeH e 262971462beSGnoCiYeH ) 263971462beSGnoCiYeH }); 264971462beSGnoCiYeH 265971462beSGnoCiYeH if flags.contains(CloneFlags::CLONE_VFORK) { 266971462beSGnoCiYeH // 等待子进程结束或者exec; 267971462beSGnoCiYeH vfork.wait_for_completion_interruptible()?; 268971462beSGnoCiYeH } 269971462beSGnoCiYeH 270971462beSGnoCiYeH return Ok(pcb.pid().0); 271971462beSGnoCiYeH } 272971462beSGnoCiYeH 273971462beSGnoCiYeH /// 设置线程地址 274971462beSGnoCiYeH pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> { 2754fda81ceSLoGin verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>()) 2764fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 277971462beSGnoCiYeH 278971462beSGnoCiYeH let pcb = ProcessManager::current_pcb(); 27952bcb59eSGnoCiYeH pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr)); 280971462beSGnoCiYeH Ok(pcb.pid.0) 281971462beSGnoCiYeH } 282393f6915SLoGin 283393f6915SLoGin pub fn gettid() -> Result<Pid, SystemError> { 284393f6915SLoGin let pcb = ProcessManager::current_pcb(); 285393f6915SLoGin Ok(pcb.pid) 286393f6915SLoGin } 28702e249f3SLoGin 28802e249f3SLoGin pub fn getuid() -> Result<usize, SystemError> { 28902e249f3SLoGin // todo: 增加credit功能之后,需要修改 29002e249f3SLoGin return Ok(0); 29102e249f3SLoGin } 29202e249f3SLoGin 29302e249f3SLoGin pub fn getgid() -> Result<usize, SystemError> { 29402e249f3SLoGin // todo: 增加credit功能之后,需要修改 29502e249f3SLoGin return Ok(0); 29602e249f3SLoGin } 29702e249f3SLoGin 29802e249f3SLoGin pub fn geteuid() -> Result<usize, SystemError> { 29902e249f3SLoGin // todo: 增加credit功能之后,需要修改 30002e249f3SLoGin return Ok(0); 30102e249f3SLoGin } 30202e249f3SLoGin 30302e249f3SLoGin pub fn getegid() -> Result<usize, SystemError> { 30402e249f3SLoGin // todo: 增加credit功能之后,需要修改 30502e249f3SLoGin return Ok(0); 30602e249f3SLoGin } 307be8cdf4bSLoGin 308be8cdf4bSLoGin pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> { 309be8cdf4bSLoGin let who = RUsageWho::try_from(who)?; 310be8cdf4bSLoGin let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?; 311be8cdf4bSLoGin let pcb = ProcessManager::current_pcb(); 312be8cdf4bSLoGin let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?; 313be8cdf4bSLoGin 314be8cdf4bSLoGin let ubuf = writer.buffer::<RUsage>(0).unwrap(); 315be8cdf4bSLoGin ubuf.copy_from_slice(&[rusage]); 316be8cdf4bSLoGin 317be8cdf4bSLoGin return Ok(0); 318be8cdf4bSLoGin } 3190d9b7d92SLoGin 3200d9b7d92SLoGin /// # 设置资源限制 3210d9b7d92SLoGin /// 3220d9b7d92SLoGin /// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能 3230d9b7d92SLoGin /// 3240d9b7d92SLoGin /// ## 参数 3250d9b7d92SLoGin /// 3260d9b7d92SLoGin /// - pid: 进程号 3270d9b7d92SLoGin /// - resource: 资源类型 3280d9b7d92SLoGin /// - new_limit: 新的资源限制 3290d9b7d92SLoGin /// - old_limit: 旧的资源限制 3300d9b7d92SLoGin /// 3310d9b7d92SLoGin /// ## 返回值 3320d9b7d92SLoGin /// 3330d9b7d92SLoGin /// - 成功,0 3340d9b7d92SLoGin /// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit 3350d9b7d92SLoGin /// 3360d9b7d92SLoGin pub fn prlimit64( 3370d9b7d92SLoGin _pid: Pid, 3380d9b7d92SLoGin resource: usize, 339bf4a4899SLoGin _new_limit: *const RLimit64, 3400d9b7d92SLoGin old_limit: *mut RLimit64, 3410d9b7d92SLoGin ) -> Result<usize, SystemError> { 3420d9b7d92SLoGin let resource = RLimitID::try_from(resource)?; 3430d9b7d92SLoGin let mut writer = None; 3440d9b7d92SLoGin 3450d9b7d92SLoGin if !old_limit.is_null() { 3460d9b7d92SLoGin writer = Some(UserBufferWriter::new( 3470d9b7d92SLoGin old_limit, 3480d9b7d92SLoGin core::mem::size_of::<RLimit64>(), 3490d9b7d92SLoGin true, 3500d9b7d92SLoGin )?); 3510d9b7d92SLoGin } 3520d9b7d92SLoGin 3530d9b7d92SLoGin match resource { 3540d9b7d92SLoGin RLimitID::Stack => { 3550d9b7d92SLoGin if let Some(mut writer) = writer { 3560d9b7d92SLoGin let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 3570d9b7d92SLoGin rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64; 3580d9b7d92SLoGin rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64; 3590d9b7d92SLoGin } 3600d9b7d92SLoGin return Ok(0); 3610d9b7d92SLoGin } 3620d9b7d92SLoGin 3630d9b7d92SLoGin RLimitID::Nofile => { 3640d9b7d92SLoGin if let Some(mut writer) = writer { 3650d9b7d92SLoGin let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 3660d9b7d92SLoGin rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64; 3670d9b7d92SLoGin rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64; 3680d9b7d92SLoGin } 3690d9b7d92SLoGin return Ok(0); 3700d9b7d92SLoGin } 3710d9b7d92SLoGin 3720d9b7d92SLoGin RLimitID::As | RLimitID::Rss => { 3730d9b7d92SLoGin if let Some(mut writer) = writer { 3740d9b7d92SLoGin let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 3750d9b7d92SLoGin rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64; 3760d9b7d92SLoGin rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64; 3770d9b7d92SLoGin } 3780d9b7d92SLoGin return Ok(0); 3790d9b7d92SLoGin } 3800d9b7d92SLoGin 3810d9b7d92SLoGin _ => { 3820d9b7d92SLoGin return Err(SystemError::ENOSYS); 3830d9b7d92SLoGin } 3840d9b7d92SLoGin } 3850d9b7d92SLoGin } 3868c6f2184Ssspphh 3878c6f2184Ssspphh pub fn uname(name: *mut PosixOldUtsName) -> Result<usize, SystemError> { 3888c6f2184Ssspphh let mut writer = 3898c6f2184Ssspphh UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?; 3908c6f2184Ssspphh writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?; 3918c6f2184Ssspphh 3928c6f2184Ssspphh return Ok(0); 3938c6f2184Ssspphh } 394ab5c8ca4Slogin } 395