mirror of
https://github.com/obhq/obliteration.git
synced 2024-05-31 19:17:40 -04:00
165 lines
4.3 KiB
Rust
165 lines
4.3 KiB
Rust
use crate::errno::{Errno, EINVAL};
|
|
use crate::fs::{
|
|
check_access, Access, AccessError, DefaultFileBackendError, FileBackend, IoCmd, IoLen, IoVec,
|
|
IoVecMut, Mode, OpenFlags, PollEvents, Stat, TruncateLength, VFile, VFileFlags, VPathBuf,
|
|
Vnode,
|
|
};
|
|
use crate::process::VThread;
|
|
use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls};
|
|
use crate::ucred::{Gid, Ucred, Uid};
|
|
use macros::Errno;
|
|
use std::convert::Infallible;
|
|
use std::sync::Arc;
|
|
use thiserror::Error;
|
|
|
|
pub struct SharedMemoryManager {}
|
|
|
|
impl SharedMemoryManager {
|
|
pub fn new(sys: &mut Syscalls) -> Arc<Self> {
|
|
let shm = Arc::new(Self {});
|
|
|
|
sys.register(482, &shm, Self::sys_shm_open);
|
|
sys.register(483, &shm, Self::sys_shm_unlink);
|
|
|
|
shm
|
|
}
|
|
|
|
fn sys_shm_open(self: &Arc<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
|
|
let path = unsafe { i.args[0].to_shm_path() }?.expect("invalid shm path");
|
|
let flags: OpenFlags = i.args[1].try_into().unwrap();
|
|
let mode: u32 = i.args[2].try_into().unwrap();
|
|
|
|
if (flags | OpenFlags::O_RDWR) & OpenFlags::O_ACCMODE != OpenFlags::O_RDWR {
|
|
return Err(SysErr::Raw(EINVAL));
|
|
}
|
|
|
|
if !todo!() {
|
|
return Err(SysErr::Raw(EINVAL));
|
|
}
|
|
|
|
let filedesc = td.proc().files();
|
|
|
|
#[allow(unused_variables)] // TODO: remove when implementing.
|
|
let mode = mode & filedesc.cmask() & 0o7777;
|
|
|
|
let fd = filedesc.alloc_without_budget::<Infallible>(|_| match path {
|
|
ShmPath::Anon => {
|
|
todo!()
|
|
}
|
|
ShmPath::Path(_) => {
|
|
todo!()
|
|
}
|
|
})?;
|
|
|
|
Ok(fd.into())
|
|
}
|
|
|
|
#[allow(unused_variables)] // TODO: remove when implementing.
|
|
fn sys_shm_unlink(self: &Arc<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
|
|
todo!("sys_shm_unlink")
|
|
}
|
|
}
|
|
|
|
pub enum ShmPath {
|
|
Anon,
|
|
Path(VPathBuf),
|
|
}
|
|
|
|
/// An implementation of the `shmfd` structure.
|
|
#[derive(Debug)]
|
|
#[allow(unused_variables)] // TODO: remove when used.
|
|
struct SharedMemory {
|
|
uid: Uid,
|
|
gid: Gid,
|
|
mode: Mode,
|
|
}
|
|
|
|
impl SharedMemory {
|
|
/// See `shm_do_truncate` on the PS4 for a reference.
|
|
#[allow(unused_variables)] // TODO: remove when implementing.
|
|
fn do_truncate(&self, length: TruncateLength) -> Result<(), TruncateError> {
|
|
todo!()
|
|
}
|
|
|
|
/// See `shm_access` on the PS4 for a reference.
|
|
#[allow(dead_code)] // TODO: remove when used.
|
|
fn access(&self, cred: &Ucred, flags: VFileFlags) -> Result<(), AccessError> {
|
|
let mut access = Access::empty();
|
|
|
|
if flags.intersects(VFileFlags::READ) {
|
|
access |= Access::READ;
|
|
}
|
|
|
|
if flags.intersects(VFileFlags::WRITE) {
|
|
access |= Access::WRITE;
|
|
}
|
|
|
|
check_access(cred, self.uid, self.gid, self.mode, access, false)?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl FileBackend for SharedMemory {
|
|
fn is_seekable(&self) -> bool {
|
|
todo!()
|
|
}
|
|
|
|
fn read(
|
|
&self,
|
|
_: &VFile,
|
|
_: u64,
|
|
_: &mut [IoVecMut],
|
|
_: Option<&VThread>,
|
|
) -> Result<IoLen, Box<dyn Errno>> {
|
|
Err(Box::new(DefaultFileBackendError::OperationNotSupported))
|
|
}
|
|
|
|
fn write(
|
|
&self,
|
|
_: &VFile,
|
|
_: u64,
|
|
_: &[IoVec],
|
|
_: Option<&VThread>,
|
|
) -> Result<IoLen, Box<dyn Errno>> {
|
|
Err(Box::new(DefaultFileBackendError::OperationNotSupported))
|
|
}
|
|
|
|
#[allow(unused_variables)] // remove when implementing
|
|
fn ioctl(&self, file: &VFile, cmd: IoCmd, td: Option<&VThread>) -> Result<(), Box<dyn Errno>> {
|
|
todo!()
|
|
}
|
|
|
|
#[allow(unused_variables)] // TODO: remove when implementing
|
|
fn poll(&self, file: &VFile, events: PollEvents, td: &VThread) -> PollEvents {
|
|
todo!()
|
|
}
|
|
|
|
#[allow(unused_variables)] // remove when implementing
|
|
fn stat(&self, file: &VFile, td: Option<&VThread>) -> Result<Stat, Box<dyn Errno>> {
|
|
let mut stat = Stat::zeroed();
|
|
|
|
stat.block_size = 0x4000;
|
|
|
|
todo!()
|
|
}
|
|
|
|
fn truncate(
|
|
&self,
|
|
_: &VFile,
|
|
length: TruncateLength,
|
|
_: Option<&VThread>,
|
|
) -> Result<(), Box<dyn Errno>> {
|
|
self.do_truncate(length)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn vnode(&self) -> Option<&Arc<Vnode>> {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Error, Errno)]
|
|
pub enum TruncateError {}
|