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