change set_fdflags to reopen_with_fdflags

This commit is contained in:
Pat Hickey
2021-01-21 17:56:03 -08:00
parent a46c2ad0aa
commit f1a5dce716
6 changed files with 41 additions and 19 deletions

View File

@@ -38,8 +38,8 @@ impl WasiFile for File {
// XXX get_fdflags is not implemented but lets lie rather than panic: // XXX get_fdflags is not implemented but lets lie rather than panic:
Ok(FdFlags::empty()) Ok(FdFlags::empty())
} }
fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
todo!("set_fdflags is not implemented") todo!("reopen_with_fdflags is not implemented")
} }
fn get_filestat(&self) -> Result<Filestat, Error> { fn get_filestat(&self) -> Result<Filestat, Error> {
let meta = self.0.metadata()?; let meta = self.0.metadata()?;

View File

@@ -39,9 +39,8 @@ impl WasiFile for Stdin {
// XXX get_fdflags is not implemented but lets lie rather than panic: // XXX get_fdflags is not implemented but lets lie rather than panic:
Ok(FdFlags::empty()) Ok(FdFlags::empty())
} }
fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
// XXX Err(Error::Badf)
Err(Error::Perm)
} }
fn get_filestat(&self) -> Result<Filestat, Error> { fn get_filestat(&self) -> Result<Filestat, Error> {
let meta = self.0.as_file_view().metadata()?; let meta = self.0.as_file_view().metadata()?;
@@ -131,9 +130,8 @@ macro_rules! wasi_file_write_impl {
// XXX get_fdflags is not implemented but lets lie rather than panic: // XXX get_fdflags is not implemented but lets lie rather than panic:
Ok(FdFlags::empty()) Ok(FdFlags::empty())
} }
fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
// XXX Err(Error::Badf)
Err(Error::Perm)
} }
fn get_filestat(&self) -> Result<Filestat, Error> { fn get_filestat(&self) -> Result<Filestat, Error> {
// XXX can unsafe-io give a way to get metadata? // XXX can unsafe-io give a way to get metadata?

View File

@@ -10,7 +10,7 @@ pub trait WasiFile {
fn sync(&self) -> Result<(), Error>; // file op fn sync(&self) -> Result<(), Error>; // file op
fn get_filetype(&self) -> Result<FileType, Error>; // file op fn get_filetype(&self) -> Result<FileType, Error>; // file op
fn get_fdflags(&self) -> Result<FdFlags, Error>; // file op fn get_fdflags(&self) -> Result<FdFlags, Error>; // file op
fn set_fdflags(&self, _flags: FdFlags) -> Result<(), Error>; fn reopen_with_fdflags(&self, flags: FdFlags) -> Result<Box<dyn WasiFile>, Error>; // file op
fn get_filestat(&self) -> Result<Filestat, Error>; // split out get_length as a read & write op, rest is a file op fn get_filestat(&self) -> Result<Filestat, Error>; // split out get_length as a read & write op, rest is a file op
fn set_filestat_size(&self, _size: u64) -> Result<(), Error>; // write op fn set_filestat_size(&self, _size: u64) -> Result<(), Error>; // write op
fn advise( fn advise(
@@ -83,11 +83,23 @@ pub struct Filestat {
pub(crate) trait TableFileExt { pub(crate) trait TableFileExt {
fn get_file(&self, fd: u32) -> Result<Ref<FileEntry>, Error>; fn get_file(&self, fd: u32) -> Result<Ref<FileEntry>, Error>;
fn update_file_in_place<F>(&mut self, fd: u32, f: F) -> Result<(), Error>
where
F: FnOnce(&dyn WasiFile) -> Result<Box<dyn WasiFile>, Error>;
} }
impl TableFileExt for crate::table::Table { impl TableFileExt for crate::table::Table {
fn get_file(&self, fd: u32) -> Result<Ref<FileEntry>, Error> { fn get_file(&self, fd: u32) -> Result<Ref<FileEntry>, Error> {
self.get(fd) self.get(fd)
} }
fn update_file_in_place<F>(&mut self, fd: u32, f: F) -> Result<(), Error>
where
F: FnOnce(&dyn WasiFile) -> Result<Box<dyn WasiFile>, Error>,
{
self.update_in_place(fd, |FileEntry { caps, file }| {
let file = f(file.deref())?;
Ok(FileEntry { caps, file })
})
}
} }
pub(crate) struct FileEntry { pub(crate) struct FileEntry {

View File

@@ -114,8 +114,8 @@ impl<R: Read + Any> WasiFile for ReadPipe<R> {
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
Ok(FdFlags::empty()) Ok(FdFlags::empty())
} }
fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
Err(Error::Perm) Err(Error::Badf)
} }
fn get_filestat(&self) -> Result<Filestat, Error> { fn get_filestat(&self) -> Result<Filestat, Error> {
Ok(Filestat { Ok(Filestat {
@@ -250,8 +250,8 @@ impl<W: Write + Any> WasiFile for WritePipe<W> {
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
Ok(FdFlags::APPEND) Ok(FdFlags::APPEND)
} }
fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
Err(Error::Perm) Err(Error::Badf)
} }
fn get_filestat(&self) -> Result<Filestat, Error> { fn get_filestat(&self) -> Result<Filestat, Error> {
Ok(Filestat { Ok(Filestat {

View File

@@ -272,11 +272,11 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
} }
fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<(), Error> { fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<(), Error> {
self.table() let mut table = self.table();
.get_file(u32::from(fd))? let fd = u32::from(fd);
.get_cap(FileCaps::FDSTAT_SET_FLAGS)? let table_check = table.get_file(fd)?.get_cap(FileCaps::FDSTAT_SET_FLAGS)?;
.set_fdflags(FdFlags::from(&flags))?; drop(table_check);
Ok(()) table.update_file_in_place(fd, |f| f.reopen_with_fdflags(FdFlags::from(&flags)))
} }
fn fd_fdstat_set_rights( fn fd_fdstat_set_rights(

View File

@@ -78,11 +78,23 @@ impl Table {
Err(Error::Exist) // Does exist, but borrowed Err(Error::Exist) // Does exist, but borrowed
} }
} else { } else {
Err(Error::Exist) // Does not exist Err(Error::Badf) // Does not exist
} }
} }
pub fn delete(&mut self, key: u32) -> Option<Box<dyn Any>> { pub fn delete(&mut self, key: u32) -> Option<Box<dyn Any>> {
self.map.remove(&key).map(|rc| RefCell::into_inner(rc)) self.map.remove(&key).map(|rc| RefCell::into_inner(rc))
} }
pub fn update_in_place<T, F>(&mut self, key: u32, f: F) -> Result<(), Error>
where
T: Any + Sized,
F: FnOnce(T) -> Result<T, Error>,
{
let entry = self.delete(key).ok_or(Error::Badf)?;
let downcast = entry.downcast::<T>().map_err(|_| Error::Exist)?;
let new = f(*downcast)?;
self.insert_at(key, Box::new(new));
Ok(())
}
} }