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