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