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