diff options
Diffstat (limited to 'third_party/rust/nix/src/sys/mman.rs')
-rw-r--r-- | third_party/rust/nix/src/sys/mman.rs | 320 |
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) } |