use std::ffi::CString;
use std::mem::{self, ManuallyDrop};
use std::os::unix::io::RawFd;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::ptr;
use super::{Event, Cancellation};
pub struct Statx {
pub statx: Box<libc::statx>,
path: Option<CString>,
dfd: RawFd,
flags: i32,
mask: u32,
}
impl Statx {
pub fn new(path: Option<impl AsRef<Path>>, dfd: RawFd, flags: i32, mask: u32) -> Statx {
let path = path.map(|path| {
CString::new(path.as_ref().as_os_str().as_bytes()).expect("invalid path")
});
Statx {
statx: unsafe { Box::new(mem::zeroed()) },
path, dfd, flags, mask,
}
}
}
impl Event for Statx {
unsafe fn prepare(&mut self, sqe: &mut iou::SubmissionQueueEvent<'_>) {
let statx = &mut *self.statx as *mut libc::statx;
let path = self.path.as_ref().map_or(ptr::null(), |cstring| cstring.as_ptr());
let flags = self.flags | if self.path.is_some() { libc::AT_EMPTY_PATH } else { 0 };
uring_sys::io_uring_prep_statx(sqe.raw_mut(), self.dfd, path, flags, self.mask, statx);
}
fn cancellation(this: &mut ManuallyDrop<Self>) -> Cancellation {
unsafe fn callback(statx: *mut (), path: usize) {
use std::alloc::{dealloc, Layout};
let statx: *mut u8 = statx as _;
let path: *mut u8 = path as _;
dealloc(statx as *mut u8, Layout::new::<libc::statx>());
if path != ptr::null_mut() {
}
}
let statx = &mut *this.statx as *mut libc::statx as *mut ();
let path = this.path.as_ref().map_or(ptr::null(), |cstring| cstring.as_ptr());
Cancellation::new(statx, path as usize, callback)
}
}