wasi_common/
dir.rs

1use crate::file::{FdFlags, FileType, Filestat, OFlags, WasiFile};
2use crate::{Error, ErrorExt, SystemTimeSpec};
3use std::any::Any;
4use std::path::PathBuf;
5use std::sync::Arc;
6
7pub enum OpenResult {
8    File(Box<dyn WasiFile>),
9    Dir(Box<dyn WasiDir>),
10}
11
12#[wiggle::async_trait]
13pub trait WasiDir: Send + Sync {
14    fn as_any(&self) -> &dyn Any;
15
16    async fn open_file(
17        &self,
18        _symlink_follow: bool,
19        _path: &str,
20        _oflags: OFlags,
21        _read: bool,
22        _write: bool,
23        _fdflags: FdFlags,
24    ) -> Result<OpenResult, Error> {
25        Err(Error::not_supported())
26    }
27
28    async fn create_dir(&self, _path: &str) -> Result<(), Error> {
29        Err(Error::not_supported())
30    }
31
32    // XXX the iterator here needs to be asyncified as well!
33    async fn readdir(
34        &self,
35        _cursor: ReaddirCursor,
36    ) -> Result<Box<dyn Iterator<Item = Result<ReaddirEntity, Error>> + Send>, Error> {
37        Err(Error::not_supported())
38    }
39
40    async fn symlink(&self, _old_path: &str, _new_path: &str) -> Result<(), Error> {
41        Err(Error::not_supported())
42    }
43
44    async fn remove_dir(&self, _path: &str) -> Result<(), Error> {
45        Err(Error::not_supported())
46    }
47
48    async fn unlink_file(&self, _path: &str) -> Result<(), Error> {
49        Err(Error::not_supported())
50    }
51
52    async fn read_link(&self, _path: &str) -> Result<PathBuf, Error> {
53        Err(Error::not_supported())
54    }
55
56    async fn get_filestat(&self) -> Result<Filestat, Error> {
57        Err(Error::not_supported())
58    }
59
60    async fn get_path_filestat(
61        &self,
62        _path: &str,
63        _follow_symlinks: bool,
64    ) -> Result<Filestat, Error> {
65        Err(Error::not_supported())
66    }
67
68    async fn rename(
69        &self,
70        _path: &str,
71        _dest_dir: &dyn WasiDir,
72        _dest_path: &str,
73    ) -> Result<(), Error> {
74        Err(Error::not_supported())
75    }
76
77    async fn hard_link(
78        &self,
79        _path: &str,
80        _target_dir: &dyn WasiDir,
81        _target_path: &str,
82    ) -> Result<(), Error> {
83        Err(Error::not_supported())
84    }
85
86    async fn set_times(
87        &self,
88        _path: &str,
89        _atime: Option<SystemTimeSpec>,
90        _mtime: Option<SystemTimeSpec>,
91        _follow_symlinks: bool,
92    ) -> Result<(), Error> {
93        Err(Error::not_supported())
94    }
95}
96
97pub(crate) struct DirEntry {
98    preopen_path: Option<PathBuf>, // precondition: PathBuf is valid unicode
99    pub dir: Box<dyn WasiDir>,
100}
101
102impl DirEntry {
103    pub fn new(preopen_path: Option<PathBuf>, dir: Box<dyn WasiDir>) -> Self {
104        DirEntry { preopen_path, dir }
105    }
106    pub fn preopen_path(&self) -> &Option<PathBuf> {
107        &self.preopen_path
108    }
109}
110
111pub(crate) trait TableDirExt {
112    fn get_dir(&self, fd: u32) -> Result<Arc<DirEntry>, Error>;
113}
114
115impl TableDirExt for crate::table::Table {
116    fn get_dir(&self, fd: u32) -> Result<Arc<DirEntry>, Error> {
117        self.get(fd)
118    }
119}
120
121#[derive(Debug, Clone)]
122pub struct ReaddirEntity {
123    pub next: ReaddirCursor,
124    pub inode: u64,
125    pub name: String,
126    pub filetype: FileType,
127}
128
129#[derive(Debug, Copy, Clone)]
130pub struct ReaddirCursor(u64);
131impl From<u64> for ReaddirCursor {
132    fn from(c: u64) -> ReaddirCursor {
133        ReaddirCursor(c)
134    }
135}
136impl From<ReaddirCursor> for u64 {
137    fn from(c: ReaddirCursor) -> u64 {
138        c.0
139    }
140}