xref: /DragonOS/kernel/src/process/syscall.rs (revision 876cb89ecf7c1bf1646bfc392efcbafacad2262f)
11496ba7bSLoGin use core::ffi::c_void;
2ab5c8ca4Slogin 
31496ba7bSLoGin use alloc::{string::String, vec::Vec};
41496ba7bSLoGin 
51496ba7bSLoGin use super::{fork::CloneFlags, Pid, ProcessManager, ProcessState};
6ab5c8ca4Slogin use crate::{
71496ba7bSLoGin     arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch},
81496ba7bSLoGin     exception::InterruptArch,
91496ba7bSLoGin     filesystem::vfs::MAX_PATHLEN,
101496ba7bSLoGin     process::ProcessControlBlock,
111496ba7bSLoGin     syscall::{
121496ba7bSLoGin         user_access::{
131496ba7bSLoGin             check_and_clone_cstr, check_and_clone_cstr_array, UserBufferReader, UserBufferWriter,
141496ba7bSLoGin         },
151496ba7bSLoGin         Syscall, SystemError,
161496ba7bSLoGin     },
17ab5c8ca4Slogin };
18ab5c8ca4Slogin 
19ab5c8ca4Slogin impl Syscall {
201496ba7bSLoGin     pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
211496ba7bSLoGin         let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into());
221496ba7bSLoGin         return r;
23ab5c8ca4Slogin     }
24ab5c8ca4Slogin 
251496ba7bSLoGin     pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
261496ba7bSLoGin         ProcessManager::fork(
271496ba7bSLoGin             frame,
281496ba7bSLoGin             CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
291496ba7bSLoGin         )
301496ba7bSLoGin         .map(|pid| pid.into())
31ab5c8ca4Slogin     }
32ab5c8ca4Slogin 
33ab5c8ca4Slogin     pub fn execve(
341496ba7bSLoGin         path: *const u8,
351496ba7bSLoGin         argv: *const *const u8,
361496ba7bSLoGin         envp: *const *const u8,
371496ba7bSLoGin         frame: &mut TrapFrame,
381496ba7bSLoGin     ) -> Result<(), SystemError> {
391496ba7bSLoGin         // kdebug!(
401496ba7bSLoGin         //     "execve path: {:?}, argv: {:?}, envp: {:?}\n",
411496ba7bSLoGin         //     path,
421496ba7bSLoGin         //     argv,
431496ba7bSLoGin         //     envp
441496ba7bSLoGin         // );
451496ba7bSLoGin         if path.is_null() {
461496ba7bSLoGin             return Err(SystemError::EINVAL);
471496ba7bSLoGin         }
481496ba7bSLoGin 
491496ba7bSLoGin         let x = || {
501496ba7bSLoGin             let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
511496ba7bSLoGin             let argv: Vec<String> = check_and_clone_cstr_array(argv)?;
521496ba7bSLoGin             let envp: Vec<String> = check_and_clone_cstr_array(envp)?;
531496ba7bSLoGin             Ok((path, argv, envp))
541496ba7bSLoGin         };
551496ba7bSLoGin         let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x();
561496ba7bSLoGin         if let Err(e) = r {
571496ba7bSLoGin             panic!("Failed to execve: {:?}", e);
581496ba7bSLoGin         }
591496ba7bSLoGin         let (path, argv, envp) = r.unwrap();
601496ba7bSLoGin         ProcessManager::current_pcb()
611496ba7bSLoGin             .basic_mut()
621496ba7bSLoGin             .set_name(ProcessControlBlock::generate_name(&path, &argv));
631496ba7bSLoGin 
64*876cb89eSGnoCiYeH         Self::do_execve(path, argv, envp, frame)?;
65*876cb89eSGnoCiYeH 
66*876cb89eSGnoCiYeH         // 关闭设置了O_CLOEXEC的文件描述符
67*876cb89eSGnoCiYeH         let fd_table = ProcessManager::current_pcb().fd_table();
68*876cb89eSGnoCiYeH         fd_table.write().close_on_exec();
69*876cb89eSGnoCiYeH 
70*876cb89eSGnoCiYeH         return Ok(());
71ab5c8ca4Slogin     }
72ab5c8ca4Slogin 
73ab5c8ca4Slogin     pub fn wait4(
741496ba7bSLoGin         pid: i64,
751496ba7bSLoGin         wstatus: *mut i32,
761496ba7bSLoGin         options: i32,
77ab5c8ca4Slogin         rusage: *mut c_void,
78ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
791496ba7bSLoGin         let mut _rusage_buf =
801496ba7bSLoGin             UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?;
811496ba7bSLoGin 
821496ba7bSLoGin         let mut wstatus_buf =
831496ba7bSLoGin             UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?;
841496ba7bSLoGin 
851496ba7bSLoGin         // 暂时不支持options选项
861496ba7bSLoGin         if options != 0 {
871496ba7bSLoGin             return Err(SystemError::EINVAL);
88ab5c8ca4Slogin         }
891496ba7bSLoGin 
901496ba7bSLoGin         let cur_pcb = ProcessManager::current_pcb();
911496ba7bSLoGin         let rd_childen = cur_pcb.children.read();
921496ba7bSLoGin 
931496ba7bSLoGin         if pid > 0 {
941496ba7bSLoGin             let pid = Pid(pid as usize);
951496ba7bSLoGin             let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone();
961496ba7bSLoGin             drop(rd_childen);
971496ba7bSLoGin 
981496ba7bSLoGin             // 获取退出码
991496ba7bSLoGin             if let ProcessState::Exited(status) = child_pcb.sched_info().state() {
1001496ba7bSLoGin                 if !wstatus.is_null() {
1011496ba7bSLoGin                     wstatus_buf.copy_one_to_user(&status, 0)?;
1021496ba7bSLoGin                 }
1031496ba7bSLoGin                 return Ok(pid.into());
1041496ba7bSLoGin             }
1051496ba7bSLoGin             // 等待指定进程
1061496ba7bSLoGin             child_pcb.wait_queue.sleep();
1071496ba7bSLoGin         } else if pid < -1 {
1081496ba7bSLoGin             // TODO 判断是否pgid == -pid(等待指定组任意进程)
1091496ba7bSLoGin             // 暂时不支持
1101496ba7bSLoGin             return Err(SystemError::EINVAL);
1111496ba7bSLoGin         } else if pid == 0 {
1121496ba7bSLoGin             // TODO 判断是否pgid == current_pgid(等待当前组任意进程)
1131496ba7bSLoGin             // 暂时不支持
1141496ba7bSLoGin             return Err(SystemError::EINVAL);
1151496ba7bSLoGin         } else {
1161496ba7bSLoGin             // 等待任意子进程(这两)
1171496ba7bSLoGin             let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
1181496ba7bSLoGin             for (pid, pcb) in rd_childen.iter() {
1191496ba7bSLoGin                 if pcb.sched_info().state().is_exited() {
1201496ba7bSLoGin                     if !wstatus.is_null() {
1211496ba7bSLoGin                         wstatus_buf.copy_one_to_user(&0, 0)?;
1221496ba7bSLoGin                     }
1231496ba7bSLoGin                     return Ok(pid.clone().into());
1241496ba7bSLoGin                 } else {
1251496ba7bSLoGin                     unsafe { pcb.wait_queue.sleep_without_schedule() };
1261496ba7bSLoGin                 }
1271496ba7bSLoGin             }
1281496ba7bSLoGin             drop(irq_guard);
1291496ba7bSLoGin             sched();
1301496ba7bSLoGin         }
1311496ba7bSLoGin 
1321496ba7bSLoGin         return Ok(0);
133ab5c8ca4Slogin     }
134ab5c8ca4Slogin 
135ab5c8ca4Slogin     /// # 退出进程
136ab5c8ca4Slogin     ///
137ab5c8ca4Slogin     /// ## 参数
138ab5c8ca4Slogin     ///
139ab5c8ca4Slogin     /// - status: 退出状态
140ab5c8ca4Slogin     pub fn exit(status: usize) -> ! {
1411496ba7bSLoGin         ProcessManager::exit(status);
142ab5c8ca4Slogin     }
143ab5c8ca4Slogin 
1441496ba7bSLoGin     /// @brief 获取当前进程的pid
1451496ba7bSLoGin     pub fn getpid() -> Result<Pid, SystemError> {
1461496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
1471496ba7bSLoGin         return Ok(current_pcb.pid());
1481496ba7bSLoGin     }
1491496ba7bSLoGin 
1501496ba7bSLoGin     /// @brief 获取指定进程的pgid
1511496ba7bSLoGin     ///
1521496ba7bSLoGin     /// @param pid 指定一个进程号
1531496ba7bSLoGin     ///
1541496ba7bSLoGin     /// @return 成功,指定进程的进程组id
1551496ba7bSLoGin     /// @return 错误,不存在该进程
1561496ba7bSLoGin     pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> {
1571496ba7bSLoGin         if pid == Pid(0) {
1581496ba7bSLoGin             let current_pcb = ProcessManager::current_pcb();
1591496ba7bSLoGin             pid = current_pcb.pid();
1601496ba7bSLoGin         }
1611496ba7bSLoGin         let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
1621496ba7bSLoGin         return Ok(target_proc.basic().pgid());
1631496ba7bSLoGin     }
1641496ba7bSLoGin     /// @brief 获取当前进程的父进程id
1651496ba7bSLoGin 
1661496ba7bSLoGin     /// 若为initproc则ppid设置为0
1671496ba7bSLoGin     pub fn getppid() -> Result<Pid, SystemError> {
1681496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
1691496ba7bSLoGin         return Ok(current_pcb.basic().ppid());
170ab5c8ca4Slogin     }
171ab5c8ca4Slogin }
172