1
use crate::{c_size_t, c_uint, c_ulong, sys_mmap, sys_munmap, Error, FdRef};
2
use core::ffi::c_void;
3

            
4
pub struct Mmap {
5
    pointer: *mut c_void,
6
    length: usize,
7
}
8

            
9
unsafe impl Send for Mmap {}
10
unsafe impl Sync for Mmap {}
11

            
12
impl Mmap {
13
    pub unsafe fn map(
14
        address: *mut c_void,
15
        length: c_size_t,
16
        protection: c_uint,
17
        flags: c_uint,
18
        fd: Option<FdRef>,
19
        offset: c_ulong,
20
    ) -> Result<Self, Error> {
21
        let pointer = sys_mmap(address, length, protection, flags, fd, offset)?;
22
        Ok(Self { pointer, length })
23
    }
24

            
25
    fn unmap_inplace(&mut self) -> Result<(), Error> {
26
        if self.length > 0 {
27
            unsafe {
28
                sys_munmap(self.pointer, self.length)?;
29
            }
30

            
31
            self.length = 0;
32
            self.pointer = core::ptr::NonNull::<c_void>::dangling().as_ptr();
33
        }
34

            
35
        Ok(())
36
    }
37

            
38
    pub fn unmap(mut self) -> Result<(), Error> {
39
        self.unmap_inplace()
40
    }
41

            
42
    #[inline]
43
    pub fn as_ptr(&self) -> *const c_void {
44
        self.pointer
45
    }
46

            
47
    #[inline]
48
    pub fn as_mut_ptr(&self) -> *mut c_void {
49
        self.pointer
50
    }
51

            
52
    #[inline]
53
    pub fn as_slice(&self) -> &[u8] {
54
        unsafe { core::slice::from_raw_parts(self.as_ptr().cast::<u8>(), self.length) }
55
    }
56

            
57
    #[inline]
58
    pub fn as_slice_mut(&mut self) -> &mut [u8] {
59
        unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr().cast::<u8>(), self.length) }
60
    }
61

            
62
    #[inline]
63
    pub fn len(&self) -> usize {
64
        self.length
65
    }
66
}
67

            
68
impl Default for Mmap {
69
    fn default() -> Self {
70
        Self {
71
            pointer: core::ptr::NonNull::<u8>::dangling().as_ptr().cast::<c_void>(),
72
            length: 0,
73
        }
74
    }
75
}
76

            
77
impl Drop for Mmap {
78
    fn drop(&mut self) {
79
        let _ = self.unmap_inplace();
80
    }
81
}