1use core::{ffi::CStr, 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 pub const fn as_slice(&self) -> &[u8] {
39 unsafe { slice::from_raw_parts(self.ptr, self.len) }
41 }
42}
43
44impl Drop for Mmap {
45 fn drop(&mut self) {
46 unsafe { munmap(self.ptr as _, self.len).unwrap() }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn read_file() {
57 Mmap::new(c"src/lib.rs").unwrap();
58 }
59}