use core::{ffi::CStr, ops::Deref, ptr::null_mut, slice};
use rustix::{
fs::{self, Mode, OFlags},
io,
mm::{MapFlags, ProtFlags, mmap, munmap},
};
pub struct Mmap {
ptr: *mut u8,
len: usize,
}
impl Mmap {
pub fn new(path: &CStr) -> io::Result<Self> {
let len = fs::stat(path)?.st_size as _;
let descriptor = fs::open(path, OFlags::RDONLY, Mode::RUSR)?;
Ok(Self {
ptr: unsafe {
mmap(
null_mut(),
len,
ProtFlags::READ,
MapFlags::PRIVATE,
descriptor,
0,
)?
} as _,
len,
})
}
}
impl Deref for Mmap {
type Target = [u8];
fn deref(&self) -> &Self::Target {
unsafe { slice::from_raw_parts(self.ptr, self.len) }
}
}
impl Drop for Mmap {
fn drop(&mut self) {
unsafe { munmap(self.ptr as _, self.len).unwrap() }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_file() {
Mmap::new(c"src/lib.rs").unwrap();
}
}