1 use core::ffi::c_void; 2 3 use alloc::{ffi::CString, string::ToString, sync::Arc, vec::Vec}; 4 use log::error; 5 use system_error::SystemError; 6 7 use super::{ 8 abi::WaitOption, 9 exit::kernel_wait4, 10 fork::{CloneFlags, KernelCloneArgs}, 11 resource::{RLimit64, RLimitID, RUsage, RUsageWho}, 12 KernelStack, Pid, ProcessManager, 13 }; 14 use crate::{ 15 arch::{interrupt::TrapFrame, MMArch}, 16 filesystem::{ 17 procfs::procfs_register_pid, 18 vfs::{file::FileDescriptorVec, MAX_PATHLEN}, 19 }, 20 mm::{ucontext::UserStack, verify_area, MemoryManagementArch, VirtAddr}, 21 process::ProcessControlBlock, 22 sched::completion::Completion, 23 syscall::{ 24 user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter}, 25 Syscall, 26 }, 27 }; 28 29 //参考资料:https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17 30 #[repr(C)] 31 #[derive(Debug, Clone, Copy)] 32 pub struct PosixOldUtsName { 33 pub sysname: [u8; 65], 34 pub nodename: [u8; 65], 35 pub release: [u8; 65], 36 pub version: [u8; 65], 37 pub machine: [u8; 65], 38 } 39 40 impl PosixOldUtsName { 41 pub fn new() -> Self { 42 const SYS_NAME: &[u8] = b"DragonOS"; 43 const NODENAME: &[u8] = b"DragonOS"; 44 const RELEASE: &[u8] = env!("CARGO_PKG_VERSION").as_bytes(); 45 const VERSION: &[u8] = env!("CARGO_PKG_VERSION").as_bytes(); 46 47 #[cfg(target_arch = "x86_64")] 48 const MACHINE: &[u8] = b"x86_64"; 49 50 #[cfg(target_arch = "aarch64")] 51 const MACHINE: &[u8] = b"aarch64"; 52 53 #[cfg(target_arch = "riscv64")] 54 const MACHINE: &[u8] = b"riscv64"; 55 56 let mut r = Self { 57 sysname: [0; 65], 58 nodename: [0; 65], 59 release: [0; 65], 60 version: [0; 65], 61 machine: [0; 65], 62 }; 63 64 r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME); 65 r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME); 66 r.release[0..RELEASE.len()].copy_from_slice(RELEASE); 67 r.version[0..VERSION.len()].copy_from_slice(VERSION); 68 r.machine[0..MACHINE.len()].copy_from_slice(MACHINE); 69 70 return r; 71 } 72 } 73 74 impl Syscall { 75 pub fn fork(frame: &TrapFrame) -> Result<usize, SystemError> { 76 ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()) 77 } 78 79 pub fn vfork(frame: &TrapFrame) -> Result<usize, SystemError> { 80 // 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit), 81 // 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的) 82 Self::fork(frame) 83 84 // 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏 85 // ProcessManager::fork( 86 // frame, 87 // CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL, 88 // ) 89 // .map(|pid| pid.into()) 90 } 91 92 pub fn execve( 93 path: *const u8, 94 argv: *const *const u8, 95 envp: *const *const u8, 96 frame: &mut TrapFrame, 97 ) -> Result<(), SystemError> { 98 // debug!( 99 // "execve path: {:?}, argv: {:?}, envp: {:?}\n", 100 // path, 101 // argv, 102 // envp 103 // ); 104 // debug!( 105 // "before execve: strong count: {}", 106 // Arc::strong_count(&ProcessManager::current_pcb()) 107 // ); 108 109 if path.is_null() { 110 return Err(SystemError::EINVAL); 111 } 112 113 let x = || { 114 let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?; 115 let argv: Vec<CString> = check_and_clone_cstr_array(argv)?; 116 let envp: Vec<CString> = check_and_clone_cstr_array(envp)?; 117 Ok((path, argv, envp)) 118 }; 119 let (path, argv, envp) = x().inspect_err(|e: &SystemError| { 120 error!("Failed to execve: {:?}", e); 121 })?; 122 123 let path = path.into_string().map_err(|_| SystemError::EINVAL)?; 124 ProcessManager::current_pcb() 125 .basic_mut() 126 .set_name(ProcessControlBlock::generate_name(&path, &argv)); 127 128 Self::do_execve(path, argv, envp, frame)?; 129 130 // 关闭设置了O_CLOEXEC的文件描述符 131 let fd_table = ProcessManager::current_pcb().fd_table(); 132 fd_table.write().close_on_exec(); 133 // debug!( 134 // "after execve: strong count: {}", 135 // Arc::strong_count(&ProcessManager::current_pcb()) 136 // ); 137 138 return Ok(()); 139 } 140 141 pub fn wait4( 142 pid: i64, 143 wstatus: *mut i32, 144 options: i32, 145 rusage: *mut c_void, 146 ) -> Result<usize, SystemError> { 147 let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?; 148 149 let wstatus_buf = if wstatus.is_null() { 150 None 151 } else { 152 Some(UserBufferWriter::new( 153 wstatus, 154 core::mem::size_of::<i32>(), 155 true, 156 )?) 157 }; 158 159 let mut tmp_rusage = if rusage.is_null() { 160 None 161 } else { 162 Some(RUsage::default()) 163 }; 164 165 let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?; 166 167 if !rusage.is_null() { 168 let mut rusage_buf = UserBufferWriter::new::<RUsage>( 169 rusage as *mut RUsage, 170 core::mem::size_of::<RUsage>(), 171 true, 172 )?; 173 rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?; 174 } 175 return Ok(r); 176 } 177 178 /// # 退出进程 179 /// 180 /// ## 参数 181 /// 182 /// - status: 退出状态 183 pub fn exit(status: usize) -> ! { 184 ProcessManager::exit(status); 185 } 186 187 /// @brief 获取当前进程的pid 188 pub fn getpid() -> Result<Pid, SystemError> { 189 let current_pcb = ProcessManager::current_pcb(); 190 return Ok(current_pcb.tgid()); 191 } 192 193 /// @brief 获取指定进程的pgid 194 /// 195 /// @param pid 指定一个进程号 196 /// 197 /// @return 成功,指定进程的进程组id 198 /// @return 错误,不存在该进程 199 pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> { 200 if pid == Pid(0) { 201 let current_pcb = ProcessManager::current_pcb(); 202 pid = current_pcb.pid(); 203 } 204 let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?; 205 return Ok(target_proc.basic().pgid()); 206 } 207 /// @brief 获取当前进程的父进程id 208 209 /// 若为initproc则ppid设置为0 210 pub fn getppid() -> Result<Pid, SystemError> { 211 let current_pcb = ProcessManager::current_pcb(); 212 return Ok(current_pcb.basic().ppid()); 213 } 214 215 pub fn clone( 216 current_trapframe: &TrapFrame, 217 clone_args: KernelCloneArgs, 218 ) -> Result<usize, SystemError> { 219 let flags = clone_args.flags; 220 221 let vfork = Arc::new(Completion::new()); 222 223 if flags.contains(CloneFlags::CLONE_PIDFD) 224 && flags.contains(CloneFlags::CLONE_PARENT_SETTID) 225 { 226 return Err(SystemError::EINVAL); 227 } 228 229 let current_pcb = ProcessManager::current_pcb(); 230 let new_kstack = KernelStack::new()?; 231 let name = current_pcb.basic().name().to_string(); 232 let pcb = ProcessControlBlock::new(name, new_kstack); 233 // 克隆pcb 234 ProcessManager::copy_process(¤t_pcb, &pcb, clone_args, current_trapframe)?; 235 ProcessManager::add_pcb(pcb.clone()); 236 237 // 向procfs注册进程 238 procfs_register_pid(pcb.pid()).unwrap_or_else(|e| { 239 panic!( 240 "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}", 241 pcb.pid(), 242 e 243 ) 244 }); 245 246 if flags.contains(CloneFlags::CLONE_VFORK) { 247 pcb.thread.write_irqsave().vfork_done = Some(vfork.clone()); 248 } 249 250 if pcb.thread.read_irqsave().set_child_tid.is_some() { 251 let addr = pcb.thread.read_irqsave().set_child_tid.unwrap(); 252 let mut writer = 253 UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; 254 writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; 255 } 256 257 ProcessManager::wakeup(&pcb).unwrap_or_else(|e| { 258 panic!( 259 "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}", 260 pcb.pid(), 261 e 262 ) 263 }); 264 265 if flags.contains(CloneFlags::CLONE_VFORK) { 266 // 等待子进程结束或者exec; 267 vfork.wait_for_completion_interruptible()?; 268 } 269 270 return Ok(pcb.pid().0); 271 } 272 273 /// 设置线程地址 274 pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> { 275 verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>()) 276 .map_err(|_| SystemError::EFAULT)?; 277 278 let pcb = ProcessManager::current_pcb(); 279 pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr)); 280 Ok(pcb.pid.0) 281 } 282 283 pub fn gettid() -> Result<Pid, SystemError> { 284 let pcb = ProcessManager::current_pcb(); 285 Ok(pcb.pid) 286 } 287 288 pub fn getuid() -> Result<usize, SystemError> { 289 // todo: 增加credit功能之后,需要修改 290 return Ok(0); 291 } 292 293 pub fn getgid() -> Result<usize, SystemError> { 294 // todo: 增加credit功能之后,需要修改 295 return Ok(0); 296 } 297 298 pub fn geteuid() -> Result<usize, SystemError> { 299 // todo: 增加credit功能之后,需要修改 300 return Ok(0); 301 } 302 303 pub fn getegid() -> Result<usize, SystemError> { 304 // todo: 增加credit功能之后,需要修改 305 return Ok(0); 306 } 307 308 pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> { 309 let who = RUsageWho::try_from(who)?; 310 let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?; 311 let pcb = ProcessManager::current_pcb(); 312 let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?; 313 314 let ubuf = writer.buffer::<RUsage>(0).unwrap(); 315 ubuf.copy_from_slice(&[rusage]); 316 317 return Ok(0); 318 } 319 320 /// # 设置资源限制 321 /// 322 /// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能 323 /// 324 /// ## 参数 325 /// 326 /// - pid: 进程号 327 /// - resource: 资源类型 328 /// - new_limit: 新的资源限制 329 /// - old_limit: 旧的资源限制 330 /// 331 /// ## 返回值 332 /// 333 /// - 成功,0 334 /// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit 335 /// 336 pub fn prlimit64( 337 _pid: Pid, 338 resource: usize, 339 _new_limit: *const RLimit64, 340 old_limit: *mut RLimit64, 341 ) -> Result<usize, SystemError> { 342 let resource = RLimitID::try_from(resource)?; 343 let mut writer = None; 344 345 if !old_limit.is_null() { 346 writer = Some(UserBufferWriter::new( 347 old_limit, 348 core::mem::size_of::<RLimit64>(), 349 true, 350 )?); 351 } 352 353 match resource { 354 RLimitID::Stack => { 355 if let Some(mut writer) = writer { 356 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 357 rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64; 358 rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64; 359 } 360 return Ok(0); 361 } 362 363 RLimitID::Nofile => { 364 if let Some(mut writer) = writer { 365 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 366 rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64; 367 rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64; 368 } 369 return Ok(0); 370 } 371 372 RLimitID::As | RLimitID::Rss => { 373 if let Some(mut writer) = writer { 374 let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0]; 375 rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64; 376 rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64; 377 } 378 return Ok(0); 379 } 380 381 _ => { 382 return Err(SystemError::ENOSYS); 383 } 384 } 385 } 386 387 pub fn uname(name: *mut PosixOldUtsName) -> Result<usize, SystemError> { 388 let mut writer = 389 UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?; 390 writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?; 391 392 return Ok(0); 393 } 394 } 395