xref: /DragonOS/kernel/src/ipc/syscall.rs (revision aa0367d69e15989684109c5b454e85da9ecb1975)
1 use core::{
2     ffi::{c_int, c_void},
3     sync::atomic::compiler_fence,
4 };
5 
6 use crate::{
7     arch::asm::current::current_pcb,
8     filesystem::vfs::file::{File, FileMode},
9     include::bindings::bindings::{pid_t, verify_area, NULL},
10     kwarn,
11     syscall::{Syscall, SystemError},
12 };
13 
14 use super::{
15     pipe::LockedPipeInode,
16     signal::{signal_kill_something_info, DEFAULT_SIGACTION, DEFAULT_SIGACTION_IGNORE},
17     signal_types::{
18         SignalNumber, __siginfo_union, __siginfo_union_data, si_code_val, sigaction,
19         sigaction__union_u, siginfo, sigset_init, sigset_t, user_sigaction, SA_FLAG_DFL,
20         SA_FLAG_IGN, SA_FLAG_RESTORER, USER_SIG_DFL, USER_SIG_IGN,
21     },
22 };
23 
24 impl Syscall {
25     /// # 创建匿名管道
26     ///
27     /// ## 参数
28     ///
29     /// - `fd`: 用于返回文件描述符的数组
30     pub fn pipe(fd: &mut [i32]) -> Result<usize, SystemError> {
31         let pipe_ptr = LockedPipeInode::new();
32         let read_file = File::new(pipe_ptr.clone(), FileMode::O_RDONLY)?;
33         let write_file = File::new(pipe_ptr.clone(), FileMode::O_WRONLY)?;
34 
35         let read_fd = current_pcb().alloc_fd(read_file, None)?;
36         let write_fd = current_pcb().alloc_fd(write_file, None)?;
37 
38         fd[0] = read_fd;
39         fd[1] = write_fd;
40 
41         return Ok(0);
42     }
43 
44     pub fn kill(pid: pid_t, sig: c_int) -> Result<usize, SystemError> {
45         let sig = SignalNumber::from(sig);
46         if sig == SignalNumber::INVALID {
47             // 传入的signal数值不合法
48             kwarn!("Not a valid signal number");
49             return Err(SystemError::EINVAL);
50         }
51 
52         // 初始化signal info
53         let mut info = siginfo {
54             _sinfo: __siginfo_union {
55                 data: __siginfo_union_data {
56                     si_signo: sig as i32,
57                     si_code: si_code_val::SI_USER as i32,
58                     si_errno: 0,
59                     reserved: 0,
60                     _sifields: super::signal_types::__sifields {
61                         _kill: super::signal_types::__sifields__kill { _pid: pid },
62                     },
63                 },
64             },
65         };
66         compiler_fence(core::sync::atomic::Ordering::SeqCst);
67 
68         let retval = signal_kill_something_info(sig, Some(&mut info), pid).map(|x| x as usize);
69 
70         compiler_fence(core::sync::atomic::Ordering::SeqCst);
71 
72         return retval;
73     }
74 
75     /// @brief 用户程序用于设置信号处理动作的函数(遵循posix2008)
76     ///
77     /// @param regs->r8 signumber 信号的编号
78     /// @param regs->r9 act 新的,将要被设置的sigaction
79     /// @param regs->r10 oact 返回给用户的原本的sigaction(内核将原本的sigaction的值拷贝给这个地址)
80     ///
81     /// @return int 错误码
82     #[no_mangle]
83     pub fn sigaction(
84         sig: c_int,
85         act: usize,
86         old_act: usize,
87         _from_user: bool,
88     ) -> Result<usize, SystemError> {
89         // 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
90         let act = act as *mut user_sigaction;
91         let mut old_act = old_act as *mut user_sigaction;
92         let mut new_ka: sigaction = Default::default();
93         let mut old_ka: sigaction = Default::default();
94 
95         // 如果传入的,新的sigaction不为空
96         if !act.is_null() {
97             // 如果参数的范围不在用户空间,则返回错误
98             if unsafe {
99                 !verify_area(
100                     act as usize as u64,
101                     core::mem::size_of::<sigaction>() as u64,
102                 )
103             } {
104                 return Err(SystemError::EFAULT);
105             }
106             let mask: sigset_t = unsafe { (*act).sa_mask };
107             let _input_sah = unsafe { (*act).sa_handler as u64 };
108             // kdebug!("_input_sah={}", _input_sah);
109             match _input_sah {
110                 USER_SIG_DFL | USER_SIG_IGN => {
111                     if _input_sah == USER_SIG_DFL {
112                         new_ka = DEFAULT_SIGACTION;
113                         new_ka.sa_flags = (unsafe { (*act).sa_flags }
114                             & (!(SA_FLAG_DFL | SA_FLAG_IGN)))
115                             | SA_FLAG_DFL;
116                     } else {
117                         new_ka = DEFAULT_SIGACTION_IGNORE;
118                         new_ka.sa_flags = (unsafe { (*act).sa_flags }
119                             & (!(SA_FLAG_DFL | SA_FLAG_IGN)))
120                             | SA_FLAG_IGN;
121                     }
122 
123                     let sar = unsafe { (*act).sa_restorer };
124                     new_ka.sa_restorer = sar as u64;
125                 }
126                 _ => {
127                     // 从用户空间获得sigaction结构体
128                     new_ka = sigaction {
129                         _u: sigaction__union_u {
130                             _sa_handler: unsafe { (*act).sa_handler as u64 },
131                         },
132                         sa_flags: unsafe { (*act).sa_flags },
133                         sa_mask: sigset_t::default(),
134                         sa_restorer: unsafe { (*act).sa_restorer as u64 },
135                     };
136                 }
137             }
138             // kdebug!("new_ka={:?}", new_ka);
139             // 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
140             if new_ka.sa_restorer != NULL as u64 {
141                 new_ka.sa_flags |= SA_FLAG_RESTORER;
142             } else {
143                 kwarn!(
144                 "pid:{}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
145                 current_pcb().pid,
146                 sig
147             );
148             }
149             sigset_init(&mut new_ka.sa_mask, mask);
150         }
151 
152         let sig = SignalNumber::from(sig as i32);
153         // 如果给出的信号值不合法
154         if sig == SignalNumber::INVALID {
155             return Err(SystemError::EINVAL);
156         }
157 
158         let retval = super::signal::do_sigaction(
159             sig,
160             if act.is_null() {
161                 None
162             } else {
163                 Some(&mut new_ka)
164             },
165             if old_act.is_null() {
166                 None
167             } else {
168                 Some(&mut old_ka)
169             },
170         );
171 
172         // 将原本的sigaction拷贝到用户程序指定的地址
173         if (retval == Ok(())) && (!old_act.is_null()) {
174             if unsafe {
175                 !verify_area(
176                     old_act as usize as u64,
177                     core::mem::size_of::<sigaction>() as u64,
178                 )
179             } {
180                 return Err(SystemError::EFAULT);
181             }
182             // !!!!!!!!!!todo: 检查这里old_ka的mask,是否位SIG_IGN SIG_DFL,如果是,则将_sa_handler字段替换为对应的值
183             let sah: u64;
184             let flag = old_ka.sa_flags & (SA_FLAG_DFL | SA_FLAG_IGN);
185             match flag {
186                 SA_FLAG_DFL => {
187                     sah = USER_SIG_DFL;
188                 }
189                 SA_FLAG_IGN => {
190                     sah = USER_SIG_IGN;
191                 }
192                 _ => sah = unsafe { old_ka._u._sa_handler },
193             }
194             unsafe {
195                 (*old_act).sa_handler = sah as *mut c_void;
196                 (*old_act).sa_flags = old_ka.sa_flags;
197                 (*old_act).sa_mask = old_ka.sa_mask;
198                 (*old_act).sa_restorer = old_ka.sa_restorer as *mut c_void;
199             }
200         }
201         return retval.map(|_| 0);
202     }
203 }
204