integrate GetSetFdFlags!
change reopen_with_fdflags(&self, fdflags) -> Result<Box<dyn WasiFile>> to set_fdflags(&mut self, fdflags) -> Result<()>. this makes way more sense than my prior hare-brained schemes.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::{Error, ErrorExt, SystemTimeSpec};
|
||||
use bitflags::bitflags;
|
||||
use std::any::Any;
|
||||
use std::cell::Ref;
|
||||
use std::ops::Deref;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub trait WasiFile {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
@@ -10,9 +10,7 @@ pub trait WasiFile {
|
||||
fn sync(&self) -> Result<(), Error>; // file op
|
||||
fn get_filetype(&self) -> Result<FileType, Error>; // file op
|
||||
fn get_fdflags(&self) -> Result<FdFlags, Error>; // file op
|
||||
/// This method takes a `&self` so that it can be called on a `&dyn WasiFile`. However,
|
||||
/// the caller makes the additional guarantee to drop `self` after the call is successful.
|
||||
unsafe fn reopen_with_fdflags(&self, flags: FdFlags) -> Result<Box<dyn WasiFile>, Error>; // file op
|
||||
fn set_fdflags(&mut self, flags: FdFlags) -> Result<(), 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 set_filestat_size(&self, _size: u64) -> Result<(), Error>; // write op
|
||||
fn advise(
|
||||
@@ -83,22 +81,14 @@ pub struct Filestat {
|
||||
|
||||
pub(crate) trait TableFileExt {
|
||||
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>;
|
||||
fn get_file_mut(&self, fd: u32) -> Result<RefMut<FileEntry>, Error>;
|
||||
}
|
||||
impl TableFileExt for crate::table::Table {
|
||||
fn get_file(&self, fd: u32) -> Result<Ref<FileEntry>, Error> {
|
||||
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 })
|
||||
})
|
||||
fn get_file_mut(&self, fd: u32) -> Result<RefMut<FileEntry>, Error> {
|
||||
self.get_mut(fd)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +135,16 @@ impl<'a> FileEntryExt<'a> for Ref<'a, FileEntry> {
|
||||
Ok(Ref::map(self, |r| r.file.deref()))
|
||||
}
|
||||
}
|
||||
pub trait FileEntryMutExt<'a> {
|
||||
fn get_cap(self, caps: FileCaps) -> Result<RefMut<'a, dyn WasiFile>, Error>;
|
||||
}
|
||||
|
||||
impl<'a> FileEntryMutExt<'a> for RefMut<'a, FileEntry> {
|
||||
fn get_cap(self, caps: FileCaps) -> Result<RefMut<'a, dyn WasiFile>, Error> {
|
||||
self.capable_of(caps)?;
|
||||
Ok(RefMut::map(self, |r| r.file.deref_mut()))
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct FileCaps : u32 {
|
||||
|
||||
@@ -114,7 +114,7 @@ impl<R: Read + Any> WasiFile for ReadPipe<R> {
|
||||
fn get_fdflags(&self) -> Result<FdFlags, Error> {
|
||||
Ok(FdFlags::empty())
|
||||
}
|
||||
unsafe fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
|
||||
fn set_fdflags(&mut self, _fdflags: FdFlags) -> Result<(), Error> {
|
||||
Err(Error::badf())
|
||||
}
|
||||
fn get_filestat(&self) -> Result<Filestat, Error> {
|
||||
@@ -250,7 +250,7 @@ impl<W: Write + Any> WasiFile for WritePipe<W> {
|
||||
fn get_fdflags(&self) -> Result<FdFlags, Error> {
|
||||
Ok(FdFlags::APPEND)
|
||||
}
|
||||
unsafe fn reopen_with_fdflags(&self, _fdflags: FdFlags) -> Result<Box<dyn WasiFile>, Error> {
|
||||
fn set_fdflags(&mut self, _fdflags: FdFlags) -> Result<(), Error> {
|
||||
Err(Error::badf())
|
||||
}
|
||||
fn get_filestat(&self) -> Result<Filestat, Error> {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
use crate::{
|
||||
dir::{DirCaps, DirEntry, DirEntryExt, DirFdStat, ReaddirCursor, ReaddirEntity, TableDirExt},
|
||||
file::{
|
||||
FdFlags, FdStat, FileCaps, FileEntry, FileEntryExt, FileType, Filestat, OFlags,
|
||||
TableFileExt,
|
||||
FdFlags, FdStat, FileCaps, FileEntry, FileEntryExt, FileEntryMutExt, FileType, Filestat,
|
||||
OFlags, TableFileExt,
|
||||
},
|
||||
sched::{
|
||||
subscription::{RwEventFlags, SubscriptionResult},
|
||||
@@ -332,14 +332,10 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
}
|
||||
|
||||
fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<(), Error> {
|
||||
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| unsafe {
|
||||
// Safety: update_file_in_place will drop `f` after this call.
|
||||
f.reopen_with_fdflags(FdFlags::from(&flags))
|
||||
})
|
||||
self.table()
|
||||
.get_file_mut(u32::from(fd))?
|
||||
.get_cap(FileCaps::FDSTAT_SET_FLAGS)?
|
||||
.set_fdflags(FdFlags::from(&flags))
|
||||
}
|
||||
|
||||
fn fd_fdstat_set_rights(
|
||||
|
||||
Reference in New Issue
Block a user