diff options
Diffstat (limited to 'test/sys/test_uio.rs')
-rw-r--r-- | test/sys/test_uio.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs index d805b3b3..57296938 100644 --- a/test/sys/test_uio.rs +++ b/test/sys/test_uio.rs @@ -190,3 +190,55 @@ fn test_preadv() { let all = buffers.concat(); assert_eq!(all, expected); } + +#[test] +#[cfg(target_os = "linux")] +// FIXME: qemu-user doesn't implement process_vm_readv/writev on most arches +#[cfg_attr(not(any(target_arch = "x86", target_arch = "x86_64")), ignore)] +fn test_process_vm_readv() { + use nix::unistd::ForkResult::*; + use nix::sys::signal::*; + use nix::sys::wait::*; + use std::str; + + #[allow(unused_variables)] + let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); + + // Pre-allocate memory in the child, since allocation isn't safe + // post-fork (~= async-signal-safe) + let mut vector = vec![1u8, 2, 3, 4, 5]; + + let (r, w) = pipe().unwrap(); + match fork() { + Ok(Parent { child }) => { + close(w).unwrap(); + // wait for child + read(r, &mut vec![0u8]).unwrap(); + close(r).unwrap(); + + let ptr = vector.as_ptr() as usize; + let remote_iov = RemoteIoVec { base: ptr, len: 5 }; + let mut buf = vec![0u8; 5]; + + let ret = process_vm_readv(child, + &[IoVec::from_mut_slice(&mut buf)], + &[remote_iov]); + + kill(child, SIGTERM).unwrap(); + waitpid(child, None).unwrap(); + + assert_eq!(Ok(5), ret); + assert_eq!(20u8, buf.iter().sum()); + }, + Ok(Child) => { + let _ = close(r); + for i in vector.iter_mut() { + *i += 1; + } + let _ = write(w, b"\0"); + let _ = close(w); + loop { let _ = pause(); } + }, + Err(_) => panic!("fork failed") + } +} |