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