1use core::{ffi::CStr, ops::Deref, ptr::null_mut, slice};
2use rustix::{
3 fs::{self, Mode, OFlags},
4 io,
5 mm::{MapFlags, ProtFlags, mmap, munmap},
6};
7
8pub struct Mmap {
10 ptr: *mut u8,
11 len: usize,
12}
13
14impl Mmap {
15 pub fn new(path: &CStr) -> io::Result<Self> {
17 let len = fs::stat(path)?.st_size as _;
18 let descriptor = fs::open(path, OFlags::RDONLY, Mode::RUSR)?;
20
21 Ok(Self {
22 ptr: unsafe {
24 mmap(
25 null_mut(),
26 len,
27 ProtFlags::READ,
28 MapFlags::PRIVATE,
29 descriptor,
30 0,
31 )?
32 } as _,
33 len,
34 })
35 }
36}
37
38impl Deref for Mmap {
39 type Target = [u8];
40
41 fn deref(&self) -> &Self::Target {
42 unsafe { slice::from_raw_parts(self.ptr, self.len) }
44 }
45}
46
47impl Drop for Mmap {
48 fn drop(&mut self) {
49 unsafe { munmap(self.ptr as _, self.len).unwrap() }
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn read_file() {
60 Mmap::new(c"src/lib.rs").unwrap();
61 }
62}