1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#![allow(non_camel_case_types)]
use std::os::raw::{c_int, c_long, c_uint, c_ulong};
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
pub unsafe fn io_setup(nr_events: c_uint, ctx_idp: *mut aio_context_t) -> c_int {
libc::syscall(libc::SYS_io_setup, nr_events, ctx_idp) as c_int
}
pub unsafe fn io_destroy(ctx_id: aio_context_t) -> c_int {
libc::syscall(libc::SYS_io_destroy, ctx_id) as c_int
}
pub unsafe fn io_submit(ctx_id: aio_context_t, nr: c_ulong, iocbpp: *mut *mut iocb) -> c_int {
libc::syscall(libc::SYS_io_submit, ctx_id, nr, iocbpp) as c_int
}
pub unsafe fn io_cancel(ctx_id: aio_context_t, iocb: *mut iocb, result: *mut io_event) -> c_int {
libc::syscall(libc::SYS_io_cancel, ctx_id, iocb, result) as c_int
}
pub unsafe fn io_getevents(
ctx_id: aio_context_t,
min_nr: c_long,
nr: c_long,
events: *mut io_event,
timeout: *mut libc::timespec,
) -> c_int {
libc::syscall(libc::SYS_io_getevents, ctx_id, min_nr, nr, events, timeout) as c_int
}
#[cfg(test)]
mod test {
use super::*;
use std::fs::File;
use std::io;
use std::os::unix::io::AsRawFd;
use std::ptr::null_mut;
#[test]
fn read_passwd() -> io::Result<()> {
let file = File::open("/etc/passwd")?;
let mut ctx: aio_context_t = 0;
let mut r = unsafe { io_setup(128, &mut ctx) };
assert_eq!(r, 0);
let mut buf: [u8; 4096] = unsafe { std::mem::uninitialized() };
let mut iocb = iocb {
aio_fildes: file.as_raw_fd() as u32,
aio_lio_opcode: IOCB_CMD_PREAD as u16,
aio_buf: buf.as_mut_ptr() as u64,
aio_nbytes: buf.len() as u64,
..Default::default()
};
r = unsafe { io_submit(ctx, 1, [&mut iocb as *mut iocb].as_mut_ptr()) };
assert_eq!(r, 1);
let mut events = [unsafe { std::mem::uninitialized::<io_event>() }];
r = unsafe { io_getevents(ctx, 1, 1, events.as_mut_ptr(), null_mut()) };
assert_eq!(r, 1);
assert!(events[0].res > 0);
r = unsafe { io_destroy(ctx) };
assert_eq!(r, 0);
Ok(())
}
}