rustix/
shm.rs

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
56use crate::fd::OwnedFd;
57use crate::{backend, io, path};
58
59use super::shm;
60pub use crate::backend::fs::types::Mode;
61pub use crate::backend::shm::types::ShmOFlags as OFlags;
62#[deprecated(note = "Use `shm::OFlags`.")]
63#[doc(hidden)]
64pub use crate::backend::shm::types::ShmOFlags;
65#[deprecated(note = "Use `shm::open`.")]
66#[doc(hidden)]
67pub use open as shm_open;
68#[deprecated(note = "Use `shm::unlink`.")]
69#[doc(hidden)]
70pub 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]
89pub fn open<P: path::Arg>(name: P, flags: shm::OFlags, mode: Mode) -> io::Result<OwnedFd> {
90    name.into_with_c_str(|name| backend::shm::syscalls::shm_open(name, 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]
103pub fn unlink<P: path::Arg>(name: P) -> io::Result<()> {
104    name.into_with_c_str(backend::shm::syscalls::shm_unlink)
105}