WasiDir: make all operations async

This commit is contained in:
Pat Hickey
2021-04-14 15:22:25 -07:00
parent 00e58567d9
commit 564e43d1b3
2 changed files with 53 additions and 29 deletions

View File

@@ -6,9 +6,10 @@ use std::cell::Ref;
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf; use std::path::PathBuf;
#[wiggle::async_trait]
pub trait WasiDir { pub trait WasiDir {
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
fn open_file( async fn open_file(
&self, &self,
symlink_follow: bool, symlink_follow: bool,
path: &str, path: &str,
@@ -17,26 +18,33 @@ pub trait WasiDir {
write: bool, write: bool,
fdflags: FdFlags, fdflags: FdFlags,
) -> Result<Box<dyn WasiFile>, Error>; ) -> Result<Box<dyn WasiFile>, Error>;
fn open_dir(&self, symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error>; async fn open_dir(&self, symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error>;
fn create_dir(&self, path: &str) -> Result<(), Error>; async fn create_dir(&self, path: &str) -> Result<(), Error>;
fn readdir( // XXX the iterator here needs to be asyncified as well!
async fn readdir(
&self, &self,
cursor: ReaddirCursor, cursor: ReaddirCursor,
) -> Result<Box<dyn Iterator<Item = Result<ReaddirEntity, Error>>>, Error>; ) -> Result<Box<dyn Iterator<Item = Result<ReaddirEntity, Error>>>, Error>;
fn symlink(&self, old_path: &str, new_path: &str) -> Result<(), Error>; async fn symlink(&self, old_path: &str, new_path: &str) -> Result<(), Error>;
fn remove_dir(&self, path: &str) -> Result<(), Error>; async fn remove_dir(&self, path: &str) -> Result<(), Error>;
fn unlink_file(&self, path: &str) -> Result<(), Error>; async fn unlink_file(&self, path: &str) -> Result<(), Error>;
fn read_link(&self, path: &str) -> Result<PathBuf, Error>; async fn read_link(&self, path: &str) -> Result<PathBuf, Error>;
fn get_filestat(&self) -> Result<Filestat, Error>; async fn get_filestat(&self) -> Result<Filestat, Error>;
fn get_path_filestat(&self, path: &str, follow_symlinks: bool) -> Result<Filestat, Error>; async fn get_path_filestat(&self, path: &str, follow_symlinks: bool)
fn rename(&self, path: &str, dest_dir: &dyn WasiDir, dest_path: &str) -> Result<(), Error>; -> Result<Filestat, Error>;
fn hard_link( async fn rename(
&self,
path: &str,
dest_dir: &dyn WasiDir,
dest_path: &str,
) -> Result<(), Error>;
async fn hard_link(
&self, &self,
path: &str, path: &str,
target_dir: &dyn WasiDir, target_dir: &dyn WasiDir,
target_path: &str, target_path: &str,
) -> Result<(), Error>; ) -> Result<(), Error>;
fn set_times( async fn set_times(
&self, &self,
path: &str, path: &str,
atime: Option<SystemTimeSpec>, atime: Option<SystemTimeSpec>,

View File

@@ -378,7 +378,8 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
let filestat = table let filestat = table
.get_dir(fd)? .get_dir(fd)?
.get_cap(DirCaps::FILESTAT_GET)? .get_cap(DirCaps::FILESTAT_GET)?
.get_filestat()?; .get_filestat()
.await?;
Ok(filestat.into()) Ok(filestat.into())
} else { } else {
Err(Error::badf()) Err(Error::badf())
@@ -429,6 +430,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.expect("checked that entry is dir") .expect("checked that entry is dir")
.get_cap(DirCaps::FILESTAT_SET_TIMES)? .get_cap(DirCaps::FILESTAT_SET_TIMES)?
.set_times(".", atim, mtim, false) .set_times(".", atim, mtim, false)
.await
} else { } else {
Err(Error::badf()) Err(Error::badf())
} }
@@ -658,7 +660,8 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.table() .table()
.get_dir(u32::from(fd))? .get_dir(u32::from(fd))?
.get_cap(DirCaps::READDIR)? .get_cap(DirCaps::READDIR)?
.readdir(ReaddirCursor::from(cookie))? .readdir(ReaddirCursor::from(cookie))
.await?
{ {
let entity = entity?; let entity = entity?;
let dirent_raw = dirent_bytes(types::Dirent::try_from(&entity)?); let dirent_raw = dirent_bytes(types::Dirent::try_from(&entity)?);
@@ -707,6 +710,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.get_dir(u32::from(dirfd))? .get_dir(u32::from(dirfd))?
.get_cap(DirCaps::CREATE_DIRECTORY)? .get_cap(DirCaps::CREATE_DIRECTORY)?
.create_dir(path.as_str()?.deref()) .create_dir(path.as_str()?.deref())
.await
} }
async fn path_filestat_get<'a>( async fn path_filestat_get<'a>(
@@ -722,7 +726,8 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.get_path_filestat( .get_path_filestat(
path.as_str()?.deref(), path.as_str()?.deref(),
flags.contains(types::Lookupflags::SYMLINK_FOLLOW), flags.contains(types::Lookupflags::SYMLINK_FOLLOW),
)?; )
.await?;
Ok(types::Filestat::from(filestat)) Ok(types::Filestat::from(filestat))
} }
@@ -751,6 +756,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
mtim, mtim,
flags.contains(types::Lookupflags::SYMLINK_FOLLOW), flags.contains(types::Lookupflags::SYMLINK_FOLLOW),
) )
.await
} }
async fn path_link<'a>( async fn path_link<'a>(
@@ -774,11 +780,13 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.context("symlink following on path_link is not supported")); .context("symlink following on path_link is not supported"));
} }
src_dir.hard_link( src_dir
src_path.as_str()?.deref(), .hard_link(
target_dir.deref(), src_path.as_str()?.deref(),
target_path.as_str()?.deref(), target_dir.deref(),
) target_path.as_str()?.deref(),
)
.await
} }
async fn path_open<'a>( async fn path_open<'a>(
@@ -813,7 +821,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
let dir_caps = dir_entry.child_dir_caps(DirCaps::from(&fs_rights_base)); let dir_caps = dir_entry.child_dir_caps(DirCaps::from(&fs_rights_base));
let file_caps = dir_entry.child_file_caps(FileCaps::from(&fs_rights_inheriting)); let file_caps = dir_entry.child_file_caps(FileCaps::from(&fs_rights_inheriting));
let dir = dir_entry.get_cap(DirCaps::OPEN)?; let dir = dir_entry.get_cap(DirCaps::OPEN)?;
let child_dir = dir.open_dir(symlink_follow, path.deref())?; let child_dir = dir.open_dir(symlink_follow, path.deref()).await?;
drop(dir); drop(dir);
let fd = table.push(Box::new(DirEntry::new( let fd = table.push(Box::new(DirEntry::new(
dir_caps, file_caps, None, child_dir, dir_caps, file_caps, None, child_dir,
@@ -831,7 +839,9 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
let write = file_caps.contains(FileCaps::WRITE) let write = file_caps.contains(FileCaps::WRITE)
|| file_caps.contains(FileCaps::ALLOCATE) || file_caps.contains(FileCaps::ALLOCATE)
|| file_caps.contains(FileCaps::FILESTAT_SET_SIZE); || file_caps.contains(FileCaps::FILESTAT_SET_SIZE);
let file = dir.open_file(symlink_follow, path.deref(), oflags, read, write, fdflags)?; let file = dir
.open_file(symlink_follow, path.deref(), oflags, read, write, fdflags)
.await?;
drop(dir); drop(dir);
let fd = table.push(Box::new(FileEntry::new(file_caps, file)))?; let fd = table.push(Box::new(FileEntry::new(file_caps, file)))?;
Ok(types::Fd::from(fd)) Ok(types::Fd::from(fd))
@@ -849,7 +859,8 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.table() .table()
.get_dir(u32::from(dirfd))? .get_dir(u32::from(dirfd))?
.get_cap(DirCaps::READLINK)? .get_cap(DirCaps::READLINK)?
.read_link(path.as_str()?.deref())? .read_link(path.as_str()?.deref())
.await?
.into_os_string() .into_os_string()
.into_string() .into_string()
.map_err(|_| Error::illegal_byte_sequence().context("link contents"))?; .map_err(|_| Error::illegal_byte_sequence().context("link contents"))?;
@@ -872,6 +883,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.get_dir(u32::from(dirfd))? .get_dir(u32::from(dirfd))?
.get_cap(DirCaps::REMOVE_DIRECTORY)? .get_cap(DirCaps::REMOVE_DIRECTORY)?
.remove_dir(path.as_str()?.deref()) .remove_dir(path.as_str()?.deref())
.await
} }
async fn path_rename<'a>( async fn path_rename<'a>(
@@ -888,11 +900,13 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
let dest_dir = table let dest_dir = table
.get_dir(u32::from(dest_fd))? .get_dir(u32::from(dest_fd))?
.get_cap(DirCaps::RENAME_TARGET)?; .get_cap(DirCaps::RENAME_TARGET)?;
src_dir.rename( src_dir
src_path.as_str()?.deref(), .rename(
dest_dir.deref(), src_path.as_str()?.deref(),
dest_path.as_str()?.deref(), dest_dir.deref(),
) dest_path.as_str()?.deref(),
)
.await
} }
async fn path_symlink<'a>( async fn path_symlink<'a>(
@@ -905,6 +919,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.get_dir(u32::from(dirfd))? .get_dir(u32::from(dirfd))?
.get_cap(DirCaps::SYMLINK)? .get_cap(DirCaps::SYMLINK)?
.symlink(src_path.as_str()?.deref(), dest_path.as_str()?.deref()) .symlink(src_path.as_str()?.deref(), dest_path.as_str()?.deref())
.await
} }
async fn path_unlink_file<'a>( async fn path_unlink_file<'a>(
@@ -916,6 +931,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.get_dir(u32::from(dirfd))? .get_dir(u32::from(dirfd))?
.get_cap(DirCaps::UNLINK_FILE)? .get_cap(DirCaps::UNLINK_FILE)?
.unlink_file(path.as_str()?.deref()) .unlink_file(path.as_str()?.deref())
.await
} }
async fn poll_oneoff<'a>( async fn poll_oneoff<'a>(