From 9793343c2d53e854232bd325371f3a6431ea349c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 2 Oct 2023 12:35:12 +0300 Subject: [PATCH 1/3] Add `mmap_anonymous` function --- src/sys/mman.rs | 45 +++++++++++++++++++++++++++++++++++-------- test/sys/test_mman.rs | 22 ++++++++------------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/sys/mman.rs b/src/sys/mman.rs index 8cfd6d6d54..af986f5ab5 100644 --- a/src/sys/mman.rs +++ b/src/sys/mman.rs @@ -411,7 +411,9 @@ pub fn munlockall() -> Result<()> { unsafe { Errno::result(libc::munlockall()) }.map(drop) } -/// allocate memory, or map files or devices into memory +/// Allocate memory, or map files or devices into memory +/// +/// For anonymous mappings (`MAP_ANON`/`MAP_ANONYMOUS`), see [mmap_anonymous]. /// /// # Safety /// @@ -423,13 +425,12 @@ pub unsafe fn mmap( length: NonZeroUsize, prot: ProtFlags, flags: MapFlags, - f: Option, + f: F, offset: off_t, ) -> Result<*mut c_void> { - let ptr = - addr.map_or(std::ptr::null_mut(), |a| usize::from(a) as *mut c_void); + let ptr = addr.map_or(std::ptr::null_mut(), |a| a.get() as *mut c_void); - let fd = f.map(|f| f.as_fd().as_raw_fd()).unwrap_or(-1); + let fd = f.as_fd().as_raw_fd(); let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset); @@ -440,6 +441,34 @@ pub unsafe fn mmap( } } +/// Create an anonymous memory mapping. +/// +/// This function is a wrapper around [`mmap`]: +/// `mmap(ptr, len, prot, MAP_ANONYMOUS | flags, -1, 0)`. +/// +/// # Safety +/// +/// See the [`mmap(2)`] man page for detailed requirements. +/// +/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html +pub unsafe fn mmap_anonymous( + addr: Option, + length: NonZeroUsize, + prot: ProtFlags, + flags: MapFlags, +) -> Result<*mut c_void> { + let ptr = addr.map_or(std::ptr::null_mut(), |a| a.get() as *mut c_void); + + let flags = MapFlags::MAP_ANONYMOUS | flags; + let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), -1, 0); + + if ret == libc::MAP_FAILED { + Err(Errno::last()) + } else { + Ok(ret) + } +} + /// Expands (or shrinks) an existing memory mapping, potentially moving it at /// the same time. /// @@ -519,14 +548,14 @@ pub unsafe fn madvise( /// /// ``` /// # use nix::libc::size_t; -/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags}; +/// # use nix::sys::mman::{mmap_anonymous, mprotect, MapFlags, ProtFlags}; /// # use std::ptr; /// # use std::os::unix::io::BorrowedFd; /// const ONE_K: size_t = 1024; /// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap(); /// let mut slice: &mut [u8] = unsafe { -/// let mem = mmap::(None, one_k_non_zero, ProtFlags::PROT_NONE, -/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, None, 0).unwrap(); +/// let mem = mmap_anonymous(None, one_k_non_zero, ProtFlags::PROT_NONE, MapFlags::MAP_PRIVATE) +/// .unwrap(); /// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap(); /// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) /// }; diff --git a/test/sys/test_mman.rs b/test/sys/test_mman.rs index 704e14f9c5..585b6d6363 100644 --- a/test/sys/test_mman.rs +++ b/test/sys/test_mman.rs @@ -1,16 +1,14 @@ -use nix::sys::mman::{mmap, MapFlags, ProtFlags}; -use std::{num::NonZeroUsize, os::unix::io::BorrowedFd}; +use nix::sys::mman::{mmap_anonymous, MapFlags, ProtFlags}; +use std::num::NonZeroUsize; #[test] fn test_mmap_anonymous() { unsafe { - let ptr = mmap::( + let ptr = mmap_anonymous( None, NonZeroUsize::new(1).unwrap(), ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, - MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, - None, - 0, + MapFlags::MAP_PRIVATE, ) .unwrap() as *mut u8; assert_eq!(*ptr, 0x00u8); @@ -29,13 +27,11 @@ fn test_mremap_grow() { let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap(); let slice: &mut [u8] = unsafe { - let mem = mmap::( + let mem = mmap_anonymous( None, one_k_non_zero, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, - MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, - None, - 0, + MapFlags::MAP_PRIVATE, ) .unwrap(); std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) @@ -87,13 +83,11 @@ fn test_mremap_shrink() { const ONE_K: size_t = 1024; let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap(); let slice: &mut [u8] = unsafe { - let mem = mmap::( + let mem = mmap_anonymous( None, ten_one_k, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, - MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, - None, - 0, + MapFlags::MAP_PRIVATE, ) .unwrap(); std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) From 21f6825fe01c241c06c40aa3ccba031db0d9ab07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 5 Nov 2023 15:43:47 +0300 Subject: [PATCH 2/3] Add changelog note --- changelog/2127.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/2127.added.md diff --git a/changelog/2127.added.md b/changelog/2127.added.md new file mode 100644 index 0000000000..c3302bb592 --- /dev/null +++ b/changelog/2127.added.md @@ -0,0 +1 @@ +Added `mmap_anonymous` function \ No newline at end of file From 6829989cd49e2aa2b9268eab34a8fc3172ea4321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 5 Nov 2023 15:56:07 +0300 Subject: [PATCH 3/3] Add changelog note for mmap change --- changelog/2127.changed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/2127.changed.md diff --git a/changelog/2127.changed.md b/changelog/2127.changed.md new file mode 100644 index 0000000000..10cfdea7ad --- /dev/null +++ b/changelog/2127.changed.md @@ -0,0 +1 @@ +`mmap` function now accepts `F` instead of `Option` \ No newline at end of file