xref: /DragonOS/kernel/src/process/syscall.rs (revision 1496ba7b24a5e6954291ca9643b9f3cec567479a)
1*1496ba7bSLoGin use core::ffi::c_void;
2ab5c8ca4Slogin 
3*1496ba7bSLoGin use alloc::{string::String, vec::Vec};
4*1496ba7bSLoGin 
5*1496ba7bSLoGin use super::{fork::CloneFlags, Pid, ProcessManager, ProcessState};
6ab5c8ca4Slogin use crate::{
7*1496ba7bSLoGin     arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch},
8*1496ba7bSLoGin     exception::InterruptArch,
9*1496ba7bSLoGin     filesystem::vfs::MAX_PATHLEN,
10*1496ba7bSLoGin     process::ProcessControlBlock,
11*1496ba7bSLoGin     syscall::{
12*1496ba7bSLoGin         user_access::{
13*1496ba7bSLoGin             check_and_clone_cstr, check_and_clone_cstr_array, UserBufferReader, UserBufferWriter,
14*1496ba7bSLoGin         },
15*1496ba7bSLoGin         Syscall, SystemError,
16*1496ba7bSLoGin     },
17ab5c8ca4Slogin };
18ab5c8ca4Slogin 
19ab5c8ca4Slogin impl Syscall {
20*1496ba7bSLoGin     pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
21*1496ba7bSLoGin         let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into());
22*1496ba7bSLoGin         return r;
23ab5c8ca4Slogin     }
24ab5c8ca4Slogin 
25*1496ba7bSLoGin     pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
26*1496ba7bSLoGin         ProcessManager::fork(
27*1496ba7bSLoGin             frame,
28*1496ba7bSLoGin             CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
29*1496ba7bSLoGin         )
30*1496ba7bSLoGin         .map(|pid| pid.into())
31ab5c8ca4Slogin     }
32ab5c8ca4Slogin 
33ab5c8ca4Slogin     pub fn execve(
34*1496ba7bSLoGin         path: *const u8,
35*1496ba7bSLoGin         argv: *const *const u8,
36*1496ba7bSLoGin         envp: *const *const u8,
37*1496ba7bSLoGin         frame: &mut TrapFrame,
38*1496ba7bSLoGin     ) -> Result<(), SystemError> {
39*1496ba7bSLoGin         // kdebug!(
40*1496ba7bSLoGin         //     "execve path: {:?}, argv: {:?}, envp: {:?}\n",
41*1496ba7bSLoGin         //     path,
42*1496ba7bSLoGin         //     argv,
43*1496ba7bSLoGin         //     envp
44*1496ba7bSLoGin         // );
45*1496ba7bSLoGin         if path.is_null() {
46*1496ba7bSLoGin             return Err(SystemError::EINVAL);
47*1496ba7bSLoGin         }
48*1496ba7bSLoGin 
49*1496ba7bSLoGin         let x = || {
50*1496ba7bSLoGin             let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
51*1496ba7bSLoGin             let argv: Vec<String> = check_and_clone_cstr_array(argv)?;
52*1496ba7bSLoGin             let envp: Vec<String> = check_and_clone_cstr_array(envp)?;
53*1496ba7bSLoGin             Ok((path, argv, envp))
54*1496ba7bSLoGin         };
55*1496ba7bSLoGin         let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x();
56*1496ba7bSLoGin         if let Err(e) = r {
57*1496ba7bSLoGin             panic!("Failed to execve: {:?}", e);
58*1496ba7bSLoGin         }
59*1496ba7bSLoGin         let (path, argv, envp) = r.unwrap();
60*1496ba7bSLoGin         ProcessManager::current_pcb()
61*1496ba7bSLoGin             .basic_mut()
62*1496ba7bSLoGin             .set_name(ProcessControlBlock::generate_name(&path, &argv));
63*1496ba7bSLoGin 
64*1496ba7bSLoGin         return Self::do_execve(path, argv, envp, frame);
65ab5c8ca4Slogin     }
66ab5c8ca4Slogin 
67ab5c8ca4Slogin     pub fn wait4(
68*1496ba7bSLoGin         pid: i64,
69*1496ba7bSLoGin         wstatus: *mut i32,
70*1496ba7bSLoGin         options: i32,
71ab5c8ca4Slogin         rusage: *mut c_void,
72ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
73*1496ba7bSLoGin         let mut _rusage_buf =
74*1496ba7bSLoGin             UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?;
75*1496ba7bSLoGin 
76*1496ba7bSLoGin         let mut wstatus_buf =
77*1496ba7bSLoGin             UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?;
78*1496ba7bSLoGin 
79*1496ba7bSLoGin         // 暂时不支持options选项
80*1496ba7bSLoGin         if options != 0 {
81*1496ba7bSLoGin             return Err(SystemError::EINVAL);
82ab5c8ca4Slogin         }
83*1496ba7bSLoGin 
84*1496ba7bSLoGin         let cur_pcb = ProcessManager::current_pcb();
85*1496ba7bSLoGin         let rd_childen = cur_pcb.children.read();
86*1496ba7bSLoGin 
87*1496ba7bSLoGin         if pid > 0 {
88*1496ba7bSLoGin             let pid = Pid(pid as usize);
89*1496ba7bSLoGin             let child_pcb = rd_childen.get(&pid).ok_or(SystemError::ECHILD)?.clone();
90*1496ba7bSLoGin             drop(rd_childen);
91*1496ba7bSLoGin 
92*1496ba7bSLoGin             // 获取退出码
93*1496ba7bSLoGin             if let ProcessState::Exited(status) = child_pcb.sched_info().state() {
94*1496ba7bSLoGin                 if !wstatus.is_null() {
95*1496ba7bSLoGin                     wstatus_buf.copy_one_to_user(&status, 0)?;
96*1496ba7bSLoGin                 }
97*1496ba7bSLoGin                 return Ok(pid.into());
98*1496ba7bSLoGin             }
99*1496ba7bSLoGin             // 等待指定进程
100*1496ba7bSLoGin             child_pcb.wait_queue.sleep();
101*1496ba7bSLoGin         } else if pid < -1 {
102*1496ba7bSLoGin             // TODO 判断是否pgid == -pid(等待指定组任意进程)
103*1496ba7bSLoGin             // 暂时不支持
104*1496ba7bSLoGin             return Err(SystemError::EINVAL);
105*1496ba7bSLoGin         } else if pid == 0 {
106*1496ba7bSLoGin             // TODO 判断是否pgid == current_pgid(等待当前组任意进程)
107*1496ba7bSLoGin             // 暂时不支持
108*1496ba7bSLoGin             return Err(SystemError::EINVAL);
109*1496ba7bSLoGin         } else {
110*1496ba7bSLoGin             // 等待任意子进程(这两)
111*1496ba7bSLoGin             let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
112*1496ba7bSLoGin             for (pid, pcb) in rd_childen.iter() {
113*1496ba7bSLoGin                 if pcb.sched_info().state().is_exited() {
114*1496ba7bSLoGin                     if !wstatus.is_null() {
115*1496ba7bSLoGin                         wstatus_buf.copy_one_to_user(&0, 0)?;
116*1496ba7bSLoGin                     }
117*1496ba7bSLoGin                     return Ok(pid.clone().into());
118*1496ba7bSLoGin                 } else {
119*1496ba7bSLoGin                     unsafe { pcb.wait_queue.sleep_without_schedule() };
120*1496ba7bSLoGin                 }
121*1496ba7bSLoGin             }
122*1496ba7bSLoGin             drop(irq_guard);
123*1496ba7bSLoGin             sched();
124*1496ba7bSLoGin         }
125*1496ba7bSLoGin 
126*1496ba7bSLoGin         return Ok(0);
127ab5c8ca4Slogin     }
128ab5c8ca4Slogin 
129ab5c8ca4Slogin     /// # 退出进程
130ab5c8ca4Slogin     ///
131ab5c8ca4Slogin     /// ## 参数
132ab5c8ca4Slogin     ///
133ab5c8ca4Slogin     /// - status: 退出状态
134ab5c8ca4Slogin     pub fn exit(status: usize) -> ! {
135*1496ba7bSLoGin         ProcessManager::exit(status);
136ab5c8ca4Slogin     }
137ab5c8ca4Slogin 
138*1496ba7bSLoGin     /// @brief 获取当前进程的pid
139*1496ba7bSLoGin     pub fn getpid() -> Result<Pid, SystemError> {
140*1496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
141*1496ba7bSLoGin         return Ok(current_pcb.pid());
142*1496ba7bSLoGin     }
143*1496ba7bSLoGin 
144*1496ba7bSLoGin     /// @brief 获取指定进程的pgid
145*1496ba7bSLoGin     ///
146*1496ba7bSLoGin     /// @param pid 指定一个进程号
147*1496ba7bSLoGin     ///
148*1496ba7bSLoGin     /// @return 成功,指定进程的进程组id
149*1496ba7bSLoGin     /// @return 错误,不存在该进程
150*1496ba7bSLoGin     pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> {
151*1496ba7bSLoGin         if pid == Pid(0) {
152*1496ba7bSLoGin             let current_pcb = ProcessManager::current_pcb();
153*1496ba7bSLoGin             pid = current_pcb.pid();
154*1496ba7bSLoGin         }
155*1496ba7bSLoGin         let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
156*1496ba7bSLoGin         return Ok(target_proc.basic().pgid());
157*1496ba7bSLoGin     }
158*1496ba7bSLoGin     /// @brief 获取当前进程的父进程id
159*1496ba7bSLoGin 
160*1496ba7bSLoGin     /// 若为initproc则ppid设置为0
161*1496ba7bSLoGin     pub fn getppid() -> Result<Pid, SystemError> {
162*1496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
163*1496ba7bSLoGin         return Ok(current_pcb.basic().ppid());
164ab5c8ca4Slogin     }
165ab5c8ca4Slogin }
166