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; 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 | |
44 | pub(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 | |