use crate::arch::Arch;
use crate::target::Target;
use bitflags::bitflags;
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct HostIoOpenFlags(u32);
bitflags! {
impl HostIoOpenFlags: u32 {
const O_RDONLY = 0x0;
const O_WRONLY = 0x1;
const O_RDWR = 0x2;
const O_APPEND = 0x8;
const O_CREAT = 0x200;
const O_TRUNC = 0x400;
const O_EXCL = 0x800;
const O_NONBLOCK = 1 << 28;
const O_DONT_FOLLOW_SYMLINKS = 1 << 29;
const O_CLOSE_ON_EXEC = 1 << 30;
const O_INVALID = 1 << 31;
}
}
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct HostIoOpenMode(u32);
bitflags! {
impl HostIoOpenMode: u32 {
const S_IFREG = 0o100000;
const S_IFDIR = 0o40000;
const S_IRUSR = 0o400;
const S_IWUSR = 0o200;
const S_IXUSR = 0o100;
const S_IRGRP = 0o40;
const S_IWGRP = 0o20;
const S_IXGRP = 0o10;
const S_IROTH = 0o4;
const S_IWOTH = 0o2;
const S_IXOTH = 0o1;
}
}
#[derive(Debug)]
pub struct HostIoStat {
pub st_dev: u32,
pub st_ino: u32,
pub st_mode: HostIoOpenMode,
pub st_nlink: u32,
pub st_uid: u32,
pub st_gid: u32,
pub st_rdev: u32,
pub st_size: u64,
pub st_blksize: u64,
pub st_blocks: u64,
pub st_atime: u32,
pub st_mtime: u32,
pub st_ctime: u32,
}
#[derive(Debug)]
pub enum FsKind {
Stub,
Pid(crate::common::Pid),
}
#[derive(Debug)]
pub enum HostIoErrno {
EPERM = 1,
ENOENT = 2,
EINTR = 4,
EIO = 5,
EBADF = 9,
EACCES = 13,
EFAULT = 14,
EBUSY = 16,
EEXIST = 17,
ENODEV = 19,
ENOTDIR = 20,
EISDIR = 21,
EINVAL = 22,
ENFILE = 23,
EMFILE = 24,
EFBIG = 27,
ENOSPC = 28,
ESPIPE = 29,
EROFS = 30,
ENOSYS = 88,
ENAMETOOLONG = 91,
EUNKNOWN = 9999,
}
pub enum HostIoError<E> {
Errno(HostIoErrno),
Fatal(E),
}
#[cfg(feature = "std")]
impl<E> From<std::io::Error> for HostIoError<E> {
fn from(e: std::io::Error) -> HostIoError<E> {
use std::io::ErrorKind::*;
let errno = match e.kind() {
PermissionDenied => HostIoErrno::EPERM,
NotFound => HostIoErrno::ENOENT,
Interrupted => HostIoErrno::EINTR,
AlreadyExists => HostIoErrno::EEXIST,
InvalidInput => HostIoErrno::EINVAL,
_ => HostIoErrno::EUNKNOWN,
};
HostIoError::Errno(errno)
}
}
pub type HostIoResult<T, Tgt> = Result<T, HostIoError<<Tgt as Target>::Error>>;
pub trait HostIo: Target {
#[inline(always)]
fn support_open(&mut self) -> Option<HostIoOpenOps<'_, Self>> {
None
}
#[inline(always)]
fn support_close(&mut self) -> Option<HostIoCloseOps<'_, Self>> {
None
}
#[inline(always)]
fn support_pread(&mut self) -> Option<HostIoPreadOps<'_, Self>> {
None
}
#[inline(always)]
fn support_pwrite(&mut self) -> Option<HostIoPwriteOps<'_, Self>> {
None
}
#[inline(always)]
fn support_fstat(&mut self) -> Option<HostIoFstatOps<'_, Self>> {
None
}
#[inline(always)]
fn support_unlink(&mut self) -> Option<HostIoUnlinkOps<'_, Self>> {
None
}
#[inline(always)]
fn support_readlink(&mut self) -> Option<HostIoReadlinkOps<'_, Self>> {
None
}
#[inline(always)]
fn support_setfs(&mut self) -> Option<HostIoSetfsOps<'_, Self>> {
None
}
}
define_ext!(HostIoOps, HostIo);
pub trait HostIoOpen: HostIo {
fn open(
&mut self,
filename: &[u8],
flags: HostIoOpenFlags,
mode: HostIoOpenMode,
) -> HostIoResult<u32, Self>;
}
define_ext!(HostIoOpenOps, HostIoOpen);
pub trait HostIoClose: HostIo {
fn close(&mut self, fd: u32) -> HostIoResult<(), Self>;
}
define_ext!(HostIoCloseOps, HostIoClose);
pub trait HostIoPread: HostIo {
fn pread(
&mut self,
fd: u32,
count: usize,
offset: u64,
buf: &mut [u8],
) -> HostIoResult<usize, Self>;
}
define_ext!(HostIoPreadOps, HostIoPread);
pub trait HostIoPwrite: HostIo {
fn pwrite(
&mut self,
fd: u32,
offset: <Self::Arch as Arch>::Usize,
data: &[u8],
) -> HostIoResult<<Self::Arch as Arch>::Usize, Self>;
}
define_ext!(HostIoPwriteOps, HostIoPwrite);
pub trait HostIoFstat: HostIo {
fn fstat(&mut self, fd: u32) -> HostIoResult<HostIoStat, Self>;
}
define_ext!(HostIoFstatOps, HostIoFstat);
pub trait HostIoUnlink: HostIo {
fn unlink(&mut self, filename: &[u8]) -> HostIoResult<(), Self>;
}
define_ext!(HostIoUnlinkOps, HostIoUnlink);
pub trait HostIoReadlink: HostIo {
fn readlink(&mut self, filename: &[u8], buf: &mut [u8]) -> HostIoResult<usize, Self>;
}
define_ext!(HostIoReadlinkOps, HostIoReadlink);
pub trait HostIoSetfs: HostIo {
fn setfs(&mut self, fs: FsKind) -> HostIoResult<(), Self>;
}
define_ext!(HostIoSetfsOps, HostIoSetfs);