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