summaryrefslogtreecommitdiffstats
path: root/third_party/rust/nix/src/sys/mman.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/nix/src/sys/mman.rs')
-rw-r--r--third_party/rust/nix/src/sys/mman.rs320
1 files changed, 174 insertions, 146 deletions
diff --git a/third_party/rust/nix/src/sys/mman.rs b/third_party/rust/nix/src/sys/mman.rs
index 8cfd6d6d54..a64f14f588 100644
--- a/third_party/rust/nix/src/sys/mman.rs
+++ b/third_party/rust/nix/src/sys/mman.rs
@@ -8,7 +8,11 @@ use crate::Result;
#[cfg(feature = "fs")]
use crate::{fcntl::OFlag, sys::stat::Mode};
use libc::{self, c_int, c_void, off_t, size_t};
-use std::{num::NonZeroUsize, os::unix::io::{AsRawFd, AsFd}};
+use std::ptr::NonNull;
+use std::{
+ num::NonZeroUsize,
+ os::unix::io::{AsFd, AsRawFd},
+};
libc_bitflags! {
/// Desired memory protection of a memory mapping.
@@ -22,12 +26,10 @@ libc_bitflags! {
/// Pages can be executed
PROT_EXEC;
/// Apply protection up to the end of a mapping that grows upwards.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
PROT_GROWSDOWN;
/// Apply protection down to the beginning of a mapping that grows downwards.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
PROT_GROWSUP;
}
}
@@ -45,145 +47,143 @@ libc_bitflags! {
MAP_FIXED;
/// Place the mapping at exactly the address specified in `addr`, but never clobber an existing range.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_FIXED_NOREPLACE;
/// To be used with `MAP_FIXED`, to forbid the system
/// to select a different address than the one specified.
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_EXCL;
/// Synonym for `MAP_ANONYMOUS`.
MAP_ANON;
/// The mapping is not backed by any file.
MAP_ANONYMOUS;
/// Put the mapping into the first 2GB of the process address space.
- #[cfg(any(all(any(target_os = "android", target_os = "linux"),
+ #[cfg(any(all(linux_android,
any(target_arch = "x86", target_arch = "x86_64")),
all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")),
all(target_os = "freebsd", target_pointer_width = "64")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_32BIT;
/// Used for stacks; indicates to the kernel that the mapping should extend downward in memory.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_GROWSDOWN;
/// Compatibility flag. Ignored.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_DENYWRITE;
/// Compatibility flag. Ignored.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_EXECUTABLE;
/// Mark the mmaped region to be locked in the same way as `mlock(2)`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_LOCKED;
/// Do not reserve swap space for this mapping.
///
/// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "aix")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(freebsdlike, target_os = "aix", target_os = "hurd")))]
MAP_NORESERVE;
/// Populate page tables for a mapping.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_POPULATE;
/// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_NONBLOCK;
/// Allocate the mapping using "huge pages."
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MAP_HUGETLB;
/// Make use of 64KB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_64KB;
/// Make use of 512KB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_512KB;
/// Make use of 1MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_1MB;
/// Make use of 2MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_2MB;
/// Make use of 8MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_8MB;
/// Make use of 16MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_16MB;
/// Make use of 32MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_32MB;
/// Make use of 256MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_256MB;
/// Make use of 512MB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_512MB;
/// Make use of 1GB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_1GB;
/// Make use of 2GB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_2GB;
/// Make use of 16GB huge page (must be supported by the system)
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_HUGE_16GB;
/// Lock the mapped region into memory as with `mlock(2)`.
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_WIRED;
/// Causes dirtied data in the specified range to be flushed to disk only when necessary.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MAP_NOSYNC;
/// Rename private pages to a file.
///
/// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(netbsdlike)]
MAP_RENAME;
/// Region may contain semaphores.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(freebsdlike, netbsdlike))]
MAP_HASSEMAPHORE;
/// Region grows down, like a stack.
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(any(linux_android, freebsdlike, target_os = "openbsd"))]
MAP_STACK;
/// Pages in this mapping are not retained in the kernel's memory cache.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MAP_NOCACHE;
/// Allows the W/X bit on the page, it's necessary on aarch64 architecture.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MAP_JIT;
/// Allows to use large pages, underlying alignment based on size.
#[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_ALIGNED_SUPER;
/// Pages will be discarded in the core dumps.
#[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_CONCEAL;
+ /// Attempt to place the mapping at exactly the address specified in `addr`.
+ /// it's a default behavior on OpenBSD.
+ #[cfg(netbsdlike)]
+ MAP_TRYFIXED;
+ }
+}
+
+impl MapFlags {
+ /// Create `MAP_HUGETLB` with provided size of huge page.
+ ///
+ /// Under the hood it computes `MAP_HUGETLB | (huge_page_size_log2 << libc::MAP_HUGE_SHIFT`).
+ /// `huge_page_size_log2` denotes logarithm of huge page size to use and should be
+ /// between 16 and 63 (inclusively).
+ ///
+ /// ```
+ /// # use nix::sys::mman::MapFlags;
+ /// let f = MapFlags::map_hugetlb_with_size_log2(30).unwrap();
+ /// assert_eq!(f, MapFlags::MAP_HUGETLB | MapFlags::MAP_HUGE_1GB);
+ /// ```
+ #[cfg(any(linux_android, target_os = "fuchsia"))]
+ pub fn map_hugetlb_with_size_log2(
+ huge_page_size_log2: u32,
+ ) -> Option<Self> {
+ if (16..=63).contains(&huge_page_size_log2) {
+ let flag = libc::MAP_HUGETLB
+ | (huge_page_size_log2 << libc::MAP_HUGE_SHIFT) as i32;
+ Some(Self(flag.into()))
+ } else {
+ None
+ }
}
}
@@ -193,19 +193,15 @@ libc_bitflags! {
pub struct MRemapFlags: c_int {
/// Permit the kernel to relocate the mapping to a new virtual address, if necessary.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MREMAP_MAYMOVE;
/// Place the mapping at exactly the address specified in `new_address`.
#[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MREMAP_FIXED;
/// Place the mapping at exactly the address specified in `new_address`.
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_FIXED;
/// Allows to duplicate the mapping to be able to apply different flags on the copy.
#[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MAP_REMAPDUP;
}
}
@@ -228,30 +224,24 @@ libc_enum! {
/// Do not expect access in the near future.
MADV_DONTNEED,
/// Free up a given range of pages and its associated backing store.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_REMOVE,
/// Do not make pages in this range available to the child after a `fork(2)`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DONTFORK,
/// Undo the effect of `MADV_DONTFORK`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DOFORK,
/// Poison the given pages.
///
/// Subsequent references to those pages are treated like hardware memory corruption.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_HWPOISON,
/// Enable Kernel Samepage Merging (KSM) for the given pages.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_MERGEABLE,
/// Undo the effect of `MADV_MERGEABLE`
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_UNMERGEABLE,
/// Preserve the memory of each page but offline the original page.
#[cfg(any(target_os = "android",
@@ -266,68 +256,52 @@ libc_enum! {
target_arch = "sparc64"))))]
MADV_SOFT_OFFLINE,
/// Enable Transparent Huge Pages (THP) for pages in the given range.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_HUGEPAGE,
/// Undo the effect of `MADV_HUGEPAGE`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_NOHUGEPAGE,
/// Exclude the given range from a core dump.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DONTDUMP,
/// Undo the effect of an earlier `MADV_DONTDUMP`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(linux_android)]
MADV_DODUMP,
/// Specify that the application no longer needs the pages in the given range.
- #[cfg(not(target_os = "aix"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(not(any(target_os = "aix", target_os = "hurd")))]
MADV_FREE,
/// Request that the system not flush the current range to disk unless it needs to.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_NOSYNC,
/// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_AUTOSYNC,
/// Region is not included in a core file.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_NOCORE,
/// Include region in a core file
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(freebsdlike)]
MADV_CORE,
/// This process should not be killed when swap space is exhausted.
#[cfg(any(target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MADV_PROTECT,
/// Invalidate the hardware page table for the given region.
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MADV_INVAL,
/// Set the offset of the page directory page to `value` for the virtual page table.
#[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
MADV_SETMAP,
/// Indicates that the application will not need the data in the given range.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MADV_ZERO_WIRED_PAGES,
/// Pages can be reused (by anyone).
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MADV_FREE_REUSABLE,
/// Caller wants to reuse those pages.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MADV_FREE_REUSE,
// Darwin doesn't document this flag's behavior.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
#[allow(missing_docs)]
MADV_CAN_REUSE,
}
@@ -341,12 +315,10 @@ libc_bitflags! {
/// Invalidate all cached data.
MS_INVALIDATE;
/// Invalidate pages, but leave them mapped.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MS_KILLPAGES;
/// Deactivate pages, but leave them mapped.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
+ #[cfg(apple_targets)]
MS_DEACTIVATE;
/// Perform an update and wait for it to complete.
MS_SYNC;
@@ -374,8 +346,8 @@ libc_bitflags! {
/// `addr` must meet all the requirements described in the [`mlock(2)`] man page.
///
/// [`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html
-pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
- Errno::result(libc::mlock(addr, length)).map(drop)
+pub unsafe fn mlock(addr: NonNull<c_void>, length: size_t) -> Result<()> {
+ unsafe { Errno::result(libc::mlock(addr.as_ptr(), length)).map(drop) }
}
/// Unlocks all memory pages that contain part of the address range with
@@ -387,8 +359,8 @@ pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
/// page.
///
/// [`munlock(2)`]: https://man7.org/linux/man-pages/man2/munlock.2.html
-pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
- Errno::result(libc::munlock(addr, length)).map(drop)
+pub unsafe fn munlock(addr: NonNull<c_void>, length: size_t) -> Result<()> {
+ unsafe { Errno::result(libc::munlock(addr.as_ptr(), length)).map(drop) }
}
/// Locks all memory pages mapped into this process' address space.
@@ -411,7 +383,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,20 +397,54 @@ 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);
+) -> Result<NonNull<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 ret =
- libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset);
+ let fd = f.as_fd().as_raw_fd();
+ let ret = unsafe {
+ libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset)
+ };
+
+ if ret == libc::MAP_FAILED {
+ Err(Errno::last())
+ } else {
+ // SAFETY: `libc::mmap` returns a valid non-null pointer or `libc::MAP_FAILED`, thus `ret`
+ // will be non-null here.
+ Ok(unsafe { NonNull::new_unchecked(ret) })
+ }
+}
+
+/// 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<NonNull<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 = unsafe {
+ libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), -1, 0)
+ };
if ret == libc::MAP_FAILED {
Err(Errno::last())
} else {
- Ok(ret)
+ // SAFETY: `libc::mmap` returns a valid non-null pointer or `libc::MAP_FAILED`, thus `ret`
+ // will be non-null here.
+ Ok(unsafe { NonNull::new_unchecked(ret) })
}
}
@@ -449,33 +457,43 @@ pub unsafe fn mmap<F: AsFd>(
/// detailed requirements.
#[cfg(any(target_os = "linux", target_os = "netbsd"))]
pub unsafe fn mremap(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
old_size: size_t,
new_size: size_t,
flags: MRemapFlags,
- new_address: Option<*mut c_void>,
-) -> Result<*mut c_void> {
+ new_address: Option<NonNull<c_void>>,
+) -> Result<NonNull<c_void>> {
#[cfg(target_os = "linux")]
- let ret = libc::mremap(
- addr,
- old_size,
- new_size,
- flags.bits(),
- new_address.unwrap_or(std::ptr::null_mut()),
- );
+ let ret = unsafe {
+ libc::mremap(
+ addr.as_ptr(),
+ old_size,
+ new_size,
+ flags.bits(),
+ new_address
+ .map(NonNull::as_ptr)
+ .unwrap_or(std::ptr::null_mut()),
+ )
+ };
#[cfg(target_os = "netbsd")]
- let ret = libc::mremap(
- addr,
- old_size,
- new_address.unwrap_or(std::ptr::null_mut()),
- new_size,
- flags.bits(),
- );
+ let ret = unsafe {
+ libc::mremap(
+ addr.as_ptr(),
+ old_size,
+ new_address
+ .map(NonNull::as_ptr)
+ .unwrap_or(std::ptr::null_mut()),
+ new_size,
+ flags.bits(),
+ )
+ };
if ret == libc::MAP_FAILED {
Err(Errno::last())
} else {
- Ok(ret)
+ // SAFETY: `libc::mremap` returns a valid non-null pointer or `libc::MAP_FAILED`, thus `ret`
+ // will be non-null here.
+ Ok(unsafe { NonNull::new_unchecked(ret) })
}
}
@@ -487,8 +505,8 @@ pub unsafe fn mremap(
/// page.
///
/// [`munmap(2)`]: https://man7.org/linux/man-pages/man2/munmap.2.html
-pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
- Errno::result(libc::munmap(addr, len)).map(drop)
+pub unsafe fn munmap(addr: NonNull<c_void>, len: size_t) -> Result<()> {
+ unsafe { Errno::result(libc::munmap(addr.as_ptr(), len)).map(drop) }
}
/// give advice about use of memory
@@ -499,12 +517,16 @@ pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
/// [`MmapAdvise::MADV_FREE`].
///
/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html
+#[allow(rustdoc::broken_intra_doc_links)] // For Hurd as `MADV_FREE` is not available on it
pub unsafe fn madvise(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
length: size_t,
advise: MmapAdvise,
) -> Result<()> {
- Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
+ unsafe {
+ Errno::result(libc::madvise(addr.as_ptr(), length, advise as i32))
+ .map(drop)
+ }
}
/// Set protection of memory mapping.
@@ -519,27 +541,30 @@ 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::<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)
+/// std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
/// };
/// assert_eq!(slice[0], 0x00);
/// slice[0] = 0xFF;
/// assert_eq!(slice[0], 0xFF);
/// ```
pub unsafe fn mprotect(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
length: size_t,
prot: ProtFlags,
) -> Result<()> {
- Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
+ unsafe {
+ Errno::result(libc::mprotect(addr.as_ptr(), length, prot.bits()))
+ .map(drop)
+ }
}
/// synchronize a mapped region
@@ -551,11 +576,14 @@ pub unsafe fn mprotect(
///
/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html
pub unsafe fn msync(
- addr: *mut c_void,
+ addr: NonNull<c_void>,
length: size_t,
flags: MsFlags,
) -> Result<()> {
- Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
+ unsafe {
+ Errno::result(libc::msync(addr.as_ptr(), length, flags.bits()))
+ .map(drop)
+ }
}
#[cfg(not(target_os = "android"))]
@@ -576,11 +604,11 @@ pub fn shm_open<P>(
use std::os::unix::io::{FromRawFd, OwnedFd};
let ret = name.with_nix_path(|cstr| {
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(apple_targets)]
unsafe {
libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint)
}
- #[cfg(not(any(target_os = "macos", target_os = "ios")))]
+ #[cfg(not(apple_targets))]
unsafe {
libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t)
}