Skip to content

Commit

Permalink
Disallow aio_read on an AioCb created with from_boxed_slice
Browse files Browse the repository at this point in the history
  • Loading branch information
asomers committed Jan 13, 2018
1 parent 6a00ded commit accaf58
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Use native `pipe2` on all BSD targets. Users should notice no difference.
([#777](https://github.com/nix-rust/nix/pull/777))
- `AioCb::from_boxed_slice` no longer allows `aio_read`
([#TODO](https://github.com/nix-rust/nix/pull/TODO))
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
- Marked `sys::ptrace::ptrace` as `unsafe`.
- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument
Expand Down
2 changes: 1 addition & 1 deletion src/sys/aio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<'a> AioCb<'a> {

AioCb {
aiocb: a,
mutable: true,
mutable: false,
in_progress: false,
keeper: Keeper::boxed(buf)
}
Expand Down
80 changes: 56 additions & 24 deletions test/sys/test_aio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ fn test_fsync_error() {
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
fn test_aio_suspend() {
const INITIAL: &[u8] = b"abcdef123456";
const WBUF: &[u8] = b"CDEF";
const WBUF: &[u8] = b"CDEFG";
let timeout = TimeSpec::seconds(10);
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
let mut rbuf = vec![0; 4];
let rlen = rbuf.len();
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();

Expand All @@ -148,9 +149,9 @@ fn test_aio_suspend() {
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);

let mut rcb = AioCb::from_boxed_slice( f.as_raw_fd(),
let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
Rc::clone(&rbuf),
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
Expand All @@ -168,7 +169,7 @@ fn test_aio_suspend() {
}

assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
assert!(rcb.aio_return().unwrap() as usize == rlen);
}

// Test a simple aio operation with no completion notification. We must poll
Expand All @@ -177,14 +178,14 @@ fn test_aio_suspend() {
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
fn test_read() {
const INITIAL: &[u8] = b"abcdef123456";
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
let mut rbuf = vec![0; 4];
const EXPECT: &[u8] = b"cdef";
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
{
let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
2, //offset
Rc::clone(&rbuf),
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_NOP);
Expand All @@ -206,12 +207,12 @@ fn test_read() {
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
fn test_read_error() {
const INITIAL: &[u8] = b"abcdef123456";
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
let mut rbuf = vec![0; 4];
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
-1, //an invalid offset
Rc::clone(&rbuf),
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_NOP);
Expand Down Expand Up @@ -322,10 +323,38 @@ fn test_write() {
assert!(rbuf == EXPECT);
}

// Tests `AioCb::from_boxed_slice`
#[test]
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
fn test_write_boxed_slice() {
const INITIAL: &'static [u8] = b"abcdef123456";
let wbuf = Rc::new(String::from("CDEF").into_bytes().into_boxed_slice());
let mut rbuf = Vec::new();
const EXPECT: &'static [u8] = b"abCDEF123456";

let mut f = tempfile().unwrap();
f.write(INITIAL).unwrap();
let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
2, //offset
wbuf.clone(),
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_NOP);
aiocb.write().unwrap();

let err = poll_aio(&mut aiocb);
assert!(err == Ok(()));
assert!(aiocb.aio_return().unwrap() as usize == wbuf.len());

f.seek(SeekFrom::Start(0)).unwrap();
let len = f.read_to_end(&mut rbuf).unwrap();
assert!(len == EXPECT.len());
assert!(rbuf == EXPECT);
}
// Tests `AioCb::from_ptr`
#[test]
#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
fn test_write_into_pointer() {
fn test_write_from_pointer() {
const INITIAL: &'static [u8] = b"abcdef123456";
let wbuf = "CDEF".to_string().into_bytes();
let mut rbuf = Vec::new();
Expand Down Expand Up @@ -429,7 +458,8 @@ fn test_write_sigev_signal() {
fn test_lio_listio_wait() {
const INITIAL: &[u8] = b"abcdef123456";
const WBUF: &[u8] = b"CDEF";
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
let mut rbuf = vec![0; 4];
let rlen = rbuf.len();
let mut rbuf2 = Vec::new();
const EXPECT: &[u8] = b"abCDEF123456";
let mut f = tempfile().unwrap();
Expand All @@ -444,17 +474,17 @@ fn test_lio_listio_wait() {
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);

let mut rcb = AioCb::from_boxed_slice( f.as_raw_fd(),
let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
Rc::clone(&rbuf),
&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 == WBUF.len());
assert!(rcb.aio_return().unwrap() as usize == rlen);
}
assert!(rbuf.deref().deref() == b"3456");

Expand All @@ -472,7 +502,8 @@ fn test_lio_listio_wait() {
fn test_lio_listio_nowait() {
const INITIAL: &[u8] = b"abcdef123456";
const WBUF: &[u8] = b"CDEF";
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
let mut rbuf = vec![0; 4];
let rlen = rbuf.len();
let mut rbuf2 = Vec::new();
const EXPECT: &[u8] = b"abCDEF123456";
let mut f = tempfile().unwrap();
Expand All @@ -487,9 +518,9 @@ fn test_lio_listio_nowait() {
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);

let mut rcb = AioCb::from_boxed_slice( f.as_raw_fd(),
let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
Rc::clone(&rbuf),
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
Expand All @@ -499,7 +530,7 @@ fn test_lio_listio_nowait() {
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 == WBUF.len());
assert!(rcb.aio_return().unwrap() as usize == rlen);
}
assert!(rbuf.deref().deref() == b"3456");

Expand All @@ -520,7 +551,8 @@ fn test_lio_listio_signal() {
let m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
const INITIAL: &[u8] = b"abcdef123456";
const WBUF: &[u8] = b"CDEF";
let rbuf = Rc::new(vec![0; 4].into_boxed_slice());
let mut rbuf = vec![0; 4];
let rlen = rbuf.len();
let mut rbuf2 = Vec::new();
const EXPECT: &[u8] = b"abCDEF123456";
let mut f = tempfile().unwrap();
Expand All @@ -540,9 +572,9 @@ fn test_lio_listio_signal() {
SigevNotify::SigevNone,
LioOpcode::LIO_WRITE);

let mut rcb = AioCb::from_boxed_slice( f.as_raw_fd(),
let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
8, //offset
Rc::clone(&rbuf),
&mut rbuf,
0, //priority
SigevNotify::SigevNone,
LioOpcode::LIO_READ);
Expand All @@ -555,7 +587,7 @@ fn test_lio_listio_signal() {
}

assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
assert!(rcb.aio_return().unwrap() as usize == WBUF.len());
assert!(rcb.aio_return().unwrap() as usize == rlen);
}
assert!(rbuf.deref().deref() == b"3456");

Expand Down

0 comments on commit accaf58

Please sign in to comment.