1 #![allow(clippy::redundant_slicing)]
2
3 use nix::sys::mman::{mmap_anonymous, MapFlags, ProtFlags};
4 use std::num::NonZeroUsize;
5
6 #[test]
test_mmap_anonymous()7 fn test_mmap_anonymous() {
8 unsafe {
9 let mut ptr = mmap_anonymous(
10 None,
11 NonZeroUsize::new(1).unwrap(),
12 ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
13 MapFlags::MAP_PRIVATE,
14 )
15 .unwrap()
16 .cast::<u8>();
17 assert_eq!(*ptr.as_ref(), 0x00u8);
18 *ptr.as_mut() = 0xffu8;
19 assert_eq!(*ptr.as_ref(), 0xffu8);
20 }
21 }
22
23 #[test]
24 #[cfg(any(target_os = "linux", target_os = "netbsd"))]
test_mremap_grow()25 fn test_mremap_grow() {
26 use nix::libc::size_t;
27 use nix::sys::mman::{mremap, MRemapFlags};
28 use std::ptr::NonNull;
29
30 const ONE_K: size_t = 1024;
31 let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
32
33 let slice: &mut [u8] = unsafe {
34 let mem = mmap_anonymous(
35 None,
36 one_k_non_zero,
37 ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
38 MapFlags::MAP_PRIVATE,
39 )
40 .unwrap();
41 std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
42 };
43 assert_eq!(slice[ONE_K - 1], 0x00);
44 slice[ONE_K - 1] = 0xFF;
45 assert_eq!(slice[ONE_K - 1], 0xFF);
46
47 let slice: &mut [u8] = unsafe {
48 #[cfg(target_os = "linux")]
49 let mem = mremap(
50 NonNull::from(&mut slice[..]).cast(),
51 ONE_K,
52 10 * ONE_K,
53 MRemapFlags::MREMAP_MAYMOVE,
54 None,
55 )
56 .unwrap();
57 #[cfg(target_os = "netbsd")]
58 let mem = mremap(
59 NonNull::from(&mut slice[..]).cast(),
60 ONE_K,
61 10 * ONE_K,
62 MRemapFlags::MAP_REMAPDUP,
63 None,
64 )
65 .unwrap();
66 std::slice::from_raw_parts_mut(mem.cast().as_ptr(), 10 * ONE_K)
67 };
68
69 // The first KB should still have the old data in it.
70 assert_eq!(slice[ONE_K - 1], 0xFF);
71
72 // The additional range should be zero-init'd and accessible.
73 assert_eq!(slice[10 * ONE_K - 1], 0x00);
74 slice[10 * ONE_K - 1] = 0xFF;
75 assert_eq!(slice[10 * ONE_K - 1], 0xFF);
76 }
77
78 #[test]
79 #[cfg(any(target_os = "linux", target_os = "netbsd"))]
80 // Segfaults for unknown reasons under QEMU for 32-bit targets
81 #[cfg_attr(all(target_pointer_width = "32", qemu), ignore)]
test_mremap_shrink()82 fn test_mremap_shrink() {
83 use nix::libc::size_t;
84 use nix::sys::mman::{mremap, MRemapFlags};
85 use std::num::NonZeroUsize;
86 use std::ptr::NonNull;
87
88 const ONE_K: size_t = 1024;
89 let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
90 let slice: &mut [u8] = unsafe {
91 let mem = mmap_anonymous(
92 None,
93 ten_one_k,
94 ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
95 MapFlags::MAP_PRIVATE,
96 )
97 .unwrap();
98 std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
99 };
100 assert_eq!(slice[ONE_K - 1], 0x00);
101 slice[ONE_K - 1] = 0xFF;
102 assert_eq!(slice[ONE_K - 1], 0xFF);
103
104 let slice: &mut [u8] = unsafe {
105 let mem = mremap(
106 NonNull::from(&mut slice[..]).cast(),
107 ten_one_k.into(),
108 ONE_K,
109 MRemapFlags::empty(),
110 None,
111 )
112 .unwrap();
113 // Since we didn't supply MREMAP_MAYMOVE, the address should be the
114 // same.
115 assert_eq!(mem.as_ptr(), NonNull::from(&mut slice[..]).cast().as_ptr());
116 std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
117 };
118
119 // The first KB should still be accessible and have the old data in it.
120 assert_eq!(slice[ONE_K - 1], 0xFF);
121 }
122