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