nix/sys/mman.rs
1//! Memory management declarations.
2
3use crate::Result;
4#[cfg(not(target_os = "android"))]
5use crate::NixPath;
6use crate::errno::Errno;
7#[cfg(not(target_os = "android"))]
8#[cfg(feature = "fs")]
9use crate::{fcntl::OFlag, sys::stat::Mode};
10use libc::{self, c_int, c_void, size_t, off_t};
11use std::os::unix::io::RawFd;
12
13libc_bitflags!{
14 /// Desired memory protection of a memory mapping.
15 pub struct ProtFlags: c_int {
16 /// Pages cannot be accessed.
17 PROT_NONE;
18 /// Pages can be read.
19 PROT_READ;
20 /// Pages can be written.
21 PROT_WRITE;
22 /// Pages can be executed
23 PROT_EXEC;
24 /// Apply protection up to the end of a mapping that grows upwards.
25 #[cfg(any(target_os = "android", target_os = "linux"))]
26 #[cfg_attr(docsrs, doc(cfg(all())))]
27 PROT_GROWSDOWN;
28 /// Apply protection down to the beginning of a mapping that grows downwards.
29 #[cfg(any(target_os = "android", target_os = "linux"))]
30 #[cfg_attr(docsrs, doc(cfg(all())))]
31 PROT_GROWSUP;
32 }
33}
34
35libc_bitflags!{
36 /// Additional parameters for [`mmap`].
37 pub struct MapFlags: c_int {
38 /// Compatibility flag. Ignored.
39 MAP_FILE;
40 /// Share this mapping. Mutually exclusive with `MAP_PRIVATE`.
41 MAP_SHARED;
42 /// Create a private copy-on-write mapping. Mutually exclusive with `MAP_SHARED`.
43 MAP_PRIVATE;
44 /// Place the mapping at exactly the address specified in `addr`.
45 MAP_FIXED;
46 /// Place the mapping at exactly the address specified in `addr`, but never clobber an existing range.
47 #[cfg(target_os = "linux")]
48 #[cfg_attr(docsrs, doc(cfg(all())))]
49 MAP_FIXED_NOREPLACE;
50 /// To be used with `MAP_FIXED`, to forbid the system
51 /// to select a different address than the one specified.
52 #[cfg(target_os = "freebsd")]
53 #[cfg_attr(docsrs, doc(cfg(all())))]
54 MAP_EXCL;
55 /// Synonym for `MAP_ANONYMOUS`.
56 MAP_ANON;
57 /// The mapping is not backed by any file.
58 MAP_ANONYMOUS;
59 /// Put the mapping into the first 2GB of the process address space.
60 #[cfg(any(all(any(target_os = "android", target_os = "linux"),
61 any(target_arch = "x86", target_arch = "x86_64")),
62 all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")),
63 all(target_os = "freebsd", target_pointer_width = "64")))]
64 #[cfg_attr(docsrs, doc(cfg(all())))]
65 MAP_32BIT;
66 /// Used for stacks; indicates to the kernel that the mapping should extend downward in memory.
67 #[cfg(any(target_os = "android", target_os = "linux"))]
68 #[cfg_attr(docsrs, doc(cfg(all())))]
69 MAP_GROWSDOWN;
70 /// Compatibility flag. Ignored.
71 #[cfg(any(target_os = "android", target_os = "linux"))]
72 #[cfg_attr(docsrs, doc(cfg(all())))]
73 MAP_DENYWRITE;
74 /// Compatibility flag. Ignored.
75 #[cfg(any(target_os = "android", target_os = "linux"))]
76 #[cfg_attr(docsrs, doc(cfg(all())))]
77 MAP_EXECUTABLE;
78 /// Mark the mmaped region to be locked in the same way as `mlock(2)`.
79 #[cfg(any(target_os = "android", target_os = "linux"))]
80 #[cfg_attr(docsrs, doc(cfg(all())))]
81 MAP_LOCKED;
82 /// Do not reserve swap space for this mapping.
83 ///
84 /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
85 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd")))]
86 #[cfg_attr(docsrs, doc(cfg(all())))]
87 MAP_NORESERVE;
88 /// Populate page tables for a mapping.
89 #[cfg(any(target_os = "android", target_os = "linux"))]
90 #[cfg_attr(docsrs, doc(cfg(all())))]
91 MAP_POPULATE;
92 /// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead.
93 #[cfg(any(target_os = "android", target_os = "linux"))]
94 #[cfg_attr(docsrs, doc(cfg(all())))]
95 MAP_NONBLOCK;
96 /// Allocate the mapping using "huge pages."
97 #[cfg(any(target_os = "android", target_os = "linux"))]
98 #[cfg_attr(docsrs, doc(cfg(all())))]
99 MAP_HUGETLB;
100 /// Make use of 64KB huge page (must be supported by the system)
101 #[cfg(target_os = "linux")]
102 #[cfg_attr(docsrs, doc(cfg(all())))]
103 MAP_HUGE_64KB;
104 /// Make use of 512KB huge page (must be supported by the system)
105 #[cfg(target_os = "linux")]
106 #[cfg_attr(docsrs, doc(cfg(all())))]
107 MAP_HUGE_512KB;
108 /// Make use of 1MB huge page (must be supported by the system)
109 #[cfg(target_os = "linux")]
110 #[cfg_attr(docsrs, doc(cfg(all())))]
111 MAP_HUGE_1MB;
112 /// Make use of 2MB huge page (must be supported by the system)
113 #[cfg(target_os = "linux")]
114 #[cfg_attr(docsrs, doc(cfg(all())))]
115 MAP_HUGE_2MB;
116 /// Make use of 8MB huge page (must be supported by the system)
117 #[cfg(target_os = "linux")]
118 #[cfg_attr(docsrs, doc(cfg(all())))]
119 MAP_HUGE_8MB;
120 /// Make use of 16MB huge page (must be supported by the system)
121 #[cfg(target_os = "linux")]
122 #[cfg_attr(docsrs, doc(cfg(all())))]
123 MAP_HUGE_16MB;
124 /// Make use of 32MB huge page (must be supported by the system)
125 #[cfg(target_os = "linux")]
126 #[cfg_attr(docsrs, doc(cfg(all())))]
127 MAP_HUGE_32MB;
128 /// Make use of 256MB huge page (must be supported by the system)
129 #[cfg(target_os = "linux")]
130 #[cfg_attr(docsrs, doc(cfg(all())))]
131 MAP_HUGE_256MB;
132 /// Make use of 512MB huge page (must be supported by the system)
133 #[cfg(target_os = "linux")]
134 #[cfg_attr(docsrs, doc(cfg(all())))]
135 MAP_HUGE_512MB;
136 /// Make use of 1GB huge page (must be supported by the system)
137 #[cfg(target_os = "linux")]
138 #[cfg_attr(docsrs, doc(cfg(all())))]
139 MAP_HUGE_1GB;
140 /// Make use of 2GB huge page (must be supported by the system)
141 #[cfg(target_os = "linux")]
142 #[cfg_attr(docsrs, doc(cfg(all())))]
143 MAP_HUGE_2GB;
144 /// Make use of 16GB huge page (must be supported by the system)
145 #[cfg(target_os = "linux")]
146 #[cfg_attr(docsrs, doc(cfg(all())))]
147 MAP_HUGE_16GB;
148
149 /// Lock the mapped region into memory as with `mlock(2)`.
150 #[cfg(target_os = "netbsd")]
151 #[cfg_attr(docsrs, doc(cfg(all())))]
152 MAP_WIRED;
153 /// Causes dirtied data in the specified range to be flushed to disk only when necessary.
154 #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
155 #[cfg_attr(docsrs, doc(cfg(all())))]
156 MAP_NOSYNC;
157 /// Rename private pages to a file.
158 ///
159 /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
160 #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
161 #[cfg_attr(docsrs, doc(cfg(all())))]
162 MAP_RENAME;
163 /// Region may contain semaphores.
164 #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
165 #[cfg_attr(docsrs, doc(cfg(all())))]
166 MAP_HASSEMAPHORE;
167 /// Region grows down, like a stack.
168 #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
169 #[cfg_attr(docsrs, doc(cfg(all())))]
170 MAP_STACK;
171 /// Pages in this mapping are not retained in the kernel's memory cache.
172 #[cfg(any(target_os = "ios", target_os = "macos"))]
173 #[cfg_attr(docsrs, doc(cfg(all())))]
174 MAP_NOCACHE;
175 /// Allows the W/X bit on the page, it's necessary on aarch64 architecture.
176 #[cfg(any(target_os = "ios", target_os = "macos"))]
177 #[cfg_attr(docsrs, doc(cfg(all())))]
178 MAP_JIT;
179 /// Allows to use large pages, underlying alignment based on size.
180 #[cfg(target_os = "freebsd")]
181 #[cfg_attr(docsrs, doc(cfg(all())))]
182 MAP_ALIGNED_SUPER;
183 /// Pages will be discarded in the core dumps.
184 #[cfg(target_os = "openbsd")]
185 #[cfg_attr(docsrs, doc(cfg(all())))]
186 MAP_CONCEAL;
187 }
188}
189
190#[cfg(any(target_os = "linux", target_os = "netbsd"))]
191libc_bitflags!{
192 /// Options for [`mremap`].
193 pub struct MRemapFlags: c_int {
194 /// Permit the kernel to relocate the mapping to a new virtual address, if necessary.
195 #[cfg(target_os = "linux")]
196 #[cfg_attr(docsrs, doc(cfg(all())))]
197 MREMAP_MAYMOVE;
198 /// Place the mapping at exactly the address specified in `new_address`.
199 #[cfg(target_os = "linux")]
200 #[cfg_attr(docsrs, doc(cfg(all())))]
201 MREMAP_FIXED;
202 /// Place the mapping at exactly the address specified in `new_address`.
203 #[cfg(target_os = "netbsd")]
204 #[cfg_attr(docsrs, doc(cfg(all())))]
205 MAP_FIXED;
206 /// Allows to duplicate the mapping to be able to apply different flags on the copy.
207 #[cfg(target_os = "netbsd")]
208 #[cfg_attr(docsrs, doc(cfg(all())))]
209 MAP_REMAPDUP;
210 }
211}
212
213libc_enum!{
214 /// Usage information for a range of memory to allow for performance optimizations by the kernel.
215 ///
216 /// Used by [`madvise`].
217 #[repr(i32)]
218 #[non_exhaustive]
219 pub enum MmapAdvise {
220 /// No further special treatment. This is the default.
221 MADV_NORMAL,
222 /// Expect random page references.
223 MADV_RANDOM,
224 /// Expect sequential page references.
225 MADV_SEQUENTIAL,
226 /// Expect access in the near future.
227 MADV_WILLNEED,
228 /// Do not expect access in the near future.
229 MADV_DONTNEED,
230 /// Free up a given range of pages and its associated backing store.
231 #[cfg(any(target_os = "android", target_os = "linux"))]
232 #[cfg_attr(docsrs, doc(cfg(all())))]
233 MADV_REMOVE,
234 /// Do not make pages in this range available to the child after a `fork(2)`.
235 #[cfg(any(target_os = "android", target_os = "linux"))]
236 #[cfg_attr(docsrs, doc(cfg(all())))]
237 MADV_DONTFORK,
238 /// Undo the effect of `MADV_DONTFORK`.
239 #[cfg(any(target_os = "android", target_os = "linux"))]
240 #[cfg_attr(docsrs, doc(cfg(all())))]
241 MADV_DOFORK,
242 /// Poison the given pages.
243 ///
244 /// Subsequent references to those pages are treated like hardware memory corruption.
245 #[cfg(any(target_os = "android", target_os = "linux"))]
246 #[cfg_attr(docsrs, doc(cfg(all())))]
247 MADV_HWPOISON,
248 /// Enable Kernel Samepage Merging (KSM) for the given pages.
249 #[cfg(any(target_os = "android", target_os = "linux"))]
250 #[cfg_attr(docsrs, doc(cfg(all())))]
251 MADV_MERGEABLE,
252 /// Undo the effect of `MADV_MERGEABLE`
253 #[cfg(any(target_os = "android", target_os = "linux"))]
254 #[cfg_attr(docsrs, doc(cfg(all())))]
255 MADV_UNMERGEABLE,
256 /// Preserve the memory of each page but offline the original page.
257 #[cfg(any(target_os = "android",
258 all(target_os = "linux", any(
259 target_arch = "aarch64",
260 target_arch = "arm",
261 target_arch = "powerpc",
262 target_arch = "powerpc64",
263 target_arch = "s390x",
264 target_arch = "x86",
265 target_arch = "x86_64",
266 target_arch = "sparc64"))))]
267 MADV_SOFT_OFFLINE,
268 /// Enable Transparent Huge Pages (THP) for pages in the given range.
269 #[cfg(any(target_os = "android", target_os = "linux"))]
270 #[cfg_attr(docsrs, doc(cfg(all())))]
271 MADV_HUGEPAGE,
272 /// Undo the effect of `MADV_HUGEPAGE`.
273 #[cfg(any(target_os = "android", target_os = "linux"))]
274 #[cfg_attr(docsrs, doc(cfg(all())))]
275 MADV_NOHUGEPAGE,
276 /// Exclude the given range from a core dump.
277 #[cfg(any(target_os = "android", target_os = "linux"))]
278 #[cfg_attr(docsrs, doc(cfg(all())))]
279 MADV_DONTDUMP,
280 /// Undo the effect of an earlier `MADV_DONTDUMP`.
281 #[cfg(any(target_os = "android", target_os = "linux"))]
282 #[cfg_attr(docsrs, doc(cfg(all())))]
283 MADV_DODUMP,
284 /// Specify that the application no longer needs the pages in the given range.
285 MADV_FREE,
286 /// Request that the system not flush the current range to disk unless it needs to.
287 #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
288 #[cfg_attr(docsrs, doc(cfg(all())))]
289 MADV_NOSYNC,
290 /// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range.
291 #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
292 #[cfg_attr(docsrs, doc(cfg(all())))]
293 MADV_AUTOSYNC,
294 /// Region is not included in a core file.
295 #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
296 #[cfg_attr(docsrs, doc(cfg(all())))]
297 MADV_NOCORE,
298 /// Include region in a core file
299 #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
300 #[cfg_attr(docsrs, doc(cfg(all())))]
301 MADV_CORE,
302 /// This process should not be killed when swap space is exhausted.
303 #[cfg(any(target_os = "freebsd"))]
304 #[cfg_attr(docsrs, doc(cfg(all())))]
305 MADV_PROTECT,
306 /// Invalidate the hardware page table for the given region.
307 #[cfg(target_os = "dragonfly")]
308 #[cfg_attr(docsrs, doc(cfg(all())))]
309 MADV_INVAL,
310 /// Set the offset of the page directory page to `value` for the virtual page table.
311 #[cfg(target_os = "dragonfly")]
312 #[cfg_attr(docsrs, doc(cfg(all())))]
313 MADV_SETMAP,
314 /// Indicates that the application will not need the data in the given range.
315 #[cfg(any(target_os = "ios", target_os = "macos"))]
316 #[cfg_attr(docsrs, doc(cfg(all())))]
317 MADV_ZERO_WIRED_PAGES,
318 /// Pages can be reused (by anyone).
319 #[cfg(any(target_os = "ios", target_os = "macos"))]
320 #[cfg_attr(docsrs, doc(cfg(all())))]
321 MADV_FREE_REUSABLE,
322 /// Caller wants to reuse those pages.
323 #[cfg(any(target_os = "ios", target_os = "macos"))]
324 #[cfg_attr(docsrs, doc(cfg(all())))]
325 MADV_FREE_REUSE,
326 // Darwin doesn't document this flag's behavior.
327 #[cfg(any(target_os = "ios", target_os = "macos"))]
328 #[cfg_attr(docsrs, doc(cfg(all())))]
329 #[allow(missing_docs)]
330 MADV_CAN_REUSE,
331 }
332}
333
334libc_bitflags!{
335 /// Configuration flags for [`msync`].
336 pub struct MsFlags: c_int {
337 /// Schedule an update but return immediately.
338 MS_ASYNC;
339 /// Invalidate all cached data.
340 MS_INVALIDATE;
341 /// Invalidate pages, but leave them mapped.
342 #[cfg(any(target_os = "ios", target_os = "macos"))]
343 #[cfg_attr(docsrs, doc(cfg(all())))]
344 MS_KILLPAGES;
345 /// Deactivate pages, but leave them mapped.
346 #[cfg(any(target_os = "ios", target_os = "macos"))]
347 #[cfg_attr(docsrs, doc(cfg(all())))]
348 MS_DEACTIVATE;
349 /// Perform an update and wait for it to complete.
350 MS_SYNC;
351 }
352}
353
354libc_bitflags!{
355 /// Flags for [`mlockall`].
356 pub struct MlockAllFlags: c_int {
357 /// Lock pages that are currently mapped into the address space of the process.
358 MCL_CURRENT;
359 /// Lock pages which will become mapped into the address space of the process in the future.
360 MCL_FUTURE;
361 }
362}
363
364/// Locks all memory pages that contain part of the address range with `length`
365/// bytes starting at `addr`.
366///
367/// Locked pages never move to the swap area.
368///
369/// # Safety
370///
371/// `addr` must meet all the requirements described in the [`mlock(2)`] man page.
372///
373/// [`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html
374pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
375 Errno::result(libc::mlock(addr, length)).map(drop)
376}
377
378/// Unlocks all memory pages that contain part of the address range with
379/// `length` bytes starting at `addr`.
380///
381/// # Safety
382///
383/// `addr` must meet all the requirements described in the [`munlock(2)`] man
384/// page.
385///
386/// [`munlock(2)`]: https://man7.org/linux/man-pages/man2/munlock.2.html
387pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
388 Errno::result(libc::munlock(addr, length)).map(drop)
389}
390
391/// Locks all memory pages mapped into this process' address space.
392///
393/// Locked pages never move to the swap area. For more information, see [`mlockall(2)`].
394///
395/// [`mlockall(2)`]: https://man7.org/linux/man-pages/man2/mlockall.2.html
396pub fn mlockall(flags: MlockAllFlags) -> Result<()> {
397 unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop)
398}
399
400/// Unlocks all memory pages mapped into this process' address space.
401///
402/// For more information, see [`munlockall(2)`].
403///
404/// [`munlockall(2)`]: https://man7.org/linux/man-pages/man2/munlockall.2.html
405pub fn munlockall() -> Result<()> {
406 unsafe { Errno::result(libc::munlockall()) }.map(drop)
407}
408
409/// allocate memory, or map files or devices into memory
410///
411/// # Safety
412///
413/// See the [`mmap(2)`] man page for detailed requirements.
414///
415/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
416pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
417 let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset);
418
419 if ret == libc::MAP_FAILED {
420 Err(Errno::last())
421 } else {
422 Ok(ret)
423 }
424}
425
426/// Expands (or shrinks) an existing memory mapping, potentially moving it at
427/// the same time.
428///
429/// # Safety
430///
431/// See the `mremap(2)` [man page](https://man7.org/linux/man-pages/man2/mremap.2.html) for
432/// detailed requirements.
433#[cfg(any(target_os = "linux", target_os = "netbsd"))]
434pub unsafe fn mremap(
435 addr: *mut c_void,
436 old_size: size_t,
437 new_size: size_t,
438 flags: MRemapFlags,
439 new_address: Option<* mut c_void>,
440) -> Result<*mut c_void> {
441 #[cfg(target_os = "linux")]
442 let ret = libc::mremap(addr, old_size, new_size, flags.bits(), new_address.unwrap_or(std::ptr::null_mut()));
443 #[cfg(target_os = "netbsd")]
444 let ret = libc::mremap(
445 addr,
446 old_size,
447 new_address.unwrap_or(std::ptr::null_mut()),
448 new_size,
449 flags.bits(),
450 );
451
452 if ret == libc::MAP_FAILED {
453 Err(Errno::last())
454 } else {
455 Ok(ret)
456 }
457}
458
459/// remove a mapping
460///
461/// # Safety
462///
463/// `addr` must meet all the requirements described in the [`munmap(2)`] man
464/// page.
465///
466/// [`munmap(2)`]: https://man7.org/linux/man-pages/man2/munmap.2.html
467pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
468 Errno::result(libc::munmap(addr, len)).map(drop)
469}
470
471/// give advice about use of memory
472///
473/// # Safety
474///
475/// See the [`madvise(2)`] man page. Take special care when using
476/// [`MmapAdvise::MADV_FREE`].
477///
478/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html
479pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
480 Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
481}
482
483/// Set protection of memory mapping.
484///
485/// See [`mprotect(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for
486/// details.
487///
488/// # Safety
489///
490/// Calls to `mprotect` are inherently unsafe, as changes to memory protections can lead to
491/// SIGSEGVs.
492///
493/// ```
494/// # use nix::libc::size_t;
495/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
496/// # use std::ptr;
497/// const ONE_K: size_t = 1024;
498/// let mut slice: &mut [u8] = unsafe {
499/// let mem = mmap(ptr::null_mut(), ONE_K, ProtFlags::PROT_NONE,
500/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap();
501/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
502/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
503/// };
504/// assert_eq!(slice[0], 0x00);
505/// slice[0] = 0xFF;
506/// assert_eq!(slice[0], 0xFF);
507/// ```
508pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Result<()> {
509 Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
510}
511
512/// synchronize a mapped region
513///
514/// # Safety
515///
516/// `addr` must meet all the requirements described in the [`msync(2)`] man
517/// page.
518///
519/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html
520pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> {
521 Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
522}
523
524#[cfg(not(target_os = "android"))]
525feature! {
526#![feature = "fs"]
527/// Creates and opens a new, or opens an existing, POSIX shared memory object.
528///
529/// For more information, see [`shm_open(3)`].
530///
531/// [`shm_open(3)`]: https://man7.org/linux/man-pages/man3/shm_open.3.html
532pub fn shm_open<P>(
533 name: &P,
534 flag: OFlag,
535 mode: Mode
536 ) -> Result<RawFd>
537 where P: ?Sized + NixPath
538{
539 let ret = name.with_nix_path(|cstr| {
540 #[cfg(any(target_os = "macos", target_os = "ios"))]
541 unsafe {
542 libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint)
543 }
544 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
545 unsafe {
546 libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t)
547 }
548 })?;
549
550 Errno::result(ret)
551}
552}
553
554/// Performs the converse of [`shm_open`], removing an object previously created.
555///
556/// For more information, see [`shm_unlink(3)`].
557///
558/// [`shm_unlink(3)`]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html
559#[cfg(not(target_os = "android"))]
560pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
561 let ret = name.with_nix_path(|cstr| {
562 unsafe { libc::shm_unlink(cstr.as_ptr()) }
563 })?;
564
565 Errno::result(ret).map(drop)
566}