xref: /drstd/dlibc/src/unix/header/signal/mod.rs (revision a1cd34728e2d4a5d4cf41974e4db28602cbb1b1c)
1 //! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
2 
3 use core::mem;
4 
5 use cbitset::BitSet;
6 
7 use crate::unix::header::errno;
8 
9 pub use self::platform::*;
10 
11 use crate::unix::header::signal::sys::NSIG;
12 use crate::unix::platform;
13 
14 #[cfg(target_os = "linux")]
15 #[path = "linux.rs"]
16 pub mod sys;
17 
18 #[cfg(target_os = "dragonos")]
19 #[path = "dragonos.rs"]
20 pub mod sys;
21 
22 #[cfg(target_os = "redox")]
23 #[path = "redox.rs"]
24 pub mod sys;
25 
26 type SigSet = BitSet<[::c_ulong; 1]>;
27 
28 pub const SIG_DFL: usize = 0;
29 pub const SIG_IGN: usize = 1;
30 pub const SIG_ERR: isize = -1;
31 
32 pub const SIG_BLOCK: ::c_int = 0;
33 pub const SIG_UNBLOCK: ::c_int = 1;
34 pub const SIG_SETMASK: ::c_int = 2;
35 
36 // #[repr(C)]
37 // #[derive(Clone, Debug)]
38 // pub struct sigaction {
39 //     pub sa_handler: Option<extern "C" fn(::c_int)>,
40 //     pub sa_flags: ::c_ulong,
41 //     pub sa_restorer: Option<unsafe extern "C" fn()>,
42 //     pub sa_mask: sigset_t,
43 // }
44 
45 #[repr(C)]
46 #[derive(Clone)]
47 pub struct sigaltstack {
48     pub ss_sp: *mut ::c_void,
49     pub ss_flags: ::c_int,
50     pub ss_size: ::size_t,
51 }
52 
53 // #[no_mangle]
54 // pub extern "C" fn kill(pid: ::pid_t, sig: ::c_int) -> ::c_int {
55 //     platform::pal::kill(pid, sig)
56 // }
57 
58 // #[no_mangle]
59 // pub extern "C" fn killpg(pgrp: ::pid_t, sig: ::c_int) -> ::c_int {
60 //     platform::pal::killpg(pgrp, sig)
61 // }
62 
63 #[no_mangle]
64 pub extern "C" fn pthread_sigmask(
65     how: ::c_int,
66     set: *const sigset_t,
67     oldset: *mut sigset_t,
68 ) -> ::c_int {
69     // On Linux and Redox, pthread_sigmask and sigprocmask are equivalent
70     if sigprocmask(how, set, oldset) == 0 {
71         0
72     } else {
73         //TODO: Fix race
74         unsafe { platform::errno }
75     }
76 }
77 
78 // #[no_mangle]
79 // pub extern "C" fn raise(sig: ::c_int) -> ::c_int {
80 //     platform::pal::raise(sig)
81 // }
82 
83 // #[no_mangle]
84 // pub unsafe extern "C" fn sigaction(
85 //     sig: ::c_int,
86 //     act: *const sigaction,
87 //     oact: *mut sigaction,
88 // ) -> ::c_int {
89 //     let act_opt = act.as_ref().map(|act| {
90 //         let mut act_clone = act.clone();
91 //         act_clone.sa_flags |= SA_RESTORER as ::c_ulong;
92 //         act_clone.sa_restorer = Some(__restore_rt);
93 //         act_clone
94 //     });
95 //     platform::pal::sigaction(sig, act_opt.as_ref(), oact.as_mut())
96 // }
97 
98 #[no_mangle]
99 pub extern "C" fn sigaddset(set: *mut sigset_t, signo: ::c_int) -> ::c_int {
100     if signo <= 0 || signo as usize > NSIG {
101         unsafe {
102             platform::errno = errno::EINVAL;
103         }
104         return -1;
105     }
106 
107     if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
108         set.insert(signo as usize - 1); // 0-indexed usize, please!
109     }
110     0
111 }
112 
113 // #[no_mangle]
114 // pub unsafe extern "C" fn sigaltstack(ss: *const ::stack_t, old_ss: *mut ::stack_t) -> ::c_int {
115 //     if !ss.is_null() {
116 //         if (*ss).ss_flags != SS_DISABLE as ::c_int {
117 //             return errno::EINVAL;
118 //         }
119 //         if (*ss).ss_size < MINSIGSTKSZ {
120 //             return errno::ENOMEM;
121 //         }
122 //     }
123 
124 //     platform::pal::sigaltstack(ss, old_ss)
125 // }
126 
127 #[no_mangle]
128 pub extern "C" fn sigdelset(set: *mut sigset_t, signo: ::c_int) -> ::c_int {
129     if signo <= 0 || signo as usize > NSIG {
130         unsafe {
131             platform::errno = errno::EINVAL;
132         }
133         return -1;
134     }
135 
136     if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
137         set.remove(signo as usize - 1); // 0-indexed usize, please!
138     }
139     0
140 }
141 
142 #[no_mangle]
143 pub extern "C" fn sigemptyset(set: *mut sigset_t) -> ::c_int {
144     if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
145         set.clear();
146     }
147     0
148 }
149 
150 #[no_mangle]
151 pub extern "C" fn sigfillset(set: *mut sigset_t) -> ::c_int {
152     if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
153         set.fill(.., true);
154     }
155     0
156 }
157 
158 // #[no_mangle]
159 pub extern "C" fn sighold(_sig: ::c_int) -> ::c_int {
160     unimplemented!();
161 }
162 
163 // #[no_mangle]
164 pub extern "C" fn sigignore(_sig: ::c_int) -> ::c_int {
165     unimplemented!();
166 }
167 
168 // #[no_mangle]
169 pub extern "C" fn siginterrupt(_sig: ::c_int, _flag: ::c_int) -> ::c_int {
170     unimplemented!();
171 }
172 
173 #[no_mangle]
174 pub extern "C" fn sigismember(set: *const sigset_t, signo: ::c_int) -> ::c_int {
175     if signo <= 0 || signo as usize > NSIG {
176         unsafe {
177             platform::errno = errno::EINVAL;
178         }
179         return -1;
180     }
181 
182     if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
183         if set.contains(signo as usize - 1) {
184             return 1;
185         }
186     }
187     0
188 }
189 
190 extern "C" {
191     // Defined in assembly inside platform/x/mod.rs
192     fn __restore_rt();
193 }
194 
195 //TODO: 该行为不一致,使用系统调用signal
196 //#[no_mangle]
197 pub extern "C" fn signal(
198     sig: ::c_int,
199     func: Option<extern "C" fn(::c_int)>,
200 ) -> Option<extern "C" fn(::c_int)> {
201     let sa = sigaction {
202         sa_sigaction: func.unwrap() as *const () as ::sighandler_t,
203         sa_flags: SA_RESTART,
204         sa_restorer: Some(__restore_rt),
205         sa_mask: sigset_t::default(),
206     };
207     let mut old_sa = mem::MaybeUninit::zeroed();
208     if unsafe { sigaction(sig, &sa as *const sigaction, old_sa.as_mut_ptr()) } < 0 {
209         // mem::forget(old_sa);
210         return unsafe { mem::transmute(SIG_ERR) };
211     }
212     let sa_handler = unsafe { old_sa.assume_init() }.sa_sigaction;
213     unsafe { Some(*(sa_handler as *const () as *const extern "C" fn(::c_int))) }
214 }
215 
216 // #[no_mangle]
217 // pub extern "C" fn sigpause(sig: ::c_int) -> ::c_int {
218 //     unimplemented!();
219 // }
220 
221 // #[no_mangle]
222 // pub extern "C" fn sigpending(set: *mut sigset_t) -> ::c_int {
223 //     unimplemented!();
224 // }
225 
226 // #[no_mangle]
227 // pub extern "C" fn sigprocmask(how: ::c_int, set: *const sigset_t, oset: *mut sigset_t) -> ::c_int {
228 //     platform::pal::sigprocmask(how, set, oset)
229 // }
230 
231 // #[no_mangle]
232 // pub extern "C" fn sigrelse(sig: ::c_int) -> ::c_int {
233 //     unimplemented!();
234 // }
235 
236 // #[no_mangle]
237 // pub extern "C" fn sigset(sig: ::c_int, func: fn(::c_int)) -> fn(::c_int) {
238 //     unimplemented!();
239 // }
240 
241 // #[no_mangle]
242 // pub extern "C" fn sigsuspend(sigmask: *const sigset_t) -> ::c_int {
243 //     unimplemented!();
244 // }
245 
246 // #[no_mangle]
247 // pub extern "C" fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int {
248 //     unimplemented!();
249 // }
250 
251 pub const _signal_strings: [&str; 32] = [
252     "Unknown signal\0",
253     "Hangup\0",
254     "Interrupt\0",
255     "Quit\0",
256     "Illegal instruction\0",
257     "Trace/breakpoint trap\0",
258     "Aborted\0",
259     "Bus error\0",
260     "Arithmetic exception\0",
261     "Killed\0",
262     "User defined signal 1\0",
263     "Segmentation fault\0",
264     "User defined signal 2\0",
265     "Broken pipe\0",
266     "Alarm clock\0",
267     "Terminated\0",
268     "Stack fault\0",
269     "Child process status\0",
270     "Continued\0",
271     "Stopped (signal)\0",
272     "Stopped\0",
273     "Stopped (tty input)\0",
274     "Stopped (tty output)\0",
275     "Urgent I/O condition\0",
276     "CPU time limit exceeded\0",
277     "File size limit exceeded\0",
278     "Virtual timer expired\0",
279     "Profiling timer expired\0",
280     "Window changed\0",
281     "I/O possible\0",
282     "Power failure\0",
283     "Bad system call\0",
284 ];
285