| 1 | //! POSIX shared memory |
| 2 | //! |
| 3 | //! # Example |
| 4 | //! |
| 5 | //! ``` |
| 6 | //! use rustix::fs::{ftruncate, Mode}; |
| 7 | //! use rustix::mm::{mmap, MapFlags, ProtFlags}; |
| 8 | //! use rustix::{io, shm}; |
| 9 | //! use std::mem::size_of; |
| 10 | //! use std::ptr::null_mut; |
| 11 | //! |
| 12 | //! # fn example() -> io::Result<()> { |
| 13 | //! // A type describing the data to be shared. |
| 14 | //! #[repr(C)] |
| 15 | //! struct MyBufferType { |
| 16 | //! // … |
| 17 | //! } |
| 18 | //! |
| 19 | //! // Create the shared memory object. |
| 20 | //! let shm_path = "/rustix-shm-example" ; |
| 21 | //! let fd = shm::open( |
| 22 | //! shm_path, |
| 23 | //! shm::OFlags::CREATE | shm::OFlags::EXCL | shm::OFlags::RDWR, |
| 24 | //! Mode::RUSR | Mode::WUSR, |
| 25 | //! )?; |
| 26 | //! |
| 27 | //! // Resize the shared memory object to the size of our data. |
| 28 | //! ftruncate(&fd, size_of::<MyBufferType>() as u64)?; |
| 29 | //! |
| 30 | //! // Map the shared memory object into our address space. |
| 31 | //! // |
| 32 | //! // SAFETY: We're creating a new mapping that's independent of any existing |
| 33 | //! // memory allocations. There are interesting things to say about *using* |
| 34 | //! // `ptr`, but that's for another safety comment. |
| 35 | //! let ptr = unsafe { |
| 36 | //! mmap( |
| 37 | //! null_mut(), |
| 38 | //! size_of::<MyBufferType>(), |
| 39 | //! ProtFlags::READ | ProtFlags::WRITE, |
| 40 | //! MapFlags::SHARED, |
| 41 | //! &fd, |
| 42 | //! 0, |
| 43 | //! )? |
| 44 | //! }; |
| 45 | //! |
| 46 | //! // Use `ptr`… |
| 47 | //! |
| 48 | //! // Remove the shared memory object name. |
| 49 | //! shm::unlink(shm_path)?; |
| 50 | //! # Ok(()) |
| 51 | //! # } |
| 52 | //! ``` |
| 53 | |
| 54 | #![allow (unused_qualifications)] |
| 55 | |
| 56 | use crate::fd::OwnedFd; |
| 57 | use crate::{backend, io, path}; |
| 58 | |
| 59 | use super::shm; |
| 60 | pub use crate::backend::fs::types::Mode; |
| 61 | pub use crate::backend::shm::types::ShmOFlags as OFlags; |
| 62 | #[deprecated (note = "Use `shm::OFlags`." )] |
| 63 | #[doc (hidden)] |
| 64 | pub use crate::backend::shm::types::ShmOFlags; |
| 65 | #[deprecated (note = "Use `shm::open`." )] |
| 66 | #[doc (hidden)] |
| 67 | pub use open as shm_open; |
| 68 | #[deprecated (note = "Use `shm::unlink`." )] |
| 69 | #[doc (hidden)] |
| 70 | pub use unlink as shm_unlink; |
| 71 | |
| 72 | /// `shm_open(name, oflags, mode)`—Opens a shared memory object. |
| 73 | /// |
| 74 | /// For portability, `name` should begin with a slash, contain no other |
| 75 | /// slashes, and be no longer than an implementation-defined limit (255 on |
| 76 | /// Linux). |
| 77 | /// |
| 78 | /// Exactly one of [`shm::OFlags::RDONLY`] and [`shm::OFlags::RDWR`] should be |
| 79 | /// passed. The file descriptor will be opened with `FD_CLOEXEC` set. |
| 80 | /// |
| 81 | /// # References |
| 82 | /// - [POSIX] |
| 83 | /// - [Linux] |
| 84 | /// |
| 85 | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_open.html |
| 86 | /// [Linux]: https://man7.org/linux/man-pages/man3/shm_open.3.html |
| 87 | #[doc (alias = "shm_open" )] |
| 88 | #[inline ] |
| 89 | pub fn open<P: path::Arg>(name: P, flags: shm::OFlags, mode: Mode) -> io::Result<OwnedFd> { |
| 90 | name.into_with_c_str(|name: &CStr| backend::shm::syscalls::shm_open(name, oflags:flags, mode)) |
| 91 | } |
| 92 | |
| 93 | /// `shm_unlink(name)`—Unlinks a shared memory object. |
| 94 | /// |
| 95 | /// # References |
| 96 | /// - [POSIX] |
| 97 | /// - [Linux] |
| 98 | /// |
| 99 | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_unlink.html |
| 100 | /// [Linux]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html |
| 101 | #[doc (alias = "shm_unlink" )] |
| 102 | #[inline ] |
| 103 | pub fn unlink<P: path::Arg>(name: P) -> io::Result<()> { |
| 104 | name.into_with_c_str(backend::shm::syscalls::shm_unlink) |
| 105 | } |
| 106 | |