mod.rs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
  2. use core::{mem, ptr};
  3. use cbitset::BitSet;
  4. use header::errno;
  5. use platform;
  6. use platform::types::*;
  7. use platform::{PalSignal, Sys};
  8. pub use self::sys::*;
  9. #[cfg(target_os = "linux")]
  10. #[path = "linux.rs"]
  11. pub mod sys;
  12. #[cfg(target_os = "redox")]
  13. #[path = "redox.rs"]
  14. pub mod sys;
  15. type SigSet = BitSet<[c_ulong; 1]>;
  16. const SIG_ERR: usize = !0;
  17. pub const SIG_BLOCK: c_int = 0;
  18. pub const SIG_UNBLOCK: c_int = 1;
  19. pub const SIG_SETMASK: c_int = 2;
  20. #[repr(C)]
  21. #[derive(Clone)]
  22. pub struct sigaction {
  23. pub sa_handler: extern "C" fn(c_int),
  24. pub sa_flags: c_ulong,
  25. pub sa_restorer: unsafe extern "C" fn(),
  26. pub sa_mask: sigset_t,
  27. }
  28. pub type sigset_t = c_ulong;
  29. #[no_mangle]
  30. pub extern "C" fn kill(pid: pid_t, sig: c_int) -> c_int {
  31. Sys::kill(pid, sig)
  32. }
  33. #[no_mangle]
  34. pub extern "C" fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
  35. Sys::killpg(pgrp, sig)
  36. }
  37. #[no_mangle]
  38. pub extern "C" fn pthread_sigmask(
  39. how: c_int,
  40. set: *const sigset_t,
  41. oldset: *mut sigset_t,
  42. ) -> c_int {
  43. // On Linux and Redox, pthread_sigmask and sigprocmask are equivalent
  44. if sigprocmask(how, set, oldset) == 0 {
  45. 0
  46. } else {
  47. //TODO: Fix race
  48. unsafe { platform::errno }
  49. }
  50. }
  51. #[no_mangle]
  52. pub extern "C" fn raise(sig: c_int) -> c_int {
  53. Sys::raise(sig)
  54. }
  55. #[no_mangle]
  56. pub unsafe extern "C" fn sigaction(
  57. sig: c_int,
  58. act: *const sigaction,
  59. oact: *mut sigaction,
  60. ) -> c_int {
  61. let mut _sigaction = None;
  62. let ptr = if !act.is_null() {
  63. _sigaction = Some((*act).clone());
  64. _sigaction.as_mut().unwrap().sa_flags |= SA_RESTORER as c_ulong;
  65. _sigaction.as_mut().unwrap() as *mut _
  66. } else {
  67. ptr::null_mut()
  68. };
  69. Sys::sigaction(sig, ptr, oact)
  70. }
  71. #[no_mangle]
  72. pub extern "C" fn sigaddset(set: *mut sigset_t, signo: c_int) -> c_int {
  73. if signo <= 0 || signo as usize > NSIG {
  74. unsafe {
  75. platform::errno = errno::EINVAL;
  76. }
  77. return -1;
  78. }
  79. if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
  80. set.insert(signo as usize - 1); // 0-indexed usize, please!
  81. }
  82. 0
  83. }
  84. #[no_mangle]
  85. pub extern "C" fn sigdelset(set: *mut sigset_t, signo: c_int) -> c_int {
  86. if signo <= 0 || signo as usize > NSIG {
  87. unsafe {
  88. platform::errno = errno::EINVAL;
  89. }
  90. return -1;
  91. }
  92. if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
  93. set.remove(signo as usize - 1); // 0-indexed usize, please!
  94. }
  95. 0
  96. }
  97. #[no_mangle]
  98. pub extern "C" fn sigemptyset(set: *mut sigset_t) -> c_int {
  99. if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
  100. set.clear();
  101. }
  102. 0
  103. }
  104. #[no_mangle]
  105. pub extern "C" fn sigfillset(set: *mut sigset_t) -> c_int {
  106. if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
  107. set.fill(.., true);
  108. }
  109. 0
  110. }
  111. // #[no_mangle]
  112. pub extern "C" fn sighold(sig: c_int) -> c_int {
  113. unimplemented!();
  114. }
  115. // #[no_mangle]
  116. pub extern "C" fn sigignore(sig: c_int) -> c_int {
  117. unimplemented!();
  118. }
  119. // #[no_mangle]
  120. pub extern "C" fn siginterrupt(sig: c_int, flag: c_int) -> c_int {
  121. unimplemented!();
  122. }
  123. #[no_mangle]
  124. pub extern "C" fn sigismember(set: *const sigset_t, signo: c_int) -> c_int {
  125. if signo <= 0 || signo as usize > NSIG {
  126. unsafe {
  127. platform::errno = errno::EINVAL;
  128. }
  129. return -1;
  130. }
  131. if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
  132. if set.contains(signo as usize - 1) {
  133. return 1;
  134. }
  135. }
  136. 0
  137. }
  138. extern "C" {
  139. // Defined in assembly inside platform/x/mod.rs
  140. fn __restore_rt();
  141. }
  142. #[no_mangle]
  143. pub extern "C" fn signal(sig: c_int, func: extern "C" fn(c_int)) -> extern "C" fn(c_int) {
  144. let sa = sigaction {
  145. sa_handler: func,
  146. sa_flags: SA_RESTART as c_ulong,
  147. sa_restorer: __restore_rt,
  148. sa_mask: sigset_t::default(),
  149. };
  150. let mut old_sa = unsafe { mem::uninitialized() };
  151. if unsafe { sigaction(sig, &sa, &mut old_sa) } < 0 {
  152. mem::forget(old_sa);
  153. return unsafe { mem::transmute(SIG_ERR) };
  154. }
  155. old_sa.sa_handler
  156. }
  157. // #[no_mangle]
  158. pub extern "C" fn sigpause(sig: c_int) -> c_int {
  159. unimplemented!();
  160. }
  161. // #[no_mangle]
  162. pub extern "C" fn sigpending(set: *mut sigset_t) -> c_int {
  163. unimplemented!();
  164. }
  165. #[no_mangle]
  166. pub extern "C" fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
  167. Sys::sigprocmask(how, set, oset)
  168. }
  169. // #[no_mangle]
  170. pub extern "C" fn sigrelse(sig: c_int) -> c_int {
  171. unimplemented!();
  172. }
  173. // #[no_mangle]
  174. pub extern "C" fn sigset(sig: c_int, func: fn(c_int)) -> fn(c_int) {
  175. unimplemented!();
  176. }
  177. // #[no_mangle]
  178. pub extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int {
  179. unimplemented!();
  180. }
  181. // #[no_mangle]
  182. pub extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int {
  183. unimplemented!();
  184. }
  185. pub const _signal_strings: [&str; 32] = [
  186. "Unknown signal\0",
  187. "Hangup\0",
  188. "Interrupt\0",
  189. "Quit\0",
  190. "Illegal instruction\0",
  191. "Trace/breakpoint trap\0",
  192. "Aborted\0",
  193. "Bus error\0",
  194. "Arithmetic exception\0",
  195. "Killed\0",
  196. "User defined signal 1\0",
  197. "Segmentation fault\0",
  198. "User defined signal 2\0",
  199. "Broken pipe\0",
  200. "Alarm clock\0",
  201. "Terminated\0",
  202. "Stack fault\0",
  203. "Child process status\0",
  204. "Continued\0",
  205. "Stopped (signal)\0",
  206. "Stopped\0",
  207. "Stopped (tty input)\0",
  208. "Stopped (tty output)\0",
  209. "Urgent I/O condition\0",
  210. "CPU time limit exceeded\0",
  211. "File size limit exceeded\0",
  212. "Virtual timer expired\0",
  213. "Profiling timer expired\0",
  214. "Window changed\0",
  215. "I/O possible\0",
  216. "Power failure\0",
  217. "Bad system call\0",
  218. ];