diff --git a/crates/wasi-common/cap-std-sync/src/dir.rs b/crates/wasi-common/cap-std-sync/src/dir.rs index 3ba290d508..666f9b86a8 100644 --- a/crates/wasi-common/cap-std-sync/src/dir.rs +++ b/crates/wasi-common/cap-std-sync/src/dir.rs @@ -65,21 +65,15 @@ impl WasiDir for Dir { } else { opts.follow(FollowSymlinks::No); } - - let mut f = self.0.open_with(Path::new(path), &opts)?; - // This takes care of setting the fdflags that can't be handled by OpenOptions (yet) - // (DSYNC, SYNC, NONBLOCK, RSYNC) + // the DSYNC, SYNC, and RSYNC flags are ignored! We do not + // have support for them in cap-std yet. // ideally OpenOptions would just support this though: // https://github.com/bytecodealliance/cap-std/issues/146 - { - // Even worse - set_fd_flags panicks when given DSYNC, SYNC, RSYNC! - // it only supports NONBLOCK - let fdflags = if fdflags.contains(wasi_common::file::FdFlags::NONBLOCK) { - system_interface::fs::FdFlags::NONBLOCK - } else { - system_interface::fs::FdFlags::empty() - }; - f.set_fd_flags(fdflags)?; + + let mut f = self.0.open_with(Path::new(path), &opts)?; + // NONBLOCK does not have an OpenOption either, but we can patch that on with set_fd_flags: + if fdflags.contains(wasi_common::file::FdFlags::NONBLOCK) { + f.set_fd_flags(system_interface::fs::FdFlags::NONBLOCK)?; } Ok(Box::new(File::from_cap_std(f))) } diff --git a/crates/wasi-common/cap-std-sync/src/file.rs b/crates/wasi-common/cap-std-sync/src/file.rs index 2d3b43ace9..f89a090ea1 100644 --- a/crates/wasi-common/cap-std-sync/src/file.rs +++ b/crates/wasi-common/cap-std-sync/src/file.rs @@ -9,7 +9,7 @@ use system_interface::{ }; use wasi_common::{ file::{Advice, FdFlags, FileType, Filestat, WasiFile}, - Error, + Error, ErrorExt, }; pub struct File(cap_std::fs::File); @@ -41,6 +41,13 @@ impl WasiFile for File { Ok(from_sysif_fdflags(fdflags)) } fn set_fdflags(&mut self, fdflags: FdFlags) -> Result<(), Error> { + if fdflags.intersects( + wasi_common::file::FdFlags::DSYNC + | wasi_common::file::FdFlags::SYNC + | wasi_common::file::FdFlags::RSYNC, + ) { + return Err(Error::invalid_argument().context("cannot set DSYNC, SYNC, or RSYNC flag")); + } Ok(self.0.set_fd_flags(to_sysif_fdflags(fdflags))?) } fn get_filestat(&self) -> Result {