Function nc::munmap

source ·
pub unsafe fn munmap(addr: usize, len: size_t) -> Result<(), Errno>
Expand description

Unmap files or devices from memory.

§Example

let path = "/etc/passwd";
let ret = unsafe { nc::openat(nc::AT_FDCWD, path, nc::O_RDONLY, 0o644) };
assert!(ret.is_ok());
let fd = ret.unwrap();

let mut sb = nc::stat_t::default();
let ret = unsafe { nc::fstat(fd, &mut sb) };
assert!(ret.is_ok());

let offset: usize = 0;
let length: usize = sb.st_size as usize - offset;
// Offset for mmap must be page aligned.
let pa_offset: usize = offset & !(nc::PAGE_SIZE - 1);
let map_length = length + offset - pa_offset;

let addr = unsafe {
    nc::mmap(
        0, // 0 as NULL
        map_length,
        nc::PROT_READ,
        nc::MAP_PRIVATE,
        fd,
        pa_offset as nc::off_t,
    )
};
assert!(addr.is_ok());
let addr = addr.unwrap();

let n_write = unsafe { nc::write(1, addr + offset - pa_offset, length) };
assert!(n_write.is_ok());
assert_eq!(n_write, Ok(length as nc::ssize_t));
let ret = unsafe { nc::munmap(addr, map_length) };
assert!(ret.is_ok());
let ret = unsafe { nc::close(fd) };
assert!(ret.is_ok());
Examples found in repository?
examples/mmap.rs (line 49)
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
44
45
46
47
48
49
50
51
52
53
fn main() {
    let path = "/etc/passwd";
    let fd = unsafe { nc::openat(nc::AT_FDCWD, path, nc::O_RDONLY, 0o644) };
    assert!(fd.is_ok());
    let fd = fd.unwrap();

    let mut sb = nc::stat_t::default();
    let ret = unsafe { nc::fstat(fd, &mut sb) };
    assert!(ret.is_ok());

    let offset: usize = 0;
    let length: usize = sb.st_size as usize - offset;
    // Offset for mmap must be page aligned.
    let pa_offset: usize = offset & !(nc::PAGE_SIZE - 1);
    let map_length = length + offset - pa_offset;

    #[cfg(target_arch = "arm")]
    let addr = unsafe {
        nc::mmap2(
            0, // 0 as NULL
            map_length,
            nc::PROT_READ,
            nc::MAP_PRIVATE,
            fd,
            pa_offset as nc::off_t,
        )
    };
    #[cfg(not(target_arch = "arm"))]
    let addr = unsafe {
        nc::mmap(
            0, // 0 as NULL
            map_length,
            nc::PROT_READ,
            nc::MAP_PRIVATE,
            fd,
            pa_offset as nc::off_t,
        )
    };
    assert!(addr.is_ok());

    let addr = addr.unwrap();
    let n_write = unsafe { nc::write(1, addr + offset - pa_offset, length) };
    assert!(n_write.is_ok());
    assert_eq!(n_write, Ok(length as nc::ssize_t));
    let ret = unsafe { nc::munmap(addr, map_length) };
    assert!(ret.is_ok());
    let ret = unsafe { nc::close(fd) };
    assert!(ret.is_ok());
}
More examples
Hide additional examples
examples/mprotect.rs (line 68)
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
fn main() {
    // Register SIGSEGV handler.
    let sa = nc::sigaction_t {
        sa_handler: handle_segfault as nc::sighandler_t,
        sa_flags: nc::SA_SIGINFO,
        ..nc::sigaction_t::default()
    };
    let mut old_sa = nc::sigaction_t::default();
    let ret = unsafe {
        nc::rt_sigaction(
            nc::SIGSEGV,
            &sa,
            &mut old_sa,
            mem::size_of::<nc::sigset_t>(),
        )
    };
    assert!(ret.is_ok());

    // Initialize an anonymous mapping with 4 pages.
    let map_length = 4 * nc::PAGE_SIZE;
    #[cfg(target_arch = "arm")]
    let addr = unsafe {
        nc::mmap2(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };

    #[cfg(not(target_arch = "arm"))]
    let addr = unsafe {
        nc::mmap(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };
    assert!(addr.is_ok());
    let addr = addr.unwrap();

    // Set the third page readonly. And we will run into SIGSEGV when updating it.
    let ret = unsafe { nc::mprotect(addr + 2 * nc::PAGE_SIZE, nc::PAGE_SIZE, nc::PROT_READ) };
    assert!(ret.is_ok());

    for p in addr..(addr + map_length) {
        unsafe {
            *(p as *mut u8) = 42;
        }
    }

    let ret = unsafe { nc::munmap(addr, map_length) };
    assert!(ret.is_ok());
    unsafe { nc::exit(0) };
}