xref: /DragonOS/kernel/src/ipc/syscall.rs (revision f2022a8a1cc4a8e2a85e9061e036e9c491a2fa00)
1 use core::{
2     ffi::{c_int, c_void},
3     sync::atomic::compiler_fence,
4 };
5 
6 use system_error::SystemError;
7 
8 use crate::{
9     arch::ipc::signal::{SigCode, SigFlags, SigSet, Signal},
10     filesystem::vfs::{
11         file::{File, FileMode},
12         FilePrivateData,
13     },
14     kerror, kwarn,
15     mm::VirtAddr,
16     process::{Pid, ProcessManager},
17     syscall::{user_access::UserBufferWriter, Syscall},
18 };
19 
20 use super::{
21     pipe::{LockedPipeInode, PipeFsPrivateData},
22     signal_types::{
23         SaHandlerType, SigInfo, SigType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL,
24         USER_SIG_ERR, USER_SIG_IGN,
25     },
26 };
27 
28 impl Syscall {
29     /// # 创建带参数的匿名管道
30     ///
31     /// ## 参数
32     ///
33     /// - `fd`: 用于返回文件描述符的数组
34     /// - `flags`:设置管道的参数
35     pub fn pipe2(fd: *mut i32, flags: FileMode) -> Result<usize, SystemError> {
36         if !flags
37             .difference(FileMode::O_CLOEXEC | FileMode::O_NONBLOCK | FileMode::O_DIRECT)
38             .is_empty()
39         {
40             return Err(SystemError::EINVAL);
41         }
42 
43         let mut user_buffer = UserBufferWriter::new(fd, core::mem::size_of::<[c_int; 2]>(), true)?;
44         let fd = user_buffer.buffer::<i32>(0)?;
45         let pipe_ptr = LockedPipeInode::new();
46 
47         let mut read_file = File::new(
48             pipe_ptr.clone(),
49             FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK),
50         )?;
51         read_file.private_data =
52             FilePrivateData::Pipefs(PipeFsPrivateData::new(FileMode::O_RDONLY));
53 
54         let mut write_file = File::new(
55             pipe_ptr.clone(),
56             FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
57         )?;
58         write_file.private_data = FilePrivateData::Pipefs(PipeFsPrivateData::new(
59             FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
60         ));
61 
62         if flags.contains(FileMode::O_CLOEXEC) {
63             read_file.set_close_on_exec(true);
64             write_file.set_close_on_exec(true);
65         }
66         let fd_table_ptr = ProcessManager::current_pcb().fd_table();
67         let mut fd_table_guard = fd_table_ptr.write();
68         let read_fd = fd_table_guard.alloc_fd(read_file, None)?;
69         let write_fd = fd_table_guard.alloc_fd(write_file, None)?;
70 
71         drop(fd_table_guard);
72 
73         fd[0] = read_fd;
74         fd[1] = write_fd;
75         Ok(0)
76     }
77 
78     pub fn kill(pid: Pid, sig: c_int) -> Result<usize, SystemError> {
79         let sig = Signal::from(sig);
80         if sig == Signal::INVALID {
81             // 传入的signal数值不合法
82             kwarn!("Not a valid signal number");
83             return Err(SystemError::EINVAL);
84         }
85 
86         // 初始化signal info
87         let mut info = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(pid));
88 
89         compiler_fence(core::sync::atomic::Ordering::SeqCst);
90 
91         let retval = sig
92             .send_signal_info(Some(&mut info), pid)
93             .map(|x| x as usize);
94 
95         compiler_fence(core::sync::atomic::Ordering::SeqCst);
96 
97         return retval;
98     }
99 
100     /// 通用信号注册函数
101     ///
102     /// ## 参数
103     ///
104     /// - `sig` 信号的值
105     /// - `act` 用户空间传入的 Sigaction 指针
106     /// - `old_act` 用户空间传入的用来保存旧 Sigaction 的指针
107     /// - `from_user` 用来标识这个函数调用是否来自用户空间
108     ///
109     /// @return int 错误码
110     #[no_mangle]
111     pub fn sigaction(
112         sig: c_int,
113         new_act: usize,
114         old_act: usize,
115         from_user: bool,
116     ) -> Result<usize, SystemError> {
117         // 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
118         let act: *mut UserSigaction = new_act as *mut UserSigaction;
119         let old_act = old_act as *mut UserSigaction;
120         let mut new_ka: Sigaction = Default::default();
121         let mut old_sigaction: Sigaction = Default::default();
122         // 如果传入的,新的sigaction不为空
123         if !act.is_null() {
124             // 如果参数的范围不在用户空间,则返回错误
125             let r = UserBufferWriter::new(act, core::mem::size_of::<Sigaction>(), from_user);
126             if r.is_err() {
127                 return Err(SystemError::EFAULT);
128             }
129             let mask: SigSet = unsafe { (*act).mask };
130             let input_sighandler = unsafe { (*act).handler as u64 };
131             match input_sighandler {
132                 USER_SIG_DFL => {
133                     new_ka = Sigaction::DEFAULT_SIGACTION.clone();
134                     *new_ka.flags_mut() = unsafe { (*act).flags };
135                     new_ka.set_restorer(None);
136                 }
137 
138                 USER_SIG_IGN => {
139                     new_ka = Sigaction::DEFAULT_SIGACTION_IGNORE.clone();
140                     *new_ka.flags_mut() = unsafe { (*act).flags };
141 
142                     new_ka.set_restorer(None);
143                 }
144                 _ => {
145                     // 从用户空间获得sigaction结构体
146                     // TODO mask是default还是用户空间传入
147                     new_ka = Sigaction::new(
148                         SigactionType::SaHandler(SaHandlerType::SigCustomized(unsafe {
149                             VirtAddr::new((*act).handler as usize)
150                         })),
151                         unsafe { (*act).flags },
152                         SigSet::default(),
153                         unsafe { Some(VirtAddr::new((*act).restorer as usize)) },
154                     );
155                 }
156             }
157 
158             // TODO 如果为空,赋默认值?
159             // kdebug!("new_ka={:?}", new_ka);
160             // 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
161             if new_ka.restorer().is_some() {
162                 new_ka.flags_mut().insert(SigFlags::SA_RESTORER);
163             } else if new_ka.action().is_customized() {
164                 kerror!(
165                 "pid:{:?}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
166                 ProcessManager::current_pcb().pid(),
167                 sig
168             );
169                 return Err(SystemError::EINVAL);
170             }
171             *new_ka.mask_mut() = mask;
172         }
173 
174         let sig = Signal::from(sig as i32);
175         // 如果给出的信号值不合法
176         if sig == Signal::INVALID {
177             return Err(SystemError::EINVAL);
178         }
179 
180         let retval = super::signal::do_sigaction(
181             sig,
182             if act.is_null() {
183                 None
184             } else {
185                 Some(&mut new_ka)
186             },
187             if old_act.is_null() {
188                 None
189             } else {
190                 Some(&mut old_sigaction)
191             },
192         );
193 
194         //
195         if (retval == Ok(())) && (!old_act.is_null()) {
196             let r =
197                 UserBufferWriter::new(old_act, core::mem::size_of::<UserSigaction>(), from_user);
198             if r.is_err() {
199                 return Err(SystemError::EFAULT);
200             }
201 
202             let sigaction_handler: VirtAddr;
203             sigaction_handler = match old_sigaction.action() {
204                 SigactionType::SaHandler(handler) => {
205                     if let SaHandlerType::SigCustomized(hand) = handler {
206                         hand
207                     } else if handler.is_sig_ignore() {
208                         VirtAddr::new(USER_SIG_IGN as usize)
209                     } else if handler.is_sig_error() {
210                         VirtAddr::new(USER_SIG_ERR as usize)
211                     } else {
212                         VirtAddr::new(USER_SIG_DFL as usize)
213                     }
214                 }
215                 SigactionType::SaSigaction(_) => {
216                     kerror!("unsupported type: SaSigaction");
217                     VirtAddr::new(USER_SIG_DFL as usize)
218                 }
219             };
220 
221             unsafe {
222                 (*old_act).handler = sigaction_handler.data() as *mut c_void;
223                 (*old_act).flags = old_sigaction.flags();
224                 (*old_act).mask = old_sigaction.mask();
225                 if old_sigaction.restorer().is_some() {
226                     (*old_act).restorer = old_sigaction.restorer().unwrap().data() as *mut c_void;
227                 }
228             }
229         }
230         return retval.map(|_| 0);
231     }
232 }
233