13da5c369Sopenharmony_ciuse nix::sys::mman::{mmap, MapFlags, ProtFlags};
23da5c369Sopenharmony_ciuse std::num::NonZeroUsize;
33da5c369Sopenharmony_ci
43da5c369Sopenharmony_ci#[test]
53da5c369Sopenharmony_cifn test_mmap_anonymous() {
63da5c369Sopenharmony_ci    unsafe {
73da5c369Sopenharmony_ci        let ptr = mmap(
83da5c369Sopenharmony_ci            None,
93da5c369Sopenharmony_ci            NonZeroUsize::new(1).unwrap(),
103da5c369Sopenharmony_ci            ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
113da5c369Sopenharmony_ci            MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
123da5c369Sopenharmony_ci            -1,
133da5c369Sopenharmony_ci            0,
143da5c369Sopenharmony_ci        )
153da5c369Sopenharmony_ci        .unwrap() as *mut u8;
163da5c369Sopenharmony_ci        assert_eq!(*ptr, 0x00u8);
173da5c369Sopenharmony_ci        *ptr = 0xffu8;
183da5c369Sopenharmony_ci        assert_eq!(*ptr, 0xffu8);
193da5c369Sopenharmony_ci    }
203da5c369Sopenharmony_ci}
213da5c369Sopenharmony_ci
223da5c369Sopenharmony_ci#[test]
233da5c369Sopenharmony_ci#[cfg(any(target_os = "linux", target_os = "netbsd"))]
243da5c369Sopenharmony_cifn test_mremap_grow() {
253da5c369Sopenharmony_ci    use nix::libc::{c_void, size_t};
263da5c369Sopenharmony_ci    use nix::sys::mman::{mremap, MRemapFlags};
273da5c369Sopenharmony_ci
283da5c369Sopenharmony_ci    const ONE_K: size_t = 1024;
293da5c369Sopenharmony_ci    let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
303da5c369Sopenharmony_ci
313da5c369Sopenharmony_ci    let slice: &mut [u8] = unsafe {
323da5c369Sopenharmony_ci        let mem = mmap(
333da5c369Sopenharmony_ci            None,
343da5c369Sopenharmony_ci            one_k_non_zero,
353da5c369Sopenharmony_ci            ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
363da5c369Sopenharmony_ci            MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
373da5c369Sopenharmony_ci            -1,
383da5c369Sopenharmony_ci            0,
393da5c369Sopenharmony_ci        )
403da5c369Sopenharmony_ci        .unwrap();
413da5c369Sopenharmony_ci        std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
423da5c369Sopenharmony_ci    };
433da5c369Sopenharmony_ci    assert_eq!(slice[ONE_K - 1], 0x00);
443da5c369Sopenharmony_ci    slice[ONE_K - 1] = 0xFF;
453da5c369Sopenharmony_ci    assert_eq!(slice[ONE_K - 1], 0xFF);
463da5c369Sopenharmony_ci
473da5c369Sopenharmony_ci    let slice: &mut [u8] = unsafe {
483da5c369Sopenharmony_ci        #[cfg(target_os = "linux")]
493da5c369Sopenharmony_ci        let mem = mremap(
503da5c369Sopenharmony_ci            slice.as_mut_ptr() as *mut c_void,
513da5c369Sopenharmony_ci            ONE_K,
523da5c369Sopenharmony_ci            10 * ONE_K,
533da5c369Sopenharmony_ci            MRemapFlags::MREMAP_MAYMOVE,
543da5c369Sopenharmony_ci            None,
553da5c369Sopenharmony_ci        )
563da5c369Sopenharmony_ci        .unwrap();
573da5c369Sopenharmony_ci        #[cfg(target_os = "netbsd")]
583da5c369Sopenharmony_ci        let mem = mremap(
593da5c369Sopenharmony_ci            slice.as_mut_ptr() as *mut c_void,
603da5c369Sopenharmony_ci            ONE_K,
613da5c369Sopenharmony_ci            10 * ONE_K,
623da5c369Sopenharmony_ci            MRemapFlags::MAP_REMAPDUP,
633da5c369Sopenharmony_ci            None,
643da5c369Sopenharmony_ci        )
653da5c369Sopenharmony_ci        .unwrap();
663da5c369Sopenharmony_ci        std::slice::from_raw_parts_mut(mem as *mut u8, 10 * ONE_K)
673da5c369Sopenharmony_ci    };
683da5c369Sopenharmony_ci
693da5c369Sopenharmony_ci    // The first KB should still have the old data in it.
703da5c369Sopenharmony_ci    assert_eq!(slice[ONE_K - 1], 0xFF);
713da5c369Sopenharmony_ci
723da5c369Sopenharmony_ci    // The additional range should be zero-init'd and accessible.
733da5c369Sopenharmony_ci    assert_eq!(slice[10 * ONE_K - 1], 0x00);
743da5c369Sopenharmony_ci    slice[10 * ONE_K - 1] = 0xFF;
753da5c369Sopenharmony_ci    assert_eq!(slice[10 * ONE_K - 1], 0xFF);
763da5c369Sopenharmony_ci}
773da5c369Sopenharmony_ci
783da5c369Sopenharmony_ci#[test]
793da5c369Sopenharmony_ci#[cfg(any(target_os = "linux", target_os = "netbsd"))]
803da5c369Sopenharmony_ci// Segfaults for unknown reasons under QEMU for 32-bit targets
813da5c369Sopenharmony_ci#[cfg_attr(all(target_pointer_width = "32", qemu), ignore)]
823da5c369Sopenharmony_cifn test_mremap_shrink() {
833da5c369Sopenharmony_ci    use nix::libc::{c_void, size_t};
843da5c369Sopenharmony_ci    use nix::sys::mman::{mremap, MRemapFlags};
853da5c369Sopenharmony_ci    use std::num::NonZeroUsize;
863da5c369Sopenharmony_ci
873da5c369Sopenharmony_ci    const ONE_K: size_t = 1024;
883da5c369Sopenharmony_ci    let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
893da5c369Sopenharmony_ci    let slice: &mut [u8] = unsafe {
903da5c369Sopenharmony_ci        let mem = mmap(
913da5c369Sopenharmony_ci            None,
923da5c369Sopenharmony_ci            ten_one_k,
933da5c369Sopenharmony_ci            ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
943da5c369Sopenharmony_ci            MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
953da5c369Sopenharmony_ci            -1,
963da5c369Sopenharmony_ci            0,
973da5c369Sopenharmony_ci        )
983da5c369Sopenharmony_ci        .unwrap();
993da5c369Sopenharmony_ci        std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
1003da5c369Sopenharmony_ci    };
1013da5c369Sopenharmony_ci    assert_eq!(slice[ONE_K - 1], 0x00);
1023da5c369Sopenharmony_ci    slice[ONE_K - 1] = 0xFF;
1033da5c369Sopenharmony_ci    assert_eq!(slice[ONE_K - 1], 0xFF);
1043da5c369Sopenharmony_ci
1053da5c369Sopenharmony_ci    let slice: &mut [u8] = unsafe {
1063da5c369Sopenharmony_ci        let mem = mremap(
1073da5c369Sopenharmony_ci            slice.as_mut_ptr() as *mut c_void,
1083da5c369Sopenharmony_ci            ten_one_k.into(),
1093da5c369Sopenharmony_ci            ONE_K,
1103da5c369Sopenharmony_ci            MRemapFlags::empty(),
1113da5c369Sopenharmony_ci            None,
1123da5c369Sopenharmony_ci        )
1133da5c369Sopenharmony_ci        .unwrap();
1143da5c369Sopenharmony_ci        // Since we didn't supply MREMAP_MAYMOVE, the address should be the
1153da5c369Sopenharmony_ci        // same.
1163da5c369Sopenharmony_ci        assert_eq!(mem, slice.as_mut_ptr() as *mut c_void);
1173da5c369Sopenharmony_ci        std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
1183da5c369Sopenharmony_ci    };
1193da5c369Sopenharmony_ci
1203da5c369Sopenharmony_ci    // The first KB should still be accessible and have the old data in it.
1213da5c369Sopenharmony_ci    assert_eq!(slice[ONE_K - 1], 0xFF);
1223da5c369Sopenharmony_ci}
123