xref: /third_party/rust/crates/rustix/tests/mm/mmap.rs (revision b8a62b91)
1#![cfg(not(target_os = "wasi"))]
2
3#[cfg(feature = "fs")]
4#[cfg(not(target_os = "redox"))]
5#[test]
6fn test_mmap() {
7    use rustix::fs::{cwd, openat, Mode, OFlags};
8    use rustix::io::write;
9    use rustix::mm::{mmap, munmap, MapFlags, ProtFlags};
10    use std::ptr::null_mut;
11    use std::slice;
12
13    let tmp = tempfile::tempdir().unwrap();
14    let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
15
16    let file = openat(
17        &dir,
18        "foo",
19        OFlags::CREATE | OFlags::WRONLY | OFlags::TRUNC,
20        Mode::RUSR,
21    )
22    .unwrap();
23    write(&file, &[b'a'; 8192]).unwrap();
24    drop(file);
25
26    let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap();
27    unsafe {
28        let addr = mmap(
29            null_mut(),
30            8192,
31            ProtFlags::READ,
32            MapFlags::PRIVATE,
33            &file,
34            0,
35        )
36        .unwrap();
37        let slice = slice::from_raw_parts(addr.cast::<u8>(), 8192);
38        assert_eq!(slice, &[b'a'; 8192]);
39
40        munmap(addr, 8192).unwrap();
41    }
42
43    let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap();
44    unsafe {
45        assert_eq!(
46            mmap(
47                null_mut(),
48                8192,
49                ProtFlags::READ,
50                MapFlags::PRIVATE,
51                &file,
52                u64::MAX,
53            )
54            .unwrap_err()
55            .raw_os_error(),
56            libc::EINVAL
57        );
58    }
59}
60
61#[test]
62fn test_mmap_anonymous() {
63    use rustix::mm::{mmap_anonymous, munmap, MapFlags, ProtFlags};
64    use std::ptr::null_mut;
65    use std::slice;
66
67    unsafe {
68        let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
69        let slice = slice::from_raw_parts(addr.cast::<u8>(), 8192);
70        assert_eq!(slice, &[b'\0'; 8192]);
71
72        munmap(addr, 8192).unwrap();
73    }
74}
75
76#[test]
77fn test_mprotect() {
78    use rustix::mm::{mmap_anonymous, mprotect, munmap, MapFlags, MprotectFlags, ProtFlags};
79    use std::ptr::null_mut;
80    use std::slice;
81
82    unsafe {
83        let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
84
85        mprotect(addr, 8192, MprotectFlags::empty()).unwrap();
86        mprotect(addr, 8192, MprotectFlags::READ).unwrap();
87
88        let slice = slice::from_raw_parts(addr.cast::<u8>(), 8192);
89        assert_eq!(slice, &[b'\0'; 8192]);
90
91        munmap(addr, 8192).unwrap();
92    }
93}
94
95#[test]
96fn test_mlock() {
97    use rustix::mm::{mlock, mmap_anonymous, munlock, munmap, MapFlags, ProtFlags};
98    #[cfg(any(target_os = "android", target_os = "linux"))]
99    use rustix::mm::{mlock_with, MlockFlags};
100    use std::ptr::null_mut;
101
102    unsafe {
103        let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
104
105        mlock(addr, 8192).unwrap();
106        munlock(addr, 8192).unwrap();
107
108        #[cfg(any(target_os = "android", target_os = "linux"))]
109        {
110            match mlock_with(addr, 8192, MlockFlags::empty()) {
111                Err(rustix::io::Errno::NOSYS) => (),
112                Err(err) => Err(err).unwrap(),
113                Ok(()) => munlock(addr, 8192).unwrap(),
114            }
115
116            #[cfg(linux_raw)] // libc doesn't expose `MLOCK_UNFAULT` yet.
117            {
118                match mlock_with(addr, 8192, MlockFlags::ONFAULT) {
119                    Err(rustix::io::Errno::NOSYS) => (),
120                    Err(err) => Err(err).unwrap(),
121                    Ok(()) => munlock(addr, 8192).unwrap(),
122                }
123                munlock(addr, 8192).unwrap();
124            }
125        }
126
127        munmap(addr, 8192).unwrap();
128    }
129}
130
131#[cfg(not(target_os = "redox"))]
132#[test]
133fn test_madvise() {
134    use rustix::mm::{madvise, mmap_anonymous, munmap, Advice, MapFlags, ProtFlags};
135    use std::ptr::null_mut;
136
137    unsafe {
138        let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
139
140        madvise(addr, 8192, Advice::Normal).unwrap();
141        madvise(addr, 8192, Advice::DontNeed).unwrap();
142
143        #[cfg(any(target_os = "android", target_os = "linux"))]
144        madvise(addr, 8192, Advice::LinuxDontNeed).unwrap();
145
146        munmap(addr, 8192).unwrap();
147    }
148}
149
150#[test]
151fn test_msync() {
152    use rustix::mm::{mmap_anonymous, msync, munmap, MapFlags, MsyncFlags, ProtFlags};
153    use std::ptr::null_mut;
154
155    unsafe {
156        let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
157
158        msync(addr, 8192, MsyncFlags::SYNC).unwrap();
159        msync(addr, 8192, MsyncFlags::ASYNC).unwrap();
160
161        munmap(addr, 8192).unwrap();
162    }
163}
164