1//! Tests for `mlock`. 2//! 3//! We can't easily test that it actually locks memory, but we can test that we 4//! can call it and either get success or a reasonable error message. 5 6use std::ffi::c_void; 7 8#[test] 9fn test_mlock() { 10 let mut buf = vec![0_u8; 4096]; 11 12 unsafe { 13 match rustix::mm::mlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()) { 14 Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()).unwrap(), 15 // Tests won't always have enough memory or permissions, and that's ok. 16 Err(rustix::io::Errno::PERM) | Err(rustix::io::Errno::NOMEM) => {} 17 // But they shouldn't fail otherwise. 18 Err(other) => Err(other).unwrap(), 19 } 20 } 21} 22 23#[cfg(any(target_os = "android", target_os = "linux"))] 24#[test] 25fn test_mlock_with() { 26 let mut buf = vec![0_u8; 4096]; 27 28 unsafe { 29 match rustix::mm::mlock_with( 30 buf.as_mut_ptr().cast::<c_void>(), 31 buf.len(), 32 rustix::mm::MlockFlags::empty(), 33 ) { 34 Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()).unwrap(), 35 // Tests won't always have enough memory or permissions, and that's ok. 36 Err(rustix::io::Errno::PERM) 37 | Err(rustix::io::Errno::NOMEM) 38 | Err(rustix::io::Errno::NOSYS) => {} 39 // But they shouldn't fail otherwise. 40 Err(other) => Err(other).unwrap(), 41 } 42 } 43} 44 45#[cfg(any(target_os = "android", target_os = "linux"))] 46#[test] 47fn test_mlock_with_onfault() { 48 // With glibc, `mlock2` with `MLOCK_ONFAULT` returns `EINVAL` if the 49 // `mlock2` system call returns `ENOSYS`. That's not what we want 50 // here though, because `ENOSYS` just means the OS doesn't have 51 // `mlock2`, while `EINVAL` may indicate a bug in rustix. 52 // 53 // To work around this, we use `libc::syscall` to make a `mlock2` 54 // syscall directly to test for `ENOSYS`, before running the main 55 // test below. 56 unsafe { 57 if libc::syscall(libc::SYS_mlock2, 0, 0) == -1 && libc_errno::errno().0 == libc::ENOSYS { 58 return; 59 } 60 } 61 62 let mut buf = vec![0_u8; 4096]; 63 64 unsafe { 65 match rustix::mm::mlock_with( 66 buf.as_mut_ptr().cast::<c_void>(), 67 buf.len(), 68 rustix::mm::MlockFlags::ONFAULT, 69 ) { 70 Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()).unwrap(), 71 // Tests won't always have enough memory or permissions, and that's ok. 72 Err(rustix::io::Errno::PERM) 73 | Err(rustix::io::Errno::NOMEM) 74 | Err(rustix::io::Errno::NOSYS) => {} 75 // But they shouldn't fail otherwise. 76 Err(other) => Err(other).unwrap(), 77 } 78 } 79} 80