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