azur 0.3.1

A no_std Rust crate that implements an executor/reactor and futures using io_uring
Documentation
use super::Op;
use crate::{
    buf::IoBuf,
    future::Future,
};

pub struct Openat<B: IoBuf> {
    dir: lx::RawFd,
    path: B,
    flags: u32,
    mode: u32,
}

unsafe impl<B: IoBuf> Op for Openat<B> {
    type Output = lx::Result<lx::OwnedFd>;

    fn fill_sqe(&mut self, sqe: &mut lx::io_uring_sqe) {
        sqe.opcode = lx::IORING_OP_OPENAT;
        sqe.fd = self.dir;
        sqe.op_flags = self.flags;
        sqe.addr = self.path.as_ref().as_ptr() as u64;
        sqe.len = self.mode;
    }

    fn complete(self, ret: i32) -> Self::Output {
        if let Ok(err) = lx::Error::try_from(ret) {
            Err(err)
        } else {
            Ok(lx::OwnedFd::new(ret))
        }
    }
}

/// Opens a file at path `path` from directory `dir` with the given mode and flags. This is similar
/// to the openat(2) system call in Linux.
///
/// # Safety
///
/// The memory that `path` refers to must be null-terminated.
pub unsafe fn openat_unchecked<B: IoBuf>(
    dir: &impl lx::AsRawFd,
    path: B,
    flags: u32,
    mode: u32,
) -> Future<Openat<B>> {
    Future::new(Openat {
        dir: dir.as_raw_fd(),
        path,
        flags,
        mode,
    })
}

/// Opens a file at path `path` from directory `dir` with the given mode and flags. This is similar
/// to the openat(2) system call in Linux.
///
/// # Panics
///
/// Panics if the memory that `path` refers is not null-terminated.
pub fn openat<B: IoBuf>(
    dir: &impl lx::AsRawFd,
    path: B,
    flags: u32,
    mode: u32,
) -> Future<Openat<B>> {
    if path.as_ref().last().copied() != Some(0) {
        panic!("path must be null-terminated");
    }
    unsafe { openat_unchecked(dir, path, flags, mode) }
}

/// Opens a file at path `path` with the given mode and flags. Relative paths are resolved relative
/// to the current working directory. This is similar to the open(2) system call in Linux.
///
/// # Panics
///
/// Panics if the memory that `path` refers is not null-terminated.
pub fn open<B: IoBuf>(path: B, flags: u32, mode: u32) -> Future<Openat<B>> {
    openat(&lx::AT_FDCWD, path, flags, mode)
}

#[cfg(test)]
mod tests {
    #[test]
    fn open() {
        crate::spawn(async {
            super::open(b"/dev/zero\0", lx::O_RDONLY, 0).await.unwrap();
        });
        crate::run().unwrap();
    }
}