WasiDir: make all operations async
This commit is contained in:
@@ -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>,
|
||||||
|
|||||||
@@ -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
|
||||||
|
.hard_link(
|
||||||
src_path.as_str()?.deref(),
|
src_path.as_str()?.deref(),
|
||||||
target_dir.deref(),
|
target_dir.deref(),
|
||||||
target_path.as_str()?.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
|
||||||
|
.rename(
|
||||||
src_path.as_str()?.deref(),
|
src_path.as_str()?.deref(),
|
||||||
dest_dir.deref(),
|
dest_dir.deref(),
|
||||||
dest_path.as_str()?.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>(
|
||||||
|
|||||||
Reference in New Issue
Block a user