diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/sys/mod.rs | 1 | ||||
-rw-r--r-- | test/sys/test_ptrace.rs | 49 | ||||
-rw-r--r-- | test/sys/test_select.rs | 59 | ||||
-rw-r--r-- | test/sys/test_wait.rs | 11 |
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))); } |