summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlan Somers <asomers@gmail.com>2018-03-04 21:17:08 -0700
committerAlan Somers <asomers@gmail.com>2018-03-22 16:53:11 -0600
commit4bdbf59fe5c1fd3409aa027d0ec0ea50065b39bb (patch)
tree86a5bd7df2db133b35882e6df5a91c85845567f9 /test
parent0418d346c5343d4b55d580dc9fd66cd2a150a0c3 (diff)
downloadnix-4bdbf59fe5c1fd3409aa027d0ec0ea50065b39bb.zip
Change sys::aio::lio_listio to sys::aio::LioCb::listio
The new LioCb structure allows us to control the exact arguments passed to lio_listio, guaranteeing that each call gets a unique storage location for the list argument. This prevents clients from misusing lio_listio in a way that causes events to get dropped from a kqueue Fixes #870
Diffstat (limited to 'test')
-rw-r--r--test/sys/test_aio.rs89
1 files changed, 50 insertions, 39 deletions
diff --git a/test/sys/test_aio.rs b/test/sys/test_aio.rs
index f88fc268..f11c7ef9 100644
--- a/test/sys/test_aio.rs
+++ b/test/sys/test_aio.rs
@@ -505,12 +505,12 @@ fn test_write_sigev_signal() {
assert!(rbuf == EXPECT);
}
-// Test lio_listio with LIO_WAIT, so all AIO ops should be complete by the time
-// lio_listio returns.
+// Test LioCb::listio with LIO_WAIT, so all AIO ops should be complete by the
+// time listio returns.
#[test]
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
-fn test_lio_listio_wait() {
+fn test_liocb_listio_wait() {
const INITIAL: &[u8] = b"abcdef123456";
const WBUF: &[u8] = b"CDEF";
let mut rbuf = vec![0; 4];
@@ -522,24 +522,27 @@ fn test_lio_listio_wait() {
f.write_all(INITIAL).unwrap();
{
- let mut wcb = AioCb::from_slice( f.as_raw_fd(),
+ let wcb = AioCb::from_slice( f.as_raw_fd(),
2, //offset
WBUF,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);
- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
+ let rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
- let err = lio_listio(LioMode::LIO_WAIT, &[&mut wcb, &mut rcb], SigevNotify::SigevNone);
- err.expect("lio_listio failed");
-
- assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
- assert!(rcb.aio_return().unwrap() as usize == rlen);
+ let mut liocb = LioCb::with_capacity(2);
+ liocb.aiocbs.push(wcb);
+ liocb.aiocbs.push(rcb);
+ let err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone);
+ err.expect("lio_listio");
+
+ assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
+ assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
}
assert!(rbuf.deref().deref() == b"3456");
@@ -549,12 +552,12 @@ fn test_lio_listio_wait() {
assert!(rbuf2 == EXPECT);
}
-// Test lio_listio with LIO_NOWAIT and no SigEvent, so we must use some other
+// Test LioCb::listio with LIO_NOWAIT and no SigEvent, so we must use some other
// mechanism to check for the individual AioCb's completion.
#[test]
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
-fn test_lio_listio_nowait() {
+fn test_liocb_listio_nowait() {
const INITIAL: &[u8] = b"abcdef123456";
const WBUF: &[u8] = b"CDEF";
let mut rbuf = vec![0; 4];
@@ -566,26 +569,29 @@ fn test_lio_listio_nowait() {
f.write_all(INITIAL).unwrap();
{
- let mut wcb = AioCb::from_slice( f.as_raw_fd(),
+ let wcb = AioCb::from_slice( f.as_raw_fd(),
2, //offset
WBUF,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);
- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
+ let rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
- let err = lio_listio(LioMode::LIO_NOWAIT, &[&mut wcb, &mut rcb], SigevNotify::SigevNone);
- err.expect("lio_listio failed");
-
- poll_aio(&mut wcb).unwrap();
- poll_aio(&mut rcb).unwrap();
- assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
- assert!(rcb.aio_return().unwrap() as usize == rlen);
+ let mut liocb = LioCb::with_capacity(2);
+ liocb.aiocbs.push(wcb);
+ liocb.aiocbs.push(rcb);
+ let err = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone);
+ err.expect("lio_listio");
+
+ poll_aio(&mut liocb.aiocbs[0]).unwrap();
+ poll_aio(&mut liocb.aiocbs[1]).unwrap();
+ assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
+ assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
}
assert!(rbuf.deref().deref() == b"3456");
@@ -595,13 +601,13 @@ fn test_lio_listio_nowait() {
assert!(rbuf2 == EXPECT);
}
-// Test lio_listio with LIO_NOWAIT and a SigEvent to indicate when all AioCb's
-// are complete.
+// Test LioCb::listio with LIO_NOWAIT and a SigEvent to indicate when all
+// AioCb's are complete.
// FIXME: This test is ignored on mips/mips64 because of failures in qemu in CI.
#[test]
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
#[cfg_attr(any(target_arch = "mips", target_arch = "mips64", target_env = "musl"), ignore)]
-fn test_lio_listio_signal() {
+fn test_liocb_listio_signal() {
#[allow(unused_variables)]
let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
const INITIAL: &[u8] = b"abcdef123456";
@@ -620,29 +626,32 @@ fn test_lio_listio_signal() {
f.write_all(INITIAL).unwrap();
{
- let mut wcb = AioCb::from_slice( f.as_raw_fd(),
+ let wcb = AioCb::from_slice( f.as_raw_fd(),
2, //offset
WBUF,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);
- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
+ let rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
+ let mut liocb = LioCb::with_capacity(2);
+ liocb.aiocbs.push(wcb);
+ liocb.aiocbs.push(rcb);
SIGNALED.store(false, Ordering::Relaxed);
unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
- let err = lio_listio(LioMode::LIO_NOWAIT, &[&mut wcb, &mut rcb], sigev_notify);
- err.expect("lio_listio failed");
+ let err = liocb.listio(LioMode::LIO_NOWAIT, sigev_notify);
+ err.expect("lio_listio");
while !SIGNALED.load(Ordering::Relaxed) {
thread::sleep(time::Duration::from_millis(10));
}
- assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
- assert!(rcb.aio_return().unwrap() as usize == rlen);
+ assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
+ assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
}
assert!(rbuf.deref().deref() == b"3456");
@@ -652,22 +661,24 @@ fn test_lio_listio_signal() {
assert!(rbuf2 == EXPECT);
}
-// Try to use lio_listio to read into an immutable buffer. It should fail
+// Try to use LioCb::listio to read into an immutable buffer. It should fail
// FIXME: This test fails to panic on Linux/musl
#[test]
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
#[should_panic(expected = "Can't read into an immutable buffer")]
#[cfg_attr(target_env = "musl", ignore)]
-fn test_lio_listio_read_immutable() {
+fn test_liocb_listio_read_immutable() {
let rbuf: &[u8] = b"abcd";
let f = tempfile().unwrap();
- let mut rcb = AioCb::from_slice( f.as_raw_fd(),
- 2, //offset
- rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- LioOpcode::LIO_READ);
- let _ = lio_listio(LioMode::LIO_NOWAIT, &[&mut rcb], SigevNotify::SigevNone);
+ let mut liocb = LioCb::from(vec![
+ AioCb::from_slice( f.as_raw_fd(),
+ 2, //offset
+ rbuf,
+ 0, //priority
+ SigevNotify::SigevNone,
+ LioOpcode::LIO_READ)
+ ]);
+ let _ = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone);
}