From f1a5dce716b807e259cd3f896a6e705c5612ac1f Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Thu, 21 Jan 2021 17:56:03 -0800 Subject: [PATCH] change set_fdflags to reopen_with_fdflags --- crates/wasi-c2/cap-std-sync/src/file.rs | 4 ++-- crates/wasi-c2/cap-std-sync/src/stdio.rs | 10 ++++------ crates/wasi-c2/src/file.rs | 14 +++++++++++++- crates/wasi-c2/src/pipe.rs | 8 ++++---- crates/wasi-c2/src/snapshots/preview_1.rs | 10 +++++----- crates/wasi-c2/src/table.rs | 14 +++++++++++++- 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/crates/wasi-c2/cap-std-sync/src/file.rs b/crates/wasi-c2/cap-std-sync/src/file.rs index 5502335ba1..0672455a33 100644 --- a/crates/wasi-c2/cap-std-sync/src/file.rs +++ b/crates/wasi-c2/cap-std-sync/src/file.rs @@ -38,8 +38,8 @@ impl WasiFile for File { // XXX get_fdflags is not implemented but lets lie rather than panic: Ok(FdFlags::empty()) } - fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { - todo!("set_fdflags is not implemented") + fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result, Error> { + todo!("reopen_with_fdflags is not implemented") } fn get_filestat(&self) -> Result { let meta = self.0.metadata()?; diff --git a/crates/wasi-c2/cap-std-sync/src/stdio.rs b/crates/wasi-c2/cap-std-sync/src/stdio.rs index e3dd0d2b5e..fe527bff59 100644 --- a/crates/wasi-c2/cap-std-sync/src/stdio.rs +++ b/crates/wasi-c2/cap-std-sync/src/stdio.rs @@ -39,9 +39,8 @@ impl WasiFile for Stdin { // XXX get_fdflags is not implemented but lets lie rather than panic: Ok(FdFlags::empty()) } - fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { - // XXX - Err(Error::Perm) + fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result, Error> { + Err(Error::Badf) } fn get_filestat(&self) -> Result { 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: Ok(FdFlags::empty()) } - fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { - // XXX - Err(Error::Perm) + fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result, Error> { + Err(Error::Badf) } fn get_filestat(&self) -> Result { // XXX can unsafe-io give a way to get metadata? diff --git a/crates/wasi-c2/src/file.rs b/crates/wasi-c2/src/file.rs index 97bb939eb7..3db073e096 100644 --- a/crates/wasi-c2/src/file.rs +++ b/crates/wasi-c2/src/file.rs @@ -10,7 +10,7 @@ pub trait WasiFile { fn sync(&self) -> Result<(), Error>; // file op fn get_filetype(&self) -> Result; // file op fn get_fdflags(&self) -> Result; // file op - fn set_fdflags(&self, _flags: FdFlags) -> Result<(), Error>; + fn reopen_with_fdflags(&self, flags: FdFlags) -> Result, Error>; // file op fn get_filestat(&self) -> Result; // 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 advise( @@ -83,11 +83,23 @@ pub struct Filestat { pub(crate) trait TableFileExt { fn get_file(&self, fd: u32) -> Result, Error>; + fn update_file_in_place(&mut self, fd: u32, f: F) -> Result<(), Error> + where + F: FnOnce(&dyn WasiFile) -> Result, Error>; } impl TableFileExt for crate::table::Table { fn get_file(&self, fd: u32) -> Result, Error> { self.get(fd) } + fn update_file_in_place(&mut self, fd: u32, f: F) -> Result<(), Error> + where + F: FnOnce(&dyn WasiFile) -> Result, Error>, + { + self.update_in_place(fd, |FileEntry { caps, file }| { + let file = f(file.deref())?; + Ok(FileEntry { caps, file }) + }) + } } pub(crate) struct FileEntry { diff --git a/crates/wasi-c2/src/pipe.rs b/crates/wasi-c2/src/pipe.rs index a65acd8f1e..f83e24c992 100644 --- a/crates/wasi-c2/src/pipe.rs +++ b/crates/wasi-c2/src/pipe.rs @@ -114,8 +114,8 @@ impl WasiFile for ReadPipe { fn get_fdflags(&self) -> Result { Ok(FdFlags::empty()) } - fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { - Err(Error::Perm) + fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result, Error> { + Err(Error::Badf) } fn get_filestat(&self) -> Result { Ok(Filestat { @@ -250,8 +250,8 @@ impl WasiFile for WritePipe { fn get_fdflags(&self) -> Result { Ok(FdFlags::APPEND) } - fn set_fdflags(&self, _fdflags: FdFlags) -> Result<(), Error> { - Err(Error::Perm) + fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result, Error> { + Err(Error::Badf) } fn get_filestat(&self) -> Result { Ok(Filestat { diff --git a/crates/wasi-c2/src/snapshots/preview_1.rs b/crates/wasi-c2/src/snapshots/preview_1.rs index 68cab65da9..e01de4f220 100644 --- a/crates/wasi-c2/src/snapshots/preview_1.rs +++ b/crates/wasi-c2/src/snapshots/preview_1.rs @@ -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> { - self.table() - .get_file(u32::from(fd))? - .get_cap(FileCaps::FDSTAT_SET_FLAGS)? - .set_fdflags(FdFlags::from(&flags))?; - Ok(()) + let mut table = self.table(); + let fd = u32::from(fd); + let table_check = table.get_file(fd)?.get_cap(FileCaps::FDSTAT_SET_FLAGS)?; + drop(table_check); + table.update_file_in_place(fd, |f| f.reopen_with_fdflags(FdFlags::from(&flags))) } fn fd_fdstat_set_rights( diff --git a/crates/wasi-c2/src/table.rs b/crates/wasi-c2/src/table.rs index 70b3e3b3e3..20ee87bcc7 100644 --- a/crates/wasi-c2/src/table.rs +++ b/crates/wasi-c2/src/table.rs @@ -78,11 +78,23 @@ impl Table { Err(Error::Exist) // Does exist, but borrowed } } else { - Err(Error::Exist) // Does not exist + Err(Error::Badf) // Does not exist } } pub fn delete(&mut self, key: u32) -> Option> { self.map.remove(&key).map(|rc| RefCell::into_inner(rc)) } + + pub fn update_in_place(&mut self, key: u32, f: F) -> Result<(), Error> + where + T: Any + Sized, + F: FnOnce(T) -> Result, + { + let entry = self.delete(key).ok_or(Error::Badf)?; + let downcast = entry.downcast::().map_err(|_| Error::Exist)?; + let new = f(*downcast)?; + self.insert_at(key, Box::new(new)); + Ok(()) + } }