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 | |