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