xref: /DragonOS/kernel/src/process/syscall.rs (revision bf4a48994a2b284ee34aa49a66b4dec1b6ebc07c)
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,
11*bf4a4899SLoGin     exit::kernel_wait4,
12971462beSGnoCiYeH     fork::{CloneFlags, KernelCloneArgs},
130d9b7d92SLoGin     resource::{RLimit64, RLimitID, RUsage, RUsageWho},
14*bf4a4899SLoGin     KernelStack, Pid, ProcessManager,
15971462beSGnoCiYeH };
16ab5c8ca4Slogin use crate::{
17*bf4a4899SLoGin     arch::{interrupt::TrapFrame, MMArch},
180d9b7d92SLoGin     filesystem::{
190d9b7d92SLoGin         procfs::procfs_register_pid,
200d9b7d92SLoGin         vfs::{file::FileDescriptorVec, MAX_PATHLEN},
210d9b7d92SLoGin     },
22971462beSGnoCiYeH     include::bindings::bindings::verify_area,
230d9b7d92SLoGin     mm::{ucontext::UserStack, MemoryManagementArch, VirtAddr},
241496ba7bSLoGin     process::ProcessControlBlock,
25971462beSGnoCiYeH     sched::completion::Completion,
261496ba7bSLoGin     syscall::{
27*bf4a4899SLoGin         user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter},
281496ba7bSLoGin         Syscall, SystemError,
291496ba7bSLoGin     },
30ab5c8ca4Slogin };
31ab5c8ca4Slogin 
32ab5c8ca4Slogin impl Syscall {
331496ba7bSLoGin     pub fn fork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
341496ba7bSLoGin         let r = ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into());
351496ba7bSLoGin         return r;
36ab5c8ca4Slogin     }
37ab5c8ca4Slogin 
381496ba7bSLoGin     pub fn vfork(frame: &mut TrapFrame) -> Result<usize, SystemError> {
39*bf4a4899SLoGin         // 由于Linux vfork需要保证子进程先运行(除非子进程调用execve或者exit),
40*bf4a4899SLoGin         // 而我们目前没有实现这个特性,所以暂时使用fork代替vfork(linux文档表示这样也是也可以的)
41*bf4a4899SLoGin         Self::fork(frame)
42*bf4a4899SLoGin 
43*bf4a4899SLoGin         // 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏
44*bf4a4899SLoGin         // ProcessManager::fork(
45*bf4a4899SLoGin         //     frame,
46*bf4a4899SLoGin         //     CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
47*bf4a4899SLoGin         // )
48*bf4a4899SLoGin         // .map(|pid| pid.into())
49ab5c8ca4Slogin     }
50ab5c8ca4Slogin 
51ab5c8ca4Slogin     pub fn execve(
521496ba7bSLoGin         path: *const u8,
531496ba7bSLoGin         argv: *const *const u8,
541496ba7bSLoGin         envp: *const *const u8,
551496ba7bSLoGin         frame: &mut TrapFrame,
561496ba7bSLoGin     ) -> Result<(), SystemError> {
571496ba7bSLoGin         // kdebug!(
581496ba7bSLoGin         //     "execve path: {:?}, argv: {:?}, envp: {:?}\n",
591496ba7bSLoGin         //     path,
601496ba7bSLoGin         //     argv,
611496ba7bSLoGin         //     envp
621496ba7bSLoGin         // );
63971462beSGnoCiYeH         // kdebug!(
64971462beSGnoCiYeH         //     "before execve: strong count: {}",
65971462beSGnoCiYeH         //     Arc::strong_count(&ProcessManager::current_pcb())
66971462beSGnoCiYeH         // );
67971462beSGnoCiYeH 
681496ba7bSLoGin         if path.is_null() {
691496ba7bSLoGin             return Err(SystemError::EINVAL);
701496ba7bSLoGin         }
711496ba7bSLoGin 
721496ba7bSLoGin         let x = || {
731496ba7bSLoGin             let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
741496ba7bSLoGin             let argv: Vec<String> = check_and_clone_cstr_array(argv)?;
751496ba7bSLoGin             let envp: Vec<String> = check_and_clone_cstr_array(envp)?;
761496ba7bSLoGin             Ok((path, argv, envp))
771496ba7bSLoGin         };
781496ba7bSLoGin         let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x();
791496ba7bSLoGin         if let Err(e) = r {
801496ba7bSLoGin             panic!("Failed to execve: {:?}", e);
811496ba7bSLoGin         }
821496ba7bSLoGin         let (path, argv, envp) = r.unwrap();
831496ba7bSLoGin         ProcessManager::current_pcb()
841496ba7bSLoGin             .basic_mut()
851496ba7bSLoGin             .set_name(ProcessControlBlock::generate_name(&path, &argv));
861496ba7bSLoGin 
87876cb89eSGnoCiYeH         Self::do_execve(path, argv, envp, frame)?;
88876cb89eSGnoCiYeH 
89876cb89eSGnoCiYeH         // 关闭设置了O_CLOEXEC的文件描述符
90876cb89eSGnoCiYeH         let fd_table = ProcessManager::current_pcb().fd_table();
91876cb89eSGnoCiYeH         fd_table.write().close_on_exec();
92971462beSGnoCiYeH         // kdebug!(
93971462beSGnoCiYeH         //     "after execve: strong count: {}",
94971462beSGnoCiYeH         //     Arc::strong_count(&ProcessManager::current_pcb())
95971462beSGnoCiYeH         // );
96876cb89eSGnoCiYeH 
97876cb89eSGnoCiYeH         return Ok(());
98ab5c8ca4Slogin     }
99ab5c8ca4Slogin 
100ab5c8ca4Slogin     pub fn wait4(
1011496ba7bSLoGin         pid: i64,
1021496ba7bSLoGin         wstatus: *mut i32,
1031496ba7bSLoGin         options: i32,
104ab5c8ca4Slogin         rusage: *mut c_void,
105ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
106*bf4a4899SLoGin         let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?;
107*bf4a4899SLoGin 
108*bf4a4899SLoGin         let wstatus_buf = if wstatus.is_null() {
109*bf4a4899SLoGin             None
110*bf4a4899SLoGin         } else {
111*bf4a4899SLoGin             Some(UserBufferWriter::new(
112*bf4a4899SLoGin                 wstatus,
113*bf4a4899SLoGin                 core::mem::size_of::<i32>(),
114*bf4a4899SLoGin                 true,
115*bf4a4899SLoGin             )?)
116b7b843beSGnoCiYeH         };
117b7b843beSGnoCiYeH 
118*bf4a4899SLoGin         let mut tmp_rusage = if rusage.is_null() {
119*bf4a4899SLoGin             None
120*bf4a4899SLoGin         } else {
121*bf4a4899SLoGin             Some(RUsage::default())
122*bf4a4899SLoGin         };
1231496ba7bSLoGin 
124*bf4a4899SLoGin         let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?;
1251496ba7bSLoGin 
126*bf4a4899SLoGin         if !rusage.is_null() {
127*bf4a4899SLoGin             let mut rusage_buf = UserBufferWriter::new::<RUsage>(
128*bf4a4899SLoGin                 rusage as *mut RUsage,
129*bf4a4899SLoGin                 core::mem::size_of::<RUsage>(),
130*bf4a4899SLoGin                 true,
131b7b843beSGnoCiYeH             )?;
132*bf4a4899SLoGin             rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?;
1331496ba7bSLoGin         }
134*bf4a4899SLoGin         return Ok(r);
135ab5c8ca4Slogin     }
136ab5c8ca4Slogin 
137ab5c8ca4Slogin     /// # 退出进程
138ab5c8ca4Slogin     ///
139ab5c8ca4Slogin     /// ## 参数
140ab5c8ca4Slogin     ///
141ab5c8ca4Slogin     /// - status: 退出状态
142ab5c8ca4Slogin     pub fn exit(status: usize) -> ! {
1431496ba7bSLoGin         ProcessManager::exit(status);
144ab5c8ca4Slogin     }
145ab5c8ca4Slogin 
1461496ba7bSLoGin     /// @brief 获取当前进程的pid
1471496ba7bSLoGin     pub fn getpid() -> Result<Pid, SystemError> {
1481496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
149393f6915SLoGin         return Ok(current_pcb.tgid());
1501496ba7bSLoGin     }
1511496ba7bSLoGin 
1521496ba7bSLoGin     /// @brief 获取指定进程的pgid
1531496ba7bSLoGin     ///
1541496ba7bSLoGin     /// @param pid 指定一个进程号
1551496ba7bSLoGin     ///
1561496ba7bSLoGin     /// @return 成功,指定进程的进程组id
1571496ba7bSLoGin     /// @return 错误,不存在该进程
1581496ba7bSLoGin     pub fn getpgid(mut pid: Pid) -> Result<Pid, SystemError> {
1591496ba7bSLoGin         if pid == Pid(0) {
1601496ba7bSLoGin             let current_pcb = ProcessManager::current_pcb();
1611496ba7bSLoGin             pid = current_pcb.pid();
1621496ba7bSLoGin         }
1631496ba7bSLoGin         let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
1641496ba7bSLoGin         return Ok(target_proc.basic().pgid());
1651496ba7bSLoGin     }
1661496ba7bSLoGin     /// @brief 获取当前进程的父进程id
1671496ba7bSLoGin 
1681496ba7bSLoGin     /// 若为initproc则ppid设置为0
1691496ba7bSLoGin     pub fn getppid() -> Result<Pid, SystemError> {
1701496ba7bSLoGin         let current_pcb = ProcessManager::current_pcb();
1711496ba7bSLoGin         return Ok(current_pcb.basic().ppid());
172ab5c8ca4Slogin     }
173971462beSGnoCiYeH 
174971462beSGnoCiYeH     pub fn clone(
175971462beSGnoCiYeH         current_trapframe: &mut TrapFrame,
176971462beSGnoCiYeH         clone_args: KernelCloneArgs,
177971462beSGnoCiYeH     ) -> Result<usize, SystemError> {
178971462beSGnoCiYeH         let flags = clone_args.flags;
179971462beSGnoCiYeH 
180971462beSGnoCiYeH         let vfork = Arc::new(Completion::new());
181971462beSGnoCiYeH 
182971462beSGnoCiYeH         if flags.contains(CloneFlags::CLONE_PIDFD)
183971462beSGnoCiYeH             && flags.contains(CloneFlags::CLONE_PARENT_SETTID)
184971462beSGnoCiYeH         {
185971462beSGnoCiYeH             return Err(SystemError::EINVAL);
186971462beSGnoCiYeH         }
187971462beSGnoCiYeH 
188971462beSGnoCiYeH         let current_pcb = ProcessManager::current_pcb();
189971462beSGnoCiYeH         let new_kstack = KernelStack::new()?;
190971462beSGnoCiYeH         let name = current_pcb.basic().name().to_string();
191971462beSGnoCiYeH         let pcb = ProcessControlBlock::new(name, new_kstack);
192971462beSGnoCiYeH         // 克隆pcb
193971462beSGnoCiYeH         ProcessManager::copy_process(&current_pcb, &pcb, clone_args, current_trapframe)?;
194971462beSGnoCiYeH         ProcessManager::add_pcb(pcb.clone());
195971462beSGnoCiYeH 
196971462beSGnoCiYeH         // 向procfs注册进程
197971462beSGnoCiYeH         procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
198971462beSGnoCiYeH             panic!(
199971462beSGnoCiYeH                 "fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
200971462beSGnoCiYeH                 pcb.pid(),
201971462beSGnoCiYeH                 e
202971462beSGnoCiYeH             )
203971462beSGnoCiYeH         });
204971462beSGnoCiYeH 
205971462beSGnoCiYeH         if flags.contains(CloneFlags::CLONE_VFORK) {
206971462beSGnoCiYeH             pcb.thread.write().vfork_done = Some(vfork.clone());
207971462beSGnoCiYeH         }
208971462beSGnoCiYeH 
209971462beSGnoCiYeH         if pcb.thread.read().set_child_tid.is_some() {
210971462beSGnoCiYeH             let addr = pcb.thread.read().set_child_tid.unwrap();
211971462beSGnoCiYeH             let mut writer =
212971462beSGnoCiYeH                 UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
213971462beSGnoCiYeH             writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
214971462beSGnoCiYeH         }
215971462beSGnoCiYeH 
216971462beSGnoCiYeH         ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
217971462beSGnoCiYeH             panic!(
218971462beSGnoCiYeH                 "fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
219971462beSGnoCiYeH                 pcb.pid(),
220971462beSGnoCiYeH                 e
221971462beSGnoCiYeH             )
222971462beSGnoCiYeH         });
223971462beSGnoCiYeH 
224971462beSGnoCiYeH         if flags.contains(CloneFlags::CLONE_VFORK) {
225971462beSGnoCiYeH             // 等待子进程结束或者exec;
226971462beSGnoCiYeH             vfork.wait_for_completion_interruptible()?;
227971462beSGnoCiYeH         }
228971462beSGnoCiYeH 
229971462beSGnoCiYeH         return Ok(pcb.pid().0);
230971462beSGnoCiYeH     }
231971462beSGnoCiYeH 
232971462beSGnoCiYeH     /// 设置线程地址
233971462beSGnoCiYeH     pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> {
234971462beSGnoCiYeH         if !unsafe { verify_area(ptr as u64, core::mem::size_of::<i32>() as u64) } {
235971462beSGnoCiYeH             return Err(SystemError::EFAULT);
236971462beSGnoCiYeH         }
237971462beSGnoCiYeH 
238971462beSGnoCiYeH         let pcb = ProcessManager::current_pcb();
239971462beSGnoCiYeH         pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr));
240971462beSGnoCiYeH         Ok(pcb.pid.0)
241971462beSGnoCiYeH     }
242393f6915SLoGin 
243393f6915SLoGin     pub fn gettid() -> Result<Pid, SystemError> {
244393f6915SLoGin         let pcb = ProcessManager::current_pcb();
245393f6915SLoGin         Ok(pcb.pid)
246393f6915SLoGin     }
24702e249f3SLoGin 
24802e249f3SLoGin     pub fn getuid() -> Result<usize, SystemError> {
24902e249f3SLoGin         // todo: 增加credit功能之后,需要修改
25002e249f3SLoGin         return Ok(0);
25102e249f3SLoGin     }
25202e249f3SLoGin 
25302e249f3SLoGin     pub fn getgid() -> Result<usize, SystemError> {
25402e249f3SLoGin         // todo: 增加credit功能之后,需要修改
25502e249f3SLoGin         return Ok(0);
25602e249f3SLoGin     }
25702e249f3SLoGin 
25802e249f3SLoGin     pub fn geteuid() -> Result<usize, SystemError> {
25902e249f3SLoGin         // todo: 增加credit功能之后,需要修改
26002e249f3SLoGin         return Ok(0);
26102e249f3SLoGin     }
26202e249f3SLoGin 
26302e249f3SLoGin     pub fn getegid() -> Result<usize, SystemError> {
26402e249f3SLoGin         // todo: 增加credit功能之后,需要修改
26502e249f3SLoGin         return Ok(0);
26602e249f3SLoGin     }
267be8cdf4bSLoGin 
268be8cdf4bSLoGin     pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> {
269be8cdf4bSLoGin         let who = RUsageWho::try_from(who)?;
270be8cdf4bSLoGin         let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?;
271be8cdf4bSLoGin         let pcb = ProcessManager::current_pcb();
272be8cdf4bSLoGin         let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?;
273be8cdf4bSLoGin 
274be8cdf4bSLoGin         let ubuf = writer.buffer::<RUsage>(0).unwrap();
275be8cdf4bSLoGin         ubuf.copy_from_slice(&[rusage]);
276be8cdf4bSLoGin 
277be8cdf4bSLoGin         return Ok(0);
278be8cdf4bSLoGin     }
2790d9b7d92SLoGin 
2800d9b7d92SLoGin     /// # 设置资源限制
2810d9b7d92SLoGin     ///
2820d9b7d92SLoGin     /// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能
2830d9b7d92SLoGin     ///
2840d9b7d92SLoGin     /// ## 参数
2850d9b7d92SLoGin     ///
2860d9b7d92SLoGin     /// - pid: 进程号
2870d9b7d92SLoGin     /// - resource: 资源类型
2880d9b7d92SLoGin     /// - new_limit: 新的资源限制
2890d9b7d92SLoGin     /// - old_limit: 旧的资源限制
2900d9b7d92SLoGin     ///
2910d9b7d92SLoGin     /// ## 返回值
2920d9b7d92SLoGin     ///
2930d9b7d92SLoGin     /// - 成功,0
2940d9b7d92SLoGin     /// - 如果old_limit不为NULL,则返回旧的资源限制到old_limit
2950d9b7d92SLoGin     ///
2960d9b7d92SLoGin     pub fn prlimit64(
2970d9b7d92SLoGin         _pid: Pid,
2980d9b7d92SLoGin         resource: usize,
299*bf4a4899SLoGin         _new_limit: *const RLimit64,
3000d9b7d92SLoGin         old_limit: *mut RLimit64,
3010d9b7d92SLoGin     ) -> Result<usize, SystemError> {
3020d9b7d92SLoGin         let resource = RLimitID::try_from(resource)?;
3030d9b7d92SLoGin         let mut writer = None;
3040d9b7d92SLoGin 
3050d9b7d92SLoGin         if !old_limit.is_null() {
3060d9b7d92SLoGin             writer = Some(UserBufferWriter::new(
3070d9b7d92SLoGin                 old_limit,
3080d9b7d92SLoGin                 core::mem::size_of::<RLimit64>(),
3090d9b7d92SLoGin                 true,
3100d9b7d92SLoGin             )?);
3110d9b7d92SLoGin         }
3120d9b7d92SLoGin 
3130d9b7d92SLoGin         match resource {
3140d9b7d92SLoGin             RLimitID::Stack => {
3150d9b7d92SLoGin                 if let Some(mut writer) = writer {
3160d9b7d92SLoGin                     let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
3170d9b7d92SLoGin                     rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64;
3180d9b7d92SLoGin                     rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64;
3190d9b7d92SLoGin                 }
3200d9b7d92SLoGin                 return Ok(0);
3210d9b7d92SLoGin             }
3220d9b7d92SLoGin 
3230d9b7d92SLoGin             RLimitID::Nofile => {
3240d9b7d92SLoGin                 if let Some(mut writer) = writer {
3250d9b7d92SLoGin                     let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
3260d9b7d92SLoGin                     rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64;
3270d9b7d92SLoGin                     rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64;
3280d9b7d92SLoGin                 }
3290d9b7d92SLoGin                 return Ok(0);
3300d9b7d92SLoGin             }
3310d9b7d92SLoGin 
3320d9b7d92SLoGin             RLimitID::As | RLimitID::Rss => {
3330d9b7d92SLoGin                 if let Some(mut writer) = writer {
3340d9b7d92SLoGin                     let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
3350d9b7d92SLoGin                     rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64;
3360d9b7d92SLoGin                     rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64;
3370d9b7d92SLoGin                 }
3380d9b7d92SLoGin                 return Ok(0);
3390d9b7d92SLoGin             }
3400d9b7d92SLoGin 
3410d9b7d92SLoGin             _ => {
3420d9b7d92SLoGin                 return Err(SystemError::ENOSYS);
3430d9b7d92SLoGin             }
3440d9b7d92SLoGin         }
3450d9b7d92SLoGin     }
346ab5c8ca4Slogin }
347