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