Skip to content

Commit

Permalink
Add mmap_anonymous function
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov committed Oct 2, 2023
1 parent 2f4861f commit 8c605db
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 21 deletions.
43 changes: 36 additions & 7 deletions src/sys/mman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
Expand All @@ -423,13 +425,12 @@ pub unsafe fn mmap<F: AsFd>(
length: NonZeroUsize,
prot: ProtFlags,
flags: MapFlags,
f: Option<F>,
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);

Expand All @@ -440,6 +441,34 @@ pub unsafe fn mmap<F: AsFd>(
}
}

/// 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<NonZeroUsize>,
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.
///
Expand Down Expand Up @@ -525,8 +554,8 @@ pub unsafe fn madvise(
/// 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::<BorrowedFd>(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)
/// };
Expand Down
22 changes: 8 additions & 14 deletions test/sys/test_mman.rs
Original file line number Diff line number Diff line change
@@ -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::<BorrowedFd>(
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);
Expand All @@ -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::<BorrowedFd>(
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)
Expand Down Expand Up @@ -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::<BorrowedFd>(
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)
Expand Down

0 comments on commit 8c605db

Please sign in to comment.