summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/tests/mm
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/tests/mm')
-rw-r--r--vendor/rustix/tests/mm/main.rs13
-rw-r--r--vendor/rustix/tests/mm/mlock.rs79
-rw-r--r--vendor/rustix/tests/mm/mmap.rs163
-rw-r--r--vendor/rustix/tests/mm/prot.rs4
4 files changed, 259 insertions, 0 deletions
diff --git a/vendor/rustix/tests/mm/main.rs b/vendor/rustix/tests/mm/main.rs
new file mode 100644
index 000000000..ee746d900
--- /dev/null
+++ b/vendor/rustix/tests/mm/main.rs
@@ -0,0 +1,13 @@
+//! Tests for [`rustix::mm`].
+
+#![cfg(feature = "mm")]
+#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
+#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
+
+#[cfg(not(windows))]
+#[cfg(not(target_os = "wasi"))]
+mod mlock;
+#[cfg(not(windows))]
+mod mmap;
+#[cfg(not(windows))]
+mod prot;
diff --git a/vendor/rustix/tests/mm/mlock.rs b/vendor/rustix/tests/mm/mlock.rs
new file mode 100644
index 000000000..c4a1a83b5
--- /dev/null
+++ b/vendor/rustix/tests/mm/mlock.rs
@@ -0,0 +1,79 @@
+//! Tests for `mlock`.
+//!
+//! We can't easily test that it actually locks memory, but we can test that we
+//! can call it and either get success or a reasonable error message.
+
+use std::ffi::c_void;
+
+#[test]
+fn test_mlock() {
+ let mut buf = vec![0_u8; 4096];
+
+ unsafe {
+ match rustix::mm::mlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()) {
+ Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()).unwrap(),
+ // Tests won't always have enough memory or permissions, and that's ok.
+ Err(rustix::io::Errno::PERM) | Err(rustix::io::Errno::NOMEM) => {}
+ // But they shouldn't fail otherwise.
+ Err(other) => Err(other).unwrap(),
+ }
+ }
+}
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+#[test]
+fn test_mlock_with() {
+ let mut buf = vec![0_u8; 4096];
+
+ unsafe {
+ match rustix::mm::mlock_with(
+ buf.as_mut_ptr().cast::<c_void>(),
+ buf.len(),
+ rustix::mm::MlockFlags::empty(),
+ ) {
+ Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()).unwrap(),
+ // Tests won't always have enough memory or permissions, and that's ok.
+ Err(rustix::io::Errno::PERM)
+ | Err(rustix::io::Errno::NOMEM)
+ | Err(rustix::io::Errno::NOSYS) => {}
+ // But they shouldn't fail otherwise.
+ Err(other) => Err(other).unwrap(),
+ }
+ }
+}
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+#[test]
+fn test_mlock_with_onfault() {
+ // With glibc, `mlock2` with `MLOCK_ONFAULT` returns `EINVAL` if the
+ // `mlock2` system call returns `ENOSYS`. That's not what we want
+ // here though, because `ENOSYS` just means the OS doesn't have
+ // `mlock2`, while `EINVAL` may indicate a bug in rustix.
+ //
+ // To work around this, we use `libc::syscall` to make a `mlock2`
+ // syscall directly to test for `ENOSYS`, before running the main
+ // test below.
+ unsafe {
+ if libc::syscall(libc::SYS_mlock2, 0, 0) == -1 && libc_errno::errno().0 == libc::ENOSYS {
+ return;
+ }
+ }
+
+ let mut buf = vec![0_u8; 4096];
+
+ unsafe {
+ match rustix::mm::mlock_with(
+ buf.as_mut_ptr().cast::<c_void>(),
+ buf.len(),
+ rustix::mm::MlockFlags::ONFAULT,
+ ) {
+ Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::<c_void>(), buf.len()).unwrap(),
+ // Tests won't always have enough memory or permissions, and that's ok.
+ Err(rustix::io::Errno::PERM)
+ | Err(rustix::io::Errno::NOMEM)
+ | Err(rustix::io::Errno::NOSYS) => {}
+ // But they shouldn't fail otherwise.
+ Err(other) => Err(other).unwrap(),
+ }
+ }
+}
diff --git a/vendor/rustix/tests/mm/mmap.rs b/vendor/rustix/tests/mm/mmap.rs
new file mode 100644
index 000000000..6b27287d7
--- /dev/null
+++ b/vendor/rustix/tests/mm/mmap.rs
@@ -0,0 +1,163 @@
+#![cfg(not(target_os = "wasi"))]
+
+#[cfg(feature = "fs")]
+#[cfg(not(target_os = "redox"))]
+#[test]
+fn test_mmap() {
+ use rustix::fs::{cwd, openat, Mode, OFlags};
+ use rustix::io::write;
+ use rustix::mm::{mmap, munmap, MapFlags, ProtFlags};
+ use std::ptr::null_mut;
+ use std::slice;
+
+ let tmp = tempfile::tempdir().unwrap();
+ let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
+
+ let file = openat(
+ &dir,
+ "foo",
+ OFlags::CREATE | OFlags::WRONLY | OFlags::TRUNC,
+ Mode::RUSR,
+ )
+ .unwrap();
+ write(&file, &[b'a'; 8192]).unwrap();
+ drop(file);
+
+ let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap();
+ unsafe {
+ let addr = mmap(
+ null_mut(),
+ 8192,
+ ProtFlags::READ,
+ MapFlags::PRIVATE,
+ &file,
+ 0,
+ )
+ .unwrap();
+ let slice = slice::from_raw_parts(addr.cast::<u8>(), 8192);
+ assert_eq!(slice, &[b'a'; 8192]);
+
+ munmap(addr, 8192).unwrap();
+ }
+
+ let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap();
+ unsafe {
+ assert_eq!(
+ mmap(
+ null_mut(),
+ 8192,
+ ProtFlags::READ,
+ MapFlags::PRIVATE,
+ &file,
+ u64::MAX,
+ )
+ .unwrap_err()
+ .raw_os_error(),
+ libc::EINVAL
+ );
+ }
+}
+
+#[test]
+fn test_mmap_anonymous() {
+ use rustix::mm::{mmap_anonymous, munmap, MapFlags, ProtFlags};
+ use std::ptr::null_mut;
+ use std::slice;
+
+ unsafe {
+ let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
+ let slice = slice::from_raw_parts(addr.cast::<u8>(), 8192);
+ assert_eq!(slice, &[b'\0'; 8192]);
+
+ munmap(addr, 8192).unwrap();
+ }
+}
+
+#[test]
+fn test_mprotect() {
+ use rustix::mm::{mmap_anonymous, mprotect, munmap, MapFlags, MprotectFlags, ProtFlags};
+ use std::ptr::null_mut;
+ use std::slice;
+
+ unsafe {
+ let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
+
+ mprotect(addr, 8192, MprotectFlags::empty()).unwrap();
+ mprotect(addr, 8192, MprotectFlags::READ).unwrap();
+
+ let slice = slice::from_raw_parts(addr.cast::<u8>(), 8192);
+ assert_eq!(slice, &[b'\0'; 8192]);
+
+ munmap(addr, 8192).unwrap();
+ }
+}
+
+#[test]
+fn test_mlock() {
+ use rustix::mm::{mlock, mmap_anonymous, munlock, munmap, MapFlags, ProtFlags};
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ use rustix::mm::{mlock_with, MlockFlags};
+ use std::ptr::null_mut;
+
+ unsafe {
+ let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
+
+ mlock(addr, 8192).unwrap();
+ munlock(addr, 8192).unwrap();
+
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ {
+ match mlock_with(addr, 8192, MlockFlags::empty()) {
+ Err(rustix::io::Errno::NOSYS) => (),
+ Err(err) => Err(err).unwrap(),
+ Ok(()) => munlock(addr, 8192).unwrap(),
+ }
+
+ #[cfg(linux_raw)] // libc doesn't expose `MLOCK_UNFAULT` yet.
+ {
+ match mlock_with(addr, 8192, MlockFlags::ONFAULT) {
+ Err(rustix::io::Errno::NOSYS) => (),
+ Err(err) => Err(err).unwrap(),
+ Ok(()) => munlock(addr, 8192).unwrap(),
+ }
+ munlock(addr, 8192).unwrap();
+ }
+ }
+
+ munmap(addr, 8192).unwrap();
+ }
+}
+
+#[cfg(not(target_os = "redox"))]
+#[test]
+fn test_madvise() {
+ use rustix::mm::{madvise, mmap_anonymous, munmap, Advice, MapFlags, ProtFlags};
+ use std::ptr::null_mut;
+
+ unsafe {
+ let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
+
+ madvise(addr, 8192, Advice::Normal).unwrap();
+ madvise(addr, 8192, Advice::DontNeed).unwrap();
+
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ madvise(addr, 8192, Advice::LinuxDontNeed).unwrap();
+
+ munmap(addr, 8192).unwrap();
+ }
+}
+
+#[test]
+fn test_msync() {
+ use rustix::mm::{mmap_anonymous, msync, munmap, MapFlags, MsyncFlags, ProtFlags};
+ use std::ptr::null_mut;
+
+ unsafe {
+ let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap();
+
+ msync(addr, 8192, MsyncFlags::SYNC).unwrap();
+ msync(addr, 8192, MsyncFlags::ASYNC).unwrap();
+
+ munmap(addr, 8192).unwrap();
+ }
+}
diff --git a/vendor/rustix/tests/mm/prot.rs b/vendor/rustix/tests/mm/prot.rs
new file mode 100644
index 000000000..6c86a8f2a
--- /dev/null
+++ b/vendor/rustix/tests/mm/prot.rs
@@ -0,0 +1,4 @@
+#[test]
+fn test_prot_flags() {
+ assert_eq!(libc::PROT_NONE, 0);
+}