xref: /DragonOS/kernel/src/process/syscall.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
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         // debug!(
102         //     "execve path: {:?}, argv: {:?}, envp: {:?}\n",
103         //     path,
104         //     argv,
105         //     envp
106         // );
107         // debug!(
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         // debug!(
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(&current_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