xref: /DragonOS/kernel/src/process/syscall.rs (revision be8cdf4b8edcd9579572672411f4489039dea313)
11496ba7bSLoGin use core::ffi::c_void;
2ab5c8ca4Slogin 
3971462beSGnoCiYeH use alloc::{
4971462beSGnoCiYeH     string::{String, ToString},
5971462beSGnoCiYeH     sync::Arc,
6971462beSGnoCiYeH     vec::Vec,
7971462beSGnoCiYeH };
81496ba7bSLoGin 
9971462beSGnoCiYeH use super::{
10971462beSGnoCiYeH     abi::WaitOption,
11971462beSGnoCiYeH     fork::{CloneFlags, KernelCloneArgs},
12*be8cdf4bSLoGin     resource::{RUsage, RUsageWho},
13971462beSGnoCiYeH     KernelStack, Pid, ProcessManager, ProcessState,
14971462beSGnoCiYeH };
15ab5c8ca4Slogin use crate::{
161496ba7bSLoGin     arch::{interrupt::TrapFrame, sched::sched, CurrentIrqArch},
171496ba7bSLoGin     exception::InterruptArch,
18971462beSGnoCiYeH     filesystem::{procfs::procfs_register_pid, vfs::MAX_PATHLEN},
19971462beSGnoCiYeH     include::bindings::bindings::verify_area,
20971462beSGnoCiYeH     mm::VirtAddr,
211496ba7bSLoGin     process::ProcessControlBlock,
22971462beSGnoCiYeH     sched::completion::Completion,
231496ba7bSLoGin     syscall::{
241496ba7bSLoGin         user_access::{
251496ba7bSLoGin             check_and_clone_cstr, check_and_clone_cstr_array, UserBufferReader, UserBufferWriter,
261496ba7bSLoGin         },
271496ba7bSLoGin         Syscall, SystemError,
281496ba7bSLoGin     },
29ab5c8ca4Slogin };
30ab5c8ca4Slogin 
31ab5c8ca4Slogin impl Syscall {
321496ba7bSLoGin     pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
331496ba7bSLoGin         let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into());
341496ba7bSLoGin         return r;
35ab5c8ca4Slogin     }
36ab5c8ca4Slogin 
371496ba7bSLoGin     pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
381496ba7bSLoGin         ProcessManager::fork(
391496ba7bSLoGin             frame,
401496ba7bSLoGin             CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
411496ba7bSLoGin         )
421496ba7bSLoGin         .map(|pid| pid.into())
43ab5c8ca4Slogin     }
44ab5c8ca4Slogin 
45ab5c8ca4Slogin     pub fn execve(
461496ba7bSLoGin         path: *const u8,
471496ba7bSLoGin         argv: *const *const u8,
481496ba7bSLoGin         envp: *const *const u8,
491496ba7bSLoGin         frame: &mut TrapFrame,
501496ba7bSLoGin     ) -> Result<(), SystemError> {
511496ba7bSLoGin         // kdebug!(
521496ba7bSLoGin         //     "execve path: {:?}, argv: {:?}, envp: {:?}\n",
531496ba7bSLoGin         //     path,
541496ba7bSLoGin         //     argv,
551496ba7bSLoGin         //     envp
561496ba7bSLoGin         // );
57971462beSGnoCiYeH         // kdebug!(
58971462beSGnoCiYeH         //     "before execve: strong count: {}",
59971462beSGnoCiYeH         //     Arc::strong_count(&ProcessManager::current_pcb())
60971462beSGnoCiYeH         // );
61971462beSGnoCiYeH 
621496ba7bSLoGin         if path.is_null() {
631496ba7bSLoGin             return Err(SystemError::EINVAL);
641496ba7bSLoGin         }
651496ba7bSLoGin 
661496ba7bSLoGin         let x = || {
671496ba7bSLoGin             let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
681496ba7bSLoGin             let argv: Vec<String> = check_and_clone_cstr_array(argv)?;
691496ba7bSLoGin             let envp: Vec<String> = check_and_clone_cstr_array(envp)?;
701496ba7bSLoGin             Ok((path, argv, envp))
711496ba7bSLoGin         };
721496ba7bSLoGin         let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x();
731496ba7bSLoGin         if let Err(e) = r {
741496ba7bSLoGin             panic!("Failed to execve: {:?}", e);
751496ba7bSLoGin         }
761496ba7bSLoGin         let (path, argv, envp) = r.unwrap();
771496ba7bSLoGin         ProcessManager::current_pcb()
781496ba7bSLoGin             .basic_mut()
791496ba7bSLoGin             .set_name(ProcessControlBlock::generate_name(&path, &argv));
801496ba7bSLoGin 
81876cb89eSGnoCiYeH         Self::do_execve(path, argv, envp, frame)?;
82876cb89eSGnoCiYeH 
83876cb89eSGnoCiYeH         // 关闭设置了O_CLOEXEC的文件描述符
84876cb89eSGnoCiYeH         let fd_table = ProcessManager::current_pcb().fd_table();
85876cb89eSGnoCiYeH         fd_table.write().close_on_exec();
86971462beSGnoCiYeH         // kdebug!(
87971462beSGnoCiYeH         //     "after execve: strong count: {}",
88971462beSGnoCiYeH         //     Arc::strong_count(&ProcessManager::current_pcb())
89971462beSGnoCiYeH         // );
90876cb89eSGnoCiYeH 
91876cb89eSGnoCiYeH         return Ok(());
92ab5c8ca4Slogin     }
93ab5c8ca4Slogin 
94ab5c8ca4Slogin     pub fn wait4(
951496ba7bSLoGin         pid: i64,
961496ba7bSLoGin         wstatus: *mut i32,
971496ba7bSLoGin         options: i32,
98ab5c8ca4Slogin         rusage: *mut c_void,
99ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
100b7b843beSGnoCiYeH         let ret = WaitOption::from_bits(options as u32);
101b7b843beSGnoCiYeH         let options = match ret {
102b7b843beSGnoCiYeH             Some(options) => options,
103b7b843beSGnoCiYeH             None => {
104b7b843beSGnoCiYeH                 return Err(SystemError::EINVAL);
105b7b843beSGnoCiYeH             }
106b7b843beSGnoCiYeH         };
107b7b843beSGnoCiYeH 
1081496ba7bSLoGin         let mut _rusage_buf =
1091496ba7bSLoGin             UserBufferReader::new::<c_void>(rusage, core::mem::size_of::<c_void>(), true)?;
1101496ba7bSLoGin 
1111496ba7bSLoGin         let mut wstatus_buf =
1121496ba7bSLoGin             UserBufferWriter::new::<i32>(wstatus, core::mem::size_of::<i32>(), true)?;
1131496ba7bSLoGin 
1141496ba7bSLoGin         let cur_pcb = ProcessManager::current_pcb();
1151496ba7bSLoGin         let rd_childen = cur_pcb.children.read();
1161496ba7bSLoGin 
1171496ba7bSLoGin         if pid > 0 {
1181496ba7bSLoGin             let pid = Pid(pid as usize);
119971462beSGnoCiYeH             let child_pcb = ProcessManager::find(pid).ok_or(SystemError::ECHILD)?;
1201496ba7bSLoGin             drop(rd_childen);
1211496ba7bSLoGin 
122b7b843beSGnoCiYeH             loop {
123971462beSGnoCiYeH                 let state = child_pcb.sched_info().state();
1241496ba7bSLoGin                 // 获取退出码
125971462beSGnoCiYeH                 match state {
126b7b843beSGnoCiYeH                     ProcessState::Runnable => {
127b7b843beSGnoCiYeH                         if options.contains(WaitOption::WNOHANG)
128b7b843beSGnoCiYeH                             || options.contains(WaitOption::WNOWAIT)
129b7b843beSGnoCiYeH                         {
1301496ba7bSLoGin                             if !wstatus.is_null() {
131b7b843beSGnoCiYeH                                 wstatus_buf.copy_one_to_user(&WaitOption::WCONTINUED.bits(), 0)?;
132b7b843beSGnoCiYeH                             }
133b7b843beSGnoCiYeH                             return Ok(0);
134b7b843beSGnoCiYeH                         }
135b7b843beSGnoCiYeH                     }
1363c82aa56SChiichen                     ProcessState::Blocked(_) | ProcessState::Stopped => {
137b7b843beSGnoCiYeH                         // 指定WUNTRACED则等待暂停的进程,不指定则返回0
138b7b843beSGnoCiYeH                         if !options.contains(WaitOption::WUNTRACED)
139b7b843beSGnoCiYeH                             || options.contains(WaitOption::WNOWAIT)
140b7b843beSGnoCiYeH                         {
141b7b843beSGnoCiYeH                             if !wstatus.is_null() {
142b7b843beSGnoCiYeH                                 wstatus_buf.copy_one_to_user(&WaitOption::WSTOPPED.bits(), 0)?;
143b7b843beSGnoCiYeH                             }
144b7b843beSGnoCiYeH                             return Ok(0);
145b7b843beSGnoCiYeH                         }
146b7b843beSGnoCiYeH                     }
147b7b843beSGnoCiYeH                     ProcessState::Exited(status) => {
148971462beSGnoCiYeH                         // kdebug!("wait4: child exited, pid: {:?}, status: {status}\n", pid);
149b7b843beSGnoCiYeH                         if !wstatus.is_null() {
150b7b843beSGnoCiYeH                             wstatus_buf.copy_one_to_user(
151971462beSGnoCiYeH                                 &(status as u32 | WaitOption::WEXITED.bits()),
152b7b843beSGnoCiYeH                                 0,
153b7b843beSGnoCiYeH                             )?;
1541496ba7bSLoGin                         }
155971462beSGnoCiYeH                         drop(child_pcb);
156971462beSGnoCiYeH                         // kdebug!("wait4: to release {pid:?}");
157971462beSGnoCiYeH                         unsafe { ProcessManager::release(pid) };
1581496ba7bSLoGin                         return Ok(pid.into());
1591496ba7bSLoGin                     }
160b7b843beSGnoCiYeH                 };
161b7b843beSGnoCiYeH 
1621496ba7bSLoGin                 // 等待指定进程
1631496ba7bSLoGin                 child_pcb.wait_queue.sleep();
164b7b843beSGnoCiYeH             }
1651496ba7bSLoGin         } else if pid < -1 {
1661496ba7bSLoGin             // TODO 判断是否pgid == -pid(等待指定组任意进程)
1671496ba7bSLoGin             // 暂时不支持
1681496ba7bSLoGin             return Err(SystemError::EINVAL);
1691496ba7bSLoGin         } else if pid == 0 {
1701496ba7bSLoGin             // TODO 判断是否pgid == current_pgid(等待当前组任意进程)
1711496ba7bSLoGin             // 暂时不支持
1721496ba7bSLoGin             return Err(SystemError::EINVAL);
1731496ba7bSLoGin         } else {
1741496ba7bSLoGin             // 等待任意子进程(这两)
1751496ba7bSLoGin             let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
176971462beSGnoCiYeH             for pid in rd_childen.iter() {
177971462beSGnoCiYeH                 let pcb = ProcessManager::find(*pid).ok_or(SystemError::ECHILD)?;
1781496ba7bSLoGin                 if pcb.sched_info().state().is_exited() {
1791496ba7bSLoGin                     if !wstatus.is_null() {
1801496ba7bSLoGin                         wstatus_buf.copy_one_to_user(&0, 0)?;
1811496ba7bSLoGin                     }
1821496ba7bSLoGin                     return Ok(pid.clone().into());
1831496ba7bSLoGin                 } else {
1841496ba7bSLoGin                     unsafe { pcb.wait_queue.sleep_without_schedule() };
1851496ba7bSLoGin                 }
1861496ba7bSLoGin             }
1871496ba7bSLoGin             drop(irq_guard);
1881496ba7bSLoGin             sched();
1891496ba7bSLoGin         }
1901496ba7bSLoGin 
1911496ba7bSLoGin         return Ok(0);
192ab5c8ca4Slogin     }
193ab5c8ca4Slogin 
194ab5c8ca4Slogin     /// # 退出进程
195ab5c8ca4Slogin     ///
196ab5c8ca4Slogin     /// ## 参数
197ab5c8ca4Slogin     ///
198ab5c8ca4Slogin     /// - status: 退出状态
199ab5c8ca4Slogin     pub fn exit(status: usize) -> ! {
2001496ba7bSLoGin         ProcessManager::exit(status);
201ab5c8ca4Slogin     }
202ab5c8ca4Slogin 
2031496ba7bSLoGin     /// @brief 获取当前进程的pid
2041496ba7bSLoGin     pub fn getpid() -> Result<Pid, SystemError> {
2051496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
206393f6915SLoGin         return Ok(current_pcb.tgid());
2071496ba7bSLoGin     }
2081496ba7bSLoGin 
2091496ba7bSLoGin     /// @brief 获取指定进程的pgid
2101496ba7bSLoGin     ///
2111496ba7bSLoGin     /// @param pid 指定一个进程号
2121496ba7bSLoGin     ///
2131496ba7bSLoGin     /// @return 成功,指定进程的进程组id
2141496ba7bSLoGin     /// @return 错误,不存在该进程
2151496ba7bSLoGin     pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> {
2161496ba7bSLoGin         if pid == Pid(0) {
2171496ba7bSLoGin             let current_pcb = ProcessManager::current_pcb();
2181496ba7bSLoGin             pid = current_pcb.pid();
2191496ba7bSLoGin         }
2201496ba7bSLoGin         let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
2211496ba7bSLoGin         return Ok(target_proc.basic().pgid());
2221496ba7bSLoGin     }
2231496ba7bSLoGin     /// @brief 获取当前进程的父进程id
2241496ba7bSLoGin 
2251496ba7bSLoGin     /// 若为initproc则ppid设置为0
2261496ba7bSLoGin     pub fn getppid() -> Result<Pid, SystemError> {
2271496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
2281496ba7bSLoGin         return Ok(current_pcb.basic().ppid());
229ab5c8ca4Slogin     }
230971462beSGnoCiYeH 
231971462beSGnoCiYeH     pub fn clone(
232971462beSGnoCiYeH         current_trapframe: &mut TrapFrame,
233971462beSGnoCiYeH         clone_args: KernelCloneArgs,
234971462beSGnoCiYeH     ) -> Result<usize, SystemError> {
235971462beSGnoCiYeH         let flags = clone_args.flags;
236971462beSGnoCiYeH 
237971462beSGnoCiYeH         let vfork = Arc::new(Completion::new());
238971462beSGnoCiYeH 
239971462beSGnoCiYeH         if flags.contains(CloneFlags::CLONE_PIDFD)
240971462beSGnoCiYeH             && flags.contains(CloneFlags::CLONE_PARENT_SETTID)
241971462beSGnoCiYeH         {
242971462beSGnoCiYeH             return Err(SystemError::EINVAL);
243971462beSGnoCiYeH         }
244971462beSGnoCiYeH 
245971462beSGnoCiYeH         let current_pcb = ProcessManager::current_pcb();
246971462beSGnoCiYeH         let new_kstack = KernelStack::new()?;
247971462beSGnoCiYeH         let name = current_pcb.basic().name().to_string();
248971462beSGnoCiYeH         let pcb = ProcessControlBlock::new(name, new_kstack);
249971462beSGnoCiYeH         // 克隆pcb
250971462beSGnoCiYeH         ProcessManager::copy_process(&current_pcb, &pcb, clone_args, current_trapframe)?;
251971462beSGnoCiYeH         ProcessManager::add_pcb(pcb.clone());
252971462beSGnoCiYeH 
253971462beSGnoCiYeH         // 向procfs注册进程
254971462beSGnoCiYeH         procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
255971462beSGnoCiYeH             panic!(
256971462beSGnoCiYeH                 "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
257971462beSGnoCiYeH                 pcb.pid(),
258971462beSGnoCiYeH                 e
259971462beSGnoCiYeH             )
260971462beSGnoCiYeH         });
261971462beSGnoCiYeH 
262971462beSGnoCiYeH         if flags.contains(CloneFlags::CLONE_VFORK) {
263971462beSGnoCiYeH             pcb.thread.write().vfork_done = Some(vfork.clone());
264971462beSGnoCiYeH         }
265971462beSGnoCiYeH 
266971462beSGnoCiYeH         if pcb.thread.read().set_child_tid.is_some() {
267971462beSGnoCiYeH             let addr = pcb.thread.read().set_child_tid.unwrap();
268971462beSGnoCiYeH             let mut writer =
269971462beSGnoCiYeH                 UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
270971462beSGnoCiYeH             writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
271971462beSGnoCiYeH         }
272971462beSGnoCiYeH 
273971462beSGnoCiYeH         ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
274971462beSGnoCiYeH             panic!(
275971462beSGnoCiYeH                 "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
276971462beSGnoCiYeH                 pcb.pid(),
277971462beSGnoCiYeH                 e
278971462beSGnoCiYeH             )
279971462beSGnoCiYeH         });
280971462beSGnoCiYeH 
281971462beSGnoCiYeH         if flags.contains(CloneFlags::CLONE_VFORK) {
282971462beSGnoCiYeH             // 等待子进程结束或者exec;
283971462beSGnoCiYeH             vfork.wait_for_completion_interruptible()?;
284971462beSGnoCiYeH         }
285971462beSGnoCiYeH 
286971462beSGnoCiYeH         return Ok(pcb.pid().0);
287971462beSGnoCiYeH     }
288971462beSGnoCiYeH 
289971462beSGnoCiYeH     /// 设置线程地址
290971462beSGnoCiYeH     pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> {
291971462beSGnoCiYeH         if !unsafe { verify_area(ptr as u64, core::mem::size_of::<i32>() as u64) } {
292971462beSGnoCiYeH             return Err(SystemError::EFAULT);
293971462beSGnoCiYeH         }
294971462beSGnoCiYeH 
295971462beSGnoCiYeH         let pcb = ProcessManager::current_pcb();
296971462beSGnoCiYeH         pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr));
297971462beSGnoCiYeH         Ok(pcb.pid.0)
298971462beSGnoCiYeH     }
299393f6915SLoGin 
300393f6915SLoGin     pub fn gettid() -> Result<Pid, SystemError> {
301393f6915SLoGin         let pcb = ProcessManager::current_pcb();
302393f6915SLoGin         Ok(pcb.pid)
303393f6915SLoGin     }
30402e249f3SLoGin 
30502e249f3SLoGin     pub fn getuid() -> Result<usize, SystemError> {
30602e249f3SLoGin         // todo: 增加credit功能之后,需要修改
30702e249f3SLoGin         return Ok(0);
30802e249f3SLoGin     }
30902e249f3SLoGin 
31002e249f3SLoGin     pub fn getgid() -> Result<usize, SystemError> {
31102e249f3SLoGin         // todo: 增加credit功能之后,需要修改
31202e249f3SLoGin         return Ok(0);
31302e249f3SLoGin     }
31402e249f3SLoGin 
31502e249f3SLoGin     pub fn geteuid() -> Result<usize, SystemError> {
31602e249f3SLoGin         // todo: 增加credit功能之后,需要修改
31702e249f3SLoGin         return Ok(0);
31802e249f3SLoGin     }
31902e249f3SLoGin 
32002e249f3SLoGin     pub fn getegid() -> Result<usize, SystemError> {
32102e249f3SLoGin         // todo: 增加credit功能之后,需要修改
32202e249f3SLoGin         return Ok(0);
32302e249f3SLoGin     }
324*be8cdf4bSLoGin 
325*be8cdf4bSLoGin     pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> {
326*be8cdf4bSLoGin         let who = RUsageWho::try_from(who)?;
327*be8cdf4bSLoGin         let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?;
328*be8cdf4bSLoGin         let pcb = ProcessManager::current_pcb();
329*be8cdf4bSLoGin         let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?;
330*be8cdf4bSLoGin 
331*be8cdf4bSLoGin         let ubuf = writer.buffer::<RUsage>(0).unwrap();
332*be8cdf4bSLoGin         ubuf.copy_from_slice(&[rusage]);
333*be8cdf4bSLoGin 
334*be8cdf4bSLoGin         return Ok(0);
335*be8cdf4bSLoGin     }
336ab5c8ca4Slogin }
337