Path: blob/main/crates/wasi-common/src/file.rs
1692 views
use crate::{Error, ErrorExt, SystemTimeSpec};1use bitflags::bitflags;2use std::any::Any;3use std::sync::Arc;45#[wiggle::async_trait]6pub trait WasiFile: Send + Sync {7fn as_any(&self) -> &dyn Any;8async fn get_filetype(&self) -> Result<FileType, Error>;910#[cfg(unix)]11fn pollable(&self) -> Option<rustix::fd::BorrowedFd<'_>> {12None13}1415#[cfg(windows)]16fn pollable(&self) -> Option<io_extras::os::windows::RawHandleOrSocket> {17None18}1920fn isatty(&self) -> bool {21false22}2324async fn sock_accept(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {25Err(Error::badf())26}2728async fn sock_recv<'a>(29&self,30_ri_data: &mut [std::io::IoSliceMut<'a>],31_ri_flags: RiFlags,32) -> Result<(u64, RoFlags), Error> {33Err(Error::badf())34}3536async fn sock_send<'a>(37&self,38_si_data: &[std::io::IoSlice<'a>],39_si_flags: SiFlags,40) -> Result<u64, Error> {41Err(Error::badf())42}4344async fn sock_shutdown(&self, _how: SdFlags) -> Result<(), Error> {45Err(Error::badf())46}4748async fn datasync(&self) -> Result<(), Error> {49Ok(())50}5152async fn sync(&self) -> Result<(), Error> {53Ok(())54}5556async fn get_fdflags(&self) -> Result<FdFlags, Error> {57Ok(FdFlags::empty())58}5960async fn set_fdflags(&mut self, _flags: FdFlags) -> Result<(), Error> {61Err(Error::badf())62}6364async fn get_filestat(&self) -> Result<Filestat, Error> {65Ok(Filestat {66device_id: 0,67inode: 0,68filetype: self.get_filetype().await?,69nlink: 0,70size: 0, // XXX no way to get a size out of a Read :(71atim: None,72mtim: None,73ctim: None,74})75}7677async fn set_filestat_size(&self, _size: u64) -> Result<(), Error> {78Err(Error::badf())79}8081async fn advise(&self, _offset: u64, _len: u64, _advice: Advice) -> Result<(), Error> {82Err(Error::badf())83}8485async fn set_times(86&self,87_atime: Option<SystemTimeSpec>,88_mtime: Option<SystemTimeSpec>,89) -> Result<(), Error> {90Err(Error::badf())91}9293async fn read_vectored<'a>(&self, _bufs: &mut [std::io::IoSliceMut<'a>]) -> Result<u64, Error> {94Err(Error::badf())95}9697async fn read_vectored_at<'a>(98&self,99_bufs: &mut [std::io::IoSliceMut<'a>],100_offset: u64,101) -> Result<u64, Error> {102Err(Error::badf())103}104105async fn write_vectored<'a>(&self, _bufs: &[std::io::IoSlice<'a>]) -> Result<u64, Error> {106Err(Error::badf())107}108109async fn write_vectored_at<'a>(110&self,111_bufs: &[std::io::IoSlice<'a>],112_offset: u64,113) -> Result<u64, Error> {114Err(Error::badf())115}116117async fn seek(&self, _pos: std::io::SeekFrom) -> Result<u64, Error> {118Err(Error::badf())119}120121async fn peek(&self, _buf: &mut [u8]) -> Result<u64, Error> {122Err(Error::badf())123}124125fn num_ready_bytes(&self) -> Result<u64, Error> {126Ok(0)127}128129async fn readable(&self) -> Result<(), Error> {130Err(Error::badf())131}132133async fn writable(&self) -> Result<(), Error> {134Err(Error::badf())135}136}137138#[derive(Debug, Copy, Clone, PartialEq, Eq)]139pub enum FileType {140Unknown,141BlockDevice,142CharacterDevice,143Directory,144RegularFile,145SocketDgram,146SocketStream,147SymbolicLink,148Pipe,149}150151bitflags! {152#[derive(Copy, Clone, Debug, PartialEq, Eq)]153pub struct FdFlags: u32 {154const APPEND = 0b1;155const DSYNC = 0b10;156const NONBLOCK = 0b100;157const RSYNC = 0b1000;158const SYNC = 0b10000;159}160}161162bitflags! {163#[derive(Copy, Clone, Debug, PartialEq, Eq)]164pub struct SdFlags: u32 {165const RD = 0b1;166const WR = 0b10;167}168}169170bitflags! {171#[derive(Copy, Clone, Debug, PartialEq, Eq)]172pub struct SiFlags: u32 {173}174}175176bitflags! {177#[derive(Copy, Clone, Debug, PartialEq, Eq)]178pub struct RiFlags: u32 {179const RECV_PEEK = 0b1;180const RECV_WAITALL = 0b10;181}182}183184bitflags! {185#[derive(Copy, Clone, Debug, PartialEq, Eq)]186pub struct RoFlags: u32 {187const RECV_DATA_TRUNCATED = 0b1;188}189}190191bitflags! {192#[derive(Copy, Clone, Debug, PartialEq, Eq)]193pub struct OFlags: u32 {194const CREATE = 0b1;195const DIRECTORY = 0b10;196const EXCLUSIVE = 0b100;197const TRUNCATE = 0b1000;198}199}200201#[derive(Debug, Clone, PartialEq, Eq)]202pub struct Filestat {203pub device_id: u64,204pub inode: u64,205pub filetype: FileType,206pub nlink: u64,207pub size: u64, // this is a read field, the rest are file fields208pub atim: Option<std::time::SystemTime>,209pub mtim: Option<std::time::SystemTime>,210pub ctim: Option<std::time::SystemTime>,211}212213pub(crate) trait TableFileExt {214fn get_file(&self, fd: u32) -> Result<Arc<FileEntry>, Error>;215fn get_file_mut(&mut self, fd: u32) -> Result<&mut FileEntry, Error>;216}217impl TableFileExt for crate::table::Table {218fn get_file(&self, fd: u32) -> Result<Arc<FileEntry>, Error> {219self.get(fd)220}221fn get_file_mut(&mut self, fd: u32) -> Result<&mut FileEntry, Error> {222self.get_mut(fd)223}224}225226pub(crate) struct FileEntry {227pub file: Box<dyn WasiFile>,228pub access_mode: FileAccessMode,229}230231bitflags! {232#[derive(Copy, Clone, Debug, PartialEq, Eq)]233pub struct FileAccessMode : u32 {234const READ = 0b1;235const WRITE= 0b10;236}237}238239impl FileEntry {240pub fn new(file: Box<dyn WasiFile>, access_mode: FileAccessMode) -> Self {241FileEntry { file, access_mode }242}243244pub async fn get_fdstat(&self) -> Result<FdStat, Error> {245Ok(FdStat {246filetype: self.file.get_filetype().await?,247flags: self.file.get_fdflags().await?,248access_mode: self.access_mode,249})250}251}252253#[derive(Debug, Clone)]254pub struct FdStat {255pub filetype: FileType,256pub flags: FdFlags,257pub access_mode: FileAccessMode,258}259260#[derive(Debug, Clone)]261pub enum Advice {262Normal,263Sequential,264Random,265WillNeed,266DontNeed,267NoReuse,268}269270271