rustix/backend/linux_raw/shm/
syscalls.rs1use crate::ffi::CStr;
2
3use crate::backend::fs::syscalls::{open, unlink};
4use crate::backend::fs::types::{Mode, OFlags};
5use crate::fd::OwnedFd;
6use crate::{io, shm};
7
8const NAME_MAX: usize = 255;
9const SHM_DIR: &[u8] = b"/dev/shm/";
10
11fn get_shm_name(name: &CStr) -> io::Result<([u8; NAME_MAX + SHM_DIR.len() + 1], usize)> {
12 let name = name.to_bytes();
13
14 if name.len() > NAME_MAX {
15 return Err(io::Errno::NAMETOOLONG);
16 }
17
18 let num_slashes = name.iter().take_while(|x| **x == b'/').count();
19 let after_slashes = &name[num_slashes..];
20 if after_slashes.is_empty()
21 || after_slashes == b"."
22 || after_slashes == b".."
23 || after_slashes.contains(&b'/')
24 {
25 return Err(io::Errno::INVAL);
26 }
27
28 let mut path = [0; NAME_MAX + SHM_DIR.len() + 1];
29 path[..SHM_DIR.len()].copy_from_slice(SHM_DIR);
30 path[SHM_DIR.len()..SHM_DIR.len() + name.len()].copy_from_slice(name);
31 Ok((path, SHM_DIR.len() + name.len() + 1))
32}
33
34pub(crate) fn shm_open(name: &CStr, oflags: shm::OFlags, mode: Mode) -> io::Result<OwnedFd> {
35 let (path, len) = get_shm_name(name)?;
36 open(
37 CStr::from_bytes_with_nul(&path[..len]).unwrap(),
38 OFlags::from_bits(oflags.bits()).unwrap() | OFlags::CLOEXEC,
39 mode,
40 )
41}
42
43pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> {
44 let (path, len) = get_shm_name(name)?;
45 unlink(CStr::from_bytes_with_nul(&path[..len]).unwrap())
46}