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