1use nix::sys::mman::{mmap, MapFlags, ProtFlags}; 2use std::num::NonZeroUsize; 3 4#[test] 5fn test_mmap_anonymous() { 6 unsafe { 7 let ptr = mmap( 8 None, 9 NonZeroUsize::new(1).unwrap(), 10 ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, 11 MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, 12 -1, 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"))] 24fn 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( 33 None, 34 one_k_non_zero, 35 ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, 36 MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, 37 -1, 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)] 82fn 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( 91 None, 92 ten_one_k, 93 ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, 94 MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, 95 -1, 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