| 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 | |
| 12 | fn 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 | |
| 35 | pub(crate) fn shm_open(name: &CStr, oflags: ShmOFlags, mode: Mode) -> io::Result<OwnedFd> { |
| 36 | let (path: [u8; _], 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 | |
| 44 | pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> { |
| 45 | let (path: [u8; _], len: usize) = get_shm_name(name)?; |
| 46 | unlink(path:CStr::from_bytes_with_nul(&path[..len]).unwrap()) |
| 47 | } |
| 48 | |