Skip to content

Commit 76320bc

Browse files
committed
Merge #611
611: Add SigAction getters r=asomers I want to inspect the old SigAction after installing a new one. This adds getter methods for handler, flags and mask. Returning the old SigAction isn't very useful if we can't read its fields.
2 parents ba5c837 + cd73cae commit 76320bc

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66
## [Unreleased]
77

88
### Added
9+
- Added `sys::signal::SigAction::{ flags, mask, handler}`
10+
([#611](https://github.com/nix-rust/nix/pull/609)
911
- Added `AioCb::from_boxed_slice`
1012
([#582](https://github.com/nix-rust/nix/pull/582)
1113
- Added `nix::unistd::{openat, fstatat, readlink, readlinkat}`

src/sys/signal.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ impl AsRef<libc::sigset_t> for SigSet {
315315
}
316316

317317
#[allow(unknown_lints)]
318-
#[derive(Clone, Copy, PartialEq)]
318+
#[derive(Debug, Clone, Copy, PartialEq)]
319319
pub enum SigHandler {
320320
SigDfl,
321321
SigIgn,
@@ -346,6 +346,24 @@ impl SigAction {
346346

347347
SigAction { sigaction: s }
348348
}
349+
350+
pub fn flags(&self) -> SaFlags {
351+
SaFlags::from_bits(self.sigaction.sa_flags).unwrap()
352+
}
353+
354+
pub fn mask(&self) -> SigSet {
355+
SigSet { sigset: self.sigaction.sa_mask }
356+
}
357+
358+
pub fn handler(&self) -> SigHandler {
359+
match self.sigaction.sa_sigaction {
360+
libc::SIG_DFL => SigHandler::SigDfl,
361+
libc::SIG_IGN => SigHandler::SigIgn,
362+
f if self.flags().contains(SA_SIGINFO) =>
363+
SigHandler::SigAction( unsafe { mem::transmute(f) } ),
364+
f => SigHandler::Handler( unsafe { mem::transmute(f) } ),
365+
}
366+
}
349367
}
350368

351369
pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
@@ -639,6 +657,41 @@ mod tests {
639657
assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2));
640658
}
641659

660+
#[test]
661+
fn test_sigaction() {
662+
use libc;
663+
664+
extern fn test_sigaction_handler(_: libc::c_int) {}
665+
extern fn test_sigaction_action(_: libc::c_int,
666+
_: *mut libc::siginfo_t, _: *mut libc::c_void) {}
667+
668+
let handler_sig = SigHandler::Handler(test_sigaction_handler);
669+
670+
let flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
671+
672+
let mut mask = SigSet::empty();
673+
mask.add(SIGUSR1);
674+
675+
let action_sig = SigAction::new(handler_sig, flags, mask);
676+
677+
assert_eq!(action_sig.flags(), SA_ONSTACK | SA_RESTART);
678+
assert_eq!(action_sig.handler(), handler_sig);
679+
680+
mask = action_sig.mask();
681+
assert!(mask.contains(SIGUSR1));
682+
assert!(!mask.contains(SIGUSR2));
683+
684+
let handler_act = SigHandler::SigAction(test_sigaction_action);
685+
let action_act = SigAction::new(handler_act, flags, mask);
686+
assert_eq!(action_act.handler(), handler_act);
687+
688+
let action_dfl = SigAction::new(SigHandler::SigDfl, flags, mask);
689+
assert_eq!(action_dfl.handler(), SigHandler::SigDfl);
690+
691+
let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask);
692+
assert_eq!(action_ign.handler(), SigHandler::SigIgn);
693+
}
694+
642695
// TODO(#251): Re-enable after figuring out flakiness.
643696
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
644697
#[test]

0 commit comments

Comments
 (0)