Skip to content

Commit

Permalink
Merge #826
Browse files Browse the repository at this point in the history
826: Add sigprocmask r=asomers a=Thomasdezeeuw
  • Loading branch information
bors[bot] committed Jan 6, 2018
2 parents bb69c29 + efc9ac3 commit abd72be
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#741](https://github.com/nix-rust/nix/pull/741))
- Added more standard trait implementations for various types.
([#814](https://github.com/nix-rust/nix/pull/814))
- Added `sigprocmask` to the signal module.
([#826](https://github.com/nix-rust/nix/pull/826))

### Changed
- Use native `pipe2` on all BSD targets. Users should notice no difference.
Expand Down
21 changes: 21 additions & 0 deletions src/sys/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,27 @@ pub fn pthread_sigmask(how: SigmaskHow,
Errno::result(res).map(drop)
}

/// Examine and change blocked signals.
///
/// For more informations see the [`sigprocmask` man
/// pages](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html).
pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut SigSet>) -> Result<()> {
if set.is_none() && oldset.is_none() {
return Ok(())
}

let res = unsafe {
// if set or oldset is None, pass in null pointers instead
libc::sigprocmask(how as libc::c_int,
set.map_or_else(ptr::null::<libc::sigset_t>,
|s| &s.sigset as *const libc::sigset_t),
oldset.map_or_else(ptr::null_mut::<libc::sigset_t>,
|os| &mut os.sigset as *mut libc::sigset_t))
};

Errno::result(res).map(drop)
}

pub fn kill<T: Into<Option<Signal>>>(pid: ::unistd::Pid, signal: T) -> Result<()> {
let res = unsafe { libc::kill(pid.into(),
match signal.into() {
Expand Down
42 changes: 42 additions & 0 deletions test/sys/test_signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,45 @@ use nix::sys::signal::*;
fn test_kill_none() {
kill(getpid(), None).expect("Should be able to send signal to myself.");
}

#[test]
fn test_sigprocmask_noop() {
sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
.expect("this should be an effective noop");
}

#[test]
fn test_sigprocmask() {
#[allow(unused_variables)]
let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");

// This needs to be a signal that rust doesn't use in the test harness.
const SIGNAL: Signal = Signal::SIGCHLD;

let mut old_signal_set = SigSet::empty();
sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
.expect("expect to be able to retrieve old signals");

// Make sure the old set doesn't contain the signal, otherwise the following
// test don't make sense.
assert_eq!(old_signal_set.contains(SIGNAL), false,
"the {:?} signal is already blocked, please change to a \
different one", SIGNAL);

// Now block the signal.
let mut signal_set = SigSet::empty();
signal_set.add(SIGNAL);
sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
.expect("expect to be able to block signals");

// And test it again, to make sure the change was effective.
old_signal_set.clear();
sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
.expect("expect to be able to retrieve old signals");
assert_eq!(old_signal_set.contains(SIGNAL), true,
"expected the {:?} to be blocked", SIGNAL);

// Reset the signal.
sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
.expect("expect to be able to block signals");
}

0 comments on commit abd72be

Please sign in to comment.