1 | use nix::sys::mman::{mmap, MapFlags, ProtFlags}; |
2 | use std::{num::NonZeroUsize, os::unix::io::BorrowedFd}; |
3 | |
4 | #[test] |
5 | fn test_mmap_anonymous() { |
6 | unsafe { |
7 | let ptr = mmap::<BorrowedFd>( |
8 | None, |
9 | NonZeroUsize::new(1).unwrap(), |
10 | ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, |
11 | MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, |
12 | None, |
13 | 0, |
14 | ) |
15 | .unwrap() as *mut u8; |
16 | assert_eq!(*ptr, 0x00u8); |
17 | *ptr = 0xffu8; |
18 | assert_eq!(*ptr, 0xffu8); |
19 | } |
20 | } |
21 | |
22 | #[test] |
23 | #[cfg (any(target_os = "linux" , target_os = "netbsd" ))] |
24 | fn test_mremap_grow() { |
25 | use nix::libc::{c_void, size_t}; |
26 | use nix::sys::mman::{mremap, MRemapFlags}; |
27 | |
28 | const ONE_K: size_t = 1024; |
29 | let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap(); |
30 | |
31 | let slice: &mut [u8] = unsafe { |
32 | let mem = mmap::<BorrowedFd>( |
33 | None, |
34 | one_k_non_zero, |
35 | ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, |
36 | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, |
37 | None, |
38 | 0, |
39 | ) |
40 | .unwrap(); |
41 | std::slice::from_raw_parts_mut(mem as *mut u8, 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 | slice.as_mut_ptr() as *mut c_void, |
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 | slice.as_mut_ptr() as *mut c_void, |
60 | ONE_K, |
61 | 10 * ONE_K, |
62 | MRemapFlags::MAP_REMAPDUP, |
63 | None, |
64 | ) |
65 | .unwrap(); |
66 | std::slice::from_raw_parts_mut(mem as *mut u8, 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)] |
82 | fn test_mremap_shrink() { |
83 | use nix::libc::{c_void, size_t}; |
84 | use nix::sys::mman::{mremap, MRemapFlags}; |
85 | use std::num::NonZeroUsize; |
86 | |
87 | const ONE_K: size_t = 1024; |
88 | let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap(); |
89 | let slice: &mut [u8] = unsafe { |
90 | let mem = mmap::<BorrowedFd>( |
91 | None, |
92 | ten_one_k, |
93 | ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, |
94 | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, |
95 | None, |
96 | 0, |
97 | ) |
98 | .unwrap(); |
99 | std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) |
100 | }; |
101 | assert_eq!(slice[ONE_K - 1], 0x00); |
102 | slice[ONE_K - 1] = 0xFF; |
103 | assert_eq!(slice[ONE_K - 1], 0xFF); |
104 | |
105 | let slice: &mut [u8] = unsafe { |
106 | let mem = mremap( |
107 | slice.as_mut_ptr() as *mut c_void, |
108 | ten_one_k.into(), |
109 | ONE_K, |
110 | MRemapFlags::empty(), |
111 | None, |
112 | ) |
113 | .unwrap(); |
114 | // Since we didn't supply MREMAP_MAYMOVE, the address should be the |
115 | // same. |
116 | assert_eq!(mem, slice.as_mut_ptr() as *mut c_void); |
117 | std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) |
118 | }; |
119 | |
120 | // The first KB should still be accessible and have the old data in it. |
121 | assert_eq!(slice[ONE_K - 1], 0xFF); |
122 | } |
123 | |