signal.rs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. use syscall;
  2. use super::super::types::*;
  3. use super::super::{Pal, PalSignal};
  4. use super::{e, Sys};
  5. use header::signal::{sigaction, sigset_t};
  6. #[thread_local]
  7. static mut SIG_HANDLER: Option<extern "C" fn(c_int)> = None;
  8. extern "C" fn sig_handler(sig: usize) {
  9. if let Some(ref callback) = unsafe { SIG_HANDLER } {
  10. callback(sig as c_int);
  11. }
  12. }
  13. impl PalSignal for Sys {
  14. fn kill(pid: pid_t, sig: c_int) -> c_int {
  15. e(syscall::kill(pid as usize, sig as usize)) as c_int
  16. }
  17. fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
  18. e(syscall::kill(-(pgrp as isize) as usize, sig as usize)) as c_int
  19. }
  20. fn raise(sig: c_int) -> c_int {
  21. Self::kill(Self::getpid(), sig)
  22. }
  23. unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
  24. if !oact.is_null() {
  25. // Assumes the last sigaction() call was made by relibc and not a different one
  26. if SIG_HANDLER.is_some() {
  27. (*oact).sa_handler = SIG_HANDLER;
  28. }
  29. }
  30. let act = if act.is_null() {
  31. None
  32. } else {
  33. SIG_HANDLER = (*act).sa_handler;
  34. let m = (*act).sa_mask;
  35. Some(syscall::SigAction {
  36. sa_handler: sig_handler,
  37. sa_mask: [0, m as u64],
  38. sa_flags: (*act).sa_flags as usize,
  39. })
  40. };
  41. let mut old = syscall::SigAction::default();
  42. let ret = e(syscall::sigaction(
  43. sig as usize,
  44. act.as_ref(),
  45. if oact.is_null() { None } else { Some(&mut old) },
  46. )) as c_int;
  47. if !oact.is_null() {
  48. let m = old.sa_mask;
  49. (*oact).sa_mask = m[1] as c_ulong;
  50. (*oact).sa_flags = old.sa_flags as c_ulong;
  51. }
  52. ret
  53. }
  54. //fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int;
  55. }