     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43

    use super::{AsRawFd, File};
    use core::ops::Deref;
    use core::ptr;
    use core::slice;

    pub struct Mmap {
        ptr: *mut libc::c_void,
        len: usize,
    }

    impl Mmap {
        pub unsafe fn map(file: &File, len: usize) -> Option<Mmap> {
            let ptr = libc::mmap(
                ptr::null_mut(),
                len,
                libc::PROT_READ,
                libc::MAP_PRIVATE,
                file.as_raw_fd(),
                0,
            );
            if ptr == libc::MAP_FAILED {
                return None;
            }
            Some(Mmap { ptr, len })
        }
    }

    impl Deref for Mmap {
        type Target = [u8];

        fn deref(&self) -> &[u8] {
            unsafe { slice::from_raw_parts(self.ptr as *const u8, self.len) }
        }
    }

    impl Drop for Mmap {
        fn drop(&mut self) {
            unsafe {
                let r = libc::munmap(self.ptr, self.len);
                debug_assert_eq!(r, 0);
            }
        }
    }