summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/sys/mod.rs1
-rw-r--r--test/sys/test_ptrace.rs49
-rw-r--r--test/sys/test_select.rs59
-rw-r--r--test/sys/test_wait.rs11
4 files changed, 51 insertions, 69 deletions
diff --git a/test/sys/mod.rs b/test/sys/mod.rs
index 2ecc36f8..3aab9fc5 100644
--- a/test/sys/mod.rs
+++ b/test/sys/mod.rs
@@ -9,7 +9,6 @@ mod test_sockopt;
mod test_termios;
mod test_ioctl;
mod test_wait;
-mod test_select;
mod test_uio;
#[cfg(target_os = "linux")]
diff --git a/test/sys/test_ptrace.rs b/test/sys/test_ptrace.rs
index 0614c13f..16b24110 100644
--- a/test/sys/test_ptrace.rs
+++ b/test/sys/test_ptrace.rs
@@ -3,14 +3,13 @@ use nix::errno::Errno;
use nix::unistd::getpid;
use nix::sys::ptrace;
-use std::{mem, ptr};
+use std::mem;
#[test]
fn test_ptrace() {
- use nix::sys::ptrace::ptrace::PTRACE_ATTACH;
// Just make sure ptrace can be called at all, for now.
// FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS
- let err = ptrace::ptrace(PTRACE_ATTACH, getpid(), ptr::null_mut(), ptr::null_mut()).unwrap_err();
+ let err = ptrace::attach(getpid()).unwrap_err();
assert!(err == Error::Sys(Errno::EPERM) || err == Error::Sys(Errno::ENOSYS));
}
@@ -47,3 +46,47 @@ fn test_ptrace_setsiginfo() {
_ => (),
}
}
+
+
+#[test]
+fn test_ptrace_cont() {
+ use nix::sys::ptrace;
+ use nix::sys::signal::{raise, Signal};
+ use nix::sys::wait::{waitpid, WaitStatus};
+ use nix::unistd::fork;
+ use nix::unistd::ForkResult::*;
+
+ // FIXME: qemu-user doesn't implement ptrace on all architectures
+ // and retunrs ENOSYS in this case.
+ // We (ab)use this behavior to detect the affected platforms
+ // and skip the test then.
+ // On valid platforms the ptrace call should return Errno::EPERM, this
+ // is already tested by `test_ptrace`.
+ let err = ptrace::attach(getpid()).unwrap_err();
+ if err == Error::Sys(Errno::ENOSYS) {
+ return;
+ }
+
+ match fork() {
+ Ok(Child) => {
+ ptrace::traceme().unwrap();
+ // As recommended by ptrace(2), raise SIGTRAP to pause the child
+ // until the parent is ready to continue
+ loop {
+ raise(Signal::SIGTRAP).unwrap();
+ }
+
+ },
+ Ok(Parent { child }) => {
+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)));
+ ptrace::cont(child, None).unwrap();
+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)));
+ ptrace::cont(child, Signal::SIGKILL).unwrap();
+ match waitpid(child, None) {
+ Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) if pid == child => {}
+ _ => panic!("The process should have been killed"),
+ }
+ },
+ Err(_) => panic!("Error: Fork Failed")
+ }
+}
diff --git a/test/sys/test_select.rs b/test/sys/test_select.rs
deleted file mode 100644
index d50c7d74..00000000
--- a/test/sys/test_select.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use nix::sys::select::{FdSet, FD_SETSIZE, select};
-use nix::sys::time::{TimeVal, TimeValLike};
-use nix::unistd::{write, pipe};
-
-#[test]
-fn test_fdset() {
- let mut fd_set = FdSet::new();
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i));
- }
-
- fd_set.insert(7);
-
- assert!(fd_set.contains(7));
-
- fd_set.remove(7);
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i));
- }
-
- fd_set.insert(1);
- fd_set.insert(FD_SETSIZE / 2);
- fd_set.insert(FD_SETSIZE - 1);
-
- fd_set.clear();
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i));
- }
-}
-
-// powerpc-unknown-linux-gnu currently fails on the first `assert_eq` because
-// `select()` returns a 0 instead of a 1. Since this test has only been run on
-// qemu, it's unclear if this is a OS or qemu bug. Just disable it on that arch
-// for now.
-// FIXME: Fix tests for powerpc and mips
-// FIXME: Add a link to an upstream qemu bug if there is one
-#[test]
-#[cfg_attr(any(target_arch = "powerpc", target_arch = "mips"), ignore)]
-fn test_select() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let mut timeout = TimeVal::seconds(10);
- assert_eq!(1, select(r2 + 1,
- Some(&mut fd_set),
- None,
- None,
- Some(&mut timeout)).unwrap());
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
-}
diff --git a/test/sys/test_wait.rs b/test/sys/test_wait.rs
index 620a4e33..0193e262 100644
--- a/test/sys/test_wait.rs
+++ b/test/sys/test_wait.rs
@@ -60,14 +60,13 @@ mod ptrace {
use nix::sys::wait::*;
use nix::unistd::*;
use nix::unistd::ForkResult::*;
- use std::ptr;
use libc::_exit;
fn ptrace_child() -> ! {
- ptrace::ptrace(PTRACE_TRACEME, Pid::from_raw(0), ptr::null_mut(), ptr::null_mut()).unwrap();
+ ptrace::traceme().unwrap();
// As recommended by ptrace(2), raise SIGTRAP to pause the child
// until the parent is ready to continue
- let _ = raise(SIGTRAP);
+ raise(SIGTRAP).unwrap();
unsafe { _exit(0) }
}
@@ -78,13 +77,13 @@ mod ptrace {
assert!(ptrace::setoptions(child, PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXIT).is_ok());
// First, stop on the next system call, which will be exit()
- assert!(ptrace::ptrace(PTRACE_SYSCALL, child, ptr::null_mut(), ptr::null_mut()).is_ok());
+ assert!(ptrace::syscall(child).is_ok());
assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
// Then get the ptrace event for the process exiting
- assert!(ptrace::ptrace(PTRACE_CONT, child, ptr::null_mut(), ptr::null_mut()).is_ok());
+ assert!(ptrace::cont(child, None).is_ok());
assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceEvent(child, SIGTRAP, PTRACE_EVENT_EXIT)));
// Finally get the normal wait() result, now that the process has exited
- assert!(ptrace::ptrace(PTRACE_CONT, child, ptr::null_mut(), ptr::null_mut()).is_ok());
+ assert!(ptrace::cont(child, None).is_ok());
assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0)));
}