Skip to content

Commit 9793343

Browse files
committedOct 2, 2023
Add mmap_anonymous function
1 parent 2f4861f commit 9793343

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed
 

‎src/sys/mman.rs

+37-8
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,9 @@ pub fn munlockall() -> Result<()> {
411411
unsafe { Errno::result(libc::munlockall()) }.map(drop)
412412
}
413413

414-
/// allocate memory, or map files or devices into memory
414+
/// Allocate memory, or map files or devices into memory
415+
///
416+
/// For anonymous mappings (`MAP_ANON`/`MAP_ANONYMOUS`), see [mmap_anonymous].
415417
///
416418
/// # Safety
417419
///
@@ -423,13 +425,12 @@ pub unsafe fn mmap<F: AsFd>(
423425
length: NonZeroUsize,
424426
prot: ProtFlags,
425427
flags: MapFlags,
426-
f: Option<F>,
428+
f: F,
427429
offset: off_t,
428430
) -> Result<*mut c_void> {
429-
let ptr =
430-
addr.map_or(std::ptr::null_mut(), |a| usize::from(a) as *mut c_void);
431+
let ptr = addr.map_or(std::ptr::null_mut(), |a| a.get() as *mut c_void);
431432

432-
let fd = f.map(|f| f.as_fd().as_raw_fd()).unwrap_or(-1);
433+
let fd = f.as_fd().as_raw_fd();
433434
let ret =
434435
libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset);
435436

@@ -440,6 +441,34 @@ pub unsafe fn mmap<F: AsFd>(
440441
}
441442
}
442443

444+
/// Create an anonymous memory mapping.
445+
///
446+
/// This function is a wrapper around [`mmap`]:
447+
/// `mmap(ptr, len, prot, MAP_ANONYMOUS | flags, -1, 0)`.
448+
///
449+
/// # Safety
450+
///
451+
/// See the [`mmap(2)`] man page for detailed requirements.
452+
///
453+
/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
454+
pub unsafe fn mmap_anonymous(
455+
addr: Option<NonZeroUsize>,
456+
length: NonZeroUsize,
457+
prot: ProtFlags,
458+
flags: MapFlags,
459+
) -> Result<*mut c_void> {
460+
let ptr = addr.map_or(std::ptr::null_mut(), |a| a.get() as *mut c_void);
461+
462+
let flags = MapFlags::MAP_ANONYMOUS | flags;
463+
let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), -1, 0);
464+
465+
if ret == libc::MAP_FAILED {
466+
Err(Errno::last())
467+
} else {
468+
Ok(ret)
469+
}
470+
}
471+
443472
/// Expands (or shrinks) an existing memory mapping, potentially moving it at
444473
/// the same time.
445474
///
@@ -519,14 +548,14 @@ pub unsafe fn madvise(
519548
///
520549
/// ```
521550
/// # use nix::libc::size_t;
522-
/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
551+
/// # use nix::sys::mman::{mmap_anonymous, mprotect, MapFlags, ProtFlags};
523552
/// # use std::ptr;
524553
/// # use std::os::unix::io::BorrowedFd;
525554
/// const ONE_K: size_t = 1024;
526555
/// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap();
527556
/// let mut slice: &mut [u8] = unsafe {
528-
/// let mem = mmap::<BorrowedFd>(None, one_k_non_zero, ProtFlags::PROT_NONE,
529-
/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, None, 0).unwrap();
557+
/// let mem = mmap_anonymous(None, one_k_non_zero, ProtFlags::PROT_NONE, MapFlags::MAP_PRIVATE)
558+
/// .unwrap();
530559
/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
531560
/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
532561
/// };

‎test/sys/test_mman.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
2-
use std::{num::NonZeroUsize, os::unix::io::BorrowedFd};
1+
use nix::sys::mman::{mmap_anonymous, MapFlags, ProtFlags};
2+
use std::num::NonZeroUsize;
33

44
#[test]
55
fn test_mmap_anonymous() {
66
unsafe {
7-
let ptr = mmap::<BorrowedFd>(
7+
let ptr = mmap_anonymous(
88
None,
99
NonZeroUsize::new(1).unwrap(),
1010
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
11-
MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
12-
None,
13-
0,
11+
MapFlags::MAP_PRIVATE,
1412
)
1513
.unwrap() as *mut u8;
1614
assert_eq!(*ptr, 0x00u8);
@@ -29,13 +27,11 @@ fn test_mremap_grow() {
2927
let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
3028

3129
let slice: &mut [u8] = unsafe {
32-
let mem = mmap::<BorrowedFd>(
30+
let mem = mmap_anonymous(
3331
None,
3432
one_k_non_zero,
3533
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
36-
MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
37-
None,
38-
0,
34+
MapFlags::MAP_PRIVATE,
3935
)
4036
.unwrap();
4137
std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
@@ -87,13 +83,11 @@ fn test_mremap_shrink() {
8783
const ONE_K: size_t = 1024;
8884
let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
8985
let slice: &mut [u8] = unsafe {
90-
let mem = mmap::<BorrowedFd>(
86+
let mem = mmap_anonymous(
9187
None,
9288
ten_one_k,
9389
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
94-
MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
95-
None,
96-
0,
90+
MapFlags::MAP_PRIVATE,
9791
)
9892
.unwrap();
9993
std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)

0 commit comments

Comments
 (0)