summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryant Mairs <bryant@mai.rs>2017-07-16 21:25:50 -0700
committerBryant Mairs <bryant@mai.rs>2017-07-18 13:04:31 -0700
commit74ea3c7220e616ada07544d9d82d39acd12c2588 (patch)
tree9b3937d78e34e05e4acd1866e69251ec83794c77
parent79ad5fa487d3d746aa3d03dc70bb133b96053d40 (diff)
downloadnix-74ea3c7220e616ada07544d9d82d39acd12c2588.zip
Remove signalfd feature in favor of conditional compilation
Note that this is now only available for Linux as support is missing in libc for Android (see rust-lang/libc#671). As part of this work the SIGUSR2 signal mutex was altered to be a general signal mutex. This is because all signal handling is shared across all threads in the Rust test harness, so if you alter one signal, depending on whether it's additive or may overwrite the mask for other signals, it could break the other ones. Instead of putting this on the user, just broaden the scope of the mutex so that any altering of signal handling needs to use it.
-rw-r--r--Cargo.toml7
-rw-r--r--src/sys/mod.rs4
-rw-r--r--src/sys/signalfd.rs10
-rw-r--r--test/sys/mod.rs2
-rw-r--r--test/sys/test_aio.rs4
-rw-r--r--test/sys/test_signalfd.rs26
-rw-r--r--test/test.rs6
-rw-r--r--test/test_signalfd.rs30
8 files changed, 38 insertions, 51 deletions
diff --git a/Cargo.toml b/Cargo.toml
index bde647ac..3fdf2802 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,7 +17,6 @@ exclude = [
[features]
execvpe = []
-signalfd = []
[dependencies]
libc = "0.2.25"
@@ -37,12 +36,6 @@ name = "test"
path = "test/test.rs"
[[test]]
-name = "test-signalfd"
-path = "test/test_signalfd.rs"
-harness = false
-test = true
-
-[[test]]
name = "test-mount"
path = "test/test_mount.rs"
harness = false
diff --git a/src/sys/mod.rs b/src/sys/mod.rs
index 796a00a1..9636f93d 100644
--- a/src/sys/mod.rs
+++ b/src/sys/mod.rs
@@ -23,8 +23,8 @@ pub mod sendfile;
pub mod signal;
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg(feature = "signalfd")]
+// FIXME: Add to Android once libc#671 lands in a release
+#[cfg(target_os = "linux")]
pub mod signalfd;
pub mod socket;
diff --git a/src/sys/signalfd.rs b/src/sys/signalfd.rs
index a3dfb6be..fcf2efa9 100644
--- a/src/sys/signalfd.rs
+++ b/src/sys/signalfd.rs
@@ -60,12 +60,10 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
/// # Examples
///
/// ```
-/// use nix::sys::signalfd::*;
-///
+/// # use nix::sys::signalfd::*;
+/// // Set the thread to block the SIGUSR1 signal, otherwise the default handler will be used
/// let mut mask = SigSet::empty();
-/// mask.add(signal::SIGUSR1).unwrap();
-///
-/// // Block the signal, otherwise the default handler will be invoked instead.
+/// mask.add(signal::SIGUSR1);
/// mask.thread_block().unwrap();
///
/// // Signals are queued up on the file descriptor
@@ -74,11 +72,9 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
/// match sfd.read_signal() {
/// // we caught a signal
/// Ok(Some(sig)) => (),
-///
/// // there were no signals waiting (only happens when the SFD_NONBLOCK flag is set,
/// // otherwise the read_signal call blocks)
/// Ok(None) => (),
-///
/// Err(err) => (), // some error happend
/// }
/// ```
diff --git a/test/sys/mod.rs b/test/sys/mod.rs
index 4edb6af0..2ecc36f8 100644
--- a/test/sys/mod.rs
+++ b/test/sys/mod.rs
@@ -2,6 +2,8 @@ mod test_signal;
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
target_os = "netbsd", target_os = "macos", target_os = "linux"))]
mod test_aio;
+#[cfg(target_os = "linux")]
+mod test_signalfd;
mod test_socket;
mod test_sockopt;
mod test_termios;
diff --git a/test/sys/test_aio.rs b/test/sys/test_aio.rs
index 7e2bef63..54ee5a96 100644
--- a/test/sys/test_aio.rs
+++ b/test/sys/test_aio.rs
@@ -244,7 +244,7 @@ extern fn sigfunc(_: c_int) {
#[cfg_attr(any(all(target_env = "musl", target_arch = "x86_64"), target_arch = "mips"), ignore)]
fn test_write_sigev_signal() {
#[allow(unused_variables)]
- let m = ::SIGUSR2_MTX.lock().expect("Mutex got poisoned by another test");
+ let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
let sa = SigAction::new(SigHandler::Handler(sigfunc),
SA_RESETHAND,
SigSet::empty());
@@ -375,7 +375,7 @@ fn test_lio_listio_nowait() {
#[cfg_attr(any(target_arch = "mips", target_env = "musl"), ignore)]
fn test_lio_listio_signal() {
#[allow(unused_variables)]
- let m = ::SIGUSR2_MTX.lock().expect("Mutex got poisoned by another test");
+ let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
const INITIAL: &'static [u8] = b"abcdef123456";
const WBUF: &'static [u8] = b"CDEF";
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
diff --git a/test/sys/test_signalfd.rs b/test/sys/test_signalfd.rs
new file mode 100644
index 00000000..6d65e6a0
--- /dev/null
+++ b/test/sys/test_signalfd.rs
@@ -0,0 +1,26 @@
+#[test]
+fn test_signalfd() {
+ use nix::sys::signalfd::SignalFd;
+ use nix::sys::signal::{self, raise, Signal, SigSet};
+
+ // Grab the mutex for altering signals so we don't interfere with other tests.
+ #[allow(unused_variables)]
+ let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
+
+ // Block the SIGUSR1 signal from automatic processing for this thread
+ let mut mask = SigSet::empty();
+ mask.add(signal::SIGUSR1);
+ mask.thread_block().unwrap();
+
+ let mut fd = SignalFd::new(&mask).unwrap();
+
+ // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
+ // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
+ // cargo test session. Instead use `raise` which does the correct thing by default.
+ raise(signal::SIGUSR1).ok().expect("Error: raise(SIGUSR1) failed");
+
+ // And now catch that same signal.
+ let res = fd.read_signal().unwrap().unwrap();
+ let signo = Signal::from_c_int(res.ssi_signo as i32).unwrap();
+ assert_eq!(signo, signal::SIGUSR1);
+}
diff --git a/test/test.rs b/test/test.rs
index 4c81aa2b..eb4556fa 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -11,7 +11,7 @@ extern crate nix_test as nixtest;
mod sys;
mod test_fcntl;
-#[cfg(any(target_os = "linux"))]
+#[cfg(target_os = "linux")]
mod test_mq;
mod test_net;
mod test_nix_path;
@@ -45,8 +45,8 @@ lazy_static! {
/// Any test that creates child processes must grab this mutex, regardless
/// of what it does with those children.
pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
- /// Any test that registers a SIGUSR2 handler must grab this mutex
- pub static ref SIGUSR2_MTX: Mutex<()> = Mutex::new(());
+ /// Any test that alters signal handling must grab this mutex.
+ pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
}
#[test]
diff --git a/test/test_signalfd.rs b/test/test_signalfd.rs
deleted file mode 100644
index 28a6decb..00000000
--- a/test/test_signalfd.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-extern crate nix;
-
-#[cfg(feature = "signalfd")]
-use nix::sys::signalfd::SignalFd;
-#[cfg(feature = "signalfd")]
-use nix::sys::signal;
-#[cfg(feature = "signalfd")]
-use nix::unistd;
-
-#[cfg(feature = "signalfd")]
-fn main() {
- print!("test test_signalfd ... ");
-
- let mut mask = signal::SigSet::empty();
- mask.add(signal::SIGUSR1).unwrap();
- mask.thread_block().unwrap();
-
- let mut fd = SignalFd::new(&mask).unwrap();
-
- let pid = unistd::getpid();
- signal::kill(pid, signal::SIGUSR1).unwrap();
-
- let res = fd.read_signal();
-
- assert_eq!(res.unwrap().unwrap().ssi_signo as i32, signal::SIGUSR1);
- println!("ok");
-}
-
-#[cfg(not(feature = "signalfd"))]
-fn main() {}