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