diff --git a/Cargo.lock b/Cargo.lock index ed60ae353a..c220f496b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2815,6 +2815,7 @@ dependencies = [ name = "wiggle" version = "0.22.0" dependencies = [ + "bitflags", "proptest", "thiserror", "tracing", diff --git a/crates/wasi-common/src/entry.rs b/crates/wasi-common/src/entry.rs index a162b19f42..a8a5accaf0 100644 --- a/crates/wasi-common/src/entry.rs +++ b/crates/wasi-common/src/entry.rs @@ -78,7 +78,7 @@ impl Entry { /// `HandleRights` structure is a subset of rights attached to this `Entry`. The check is /// performed using `Entry::validate_rights` method. If the check fails, `Error::Notcapable` /// is returned. - pub(crate) fn as_handle(&self, rights: &HandleRights) -> Result { + pub(crate) fn as_handle(&self, rights: HandleRights) -> Result { self.validate_rights(rights)?; Ok(self.handle.get()) } @@ -87,7 +87,7 @@ impl Entry { /// rights attached to this `Entry` object are a superset. /// /// Upon unsuccessful check, `Error::Notcapable` is returned. - pub(crate) fn validate_rights(&self, rights: &HandleRights) -> Result<()> { + pub(crate) fn validate_rights(&self, rights: HandleRights) -> Result<()> { let this_rights = self.handle.get_rights(); if this_rights.contains(rights) { Ok(()) diff --git a/crates/wasi-common/src/handle.rs b/crates/wasi-common/src/handle.rs index ccb549703c..9bef53eacc 100644 --- a/crates/wasi-common/src/handle.rs +++ b/crates/wasi-common/src/handle.rs @@ -39,8 +39,8 @@ impl HandleRights { } /// Checks if `other` is a subset of those rights. - pub fn contains(&self, other: &Self) -> bool { - self.base.contains(&other.base) && self.inheriting.contains(&other.inheriting) + pub fn contains(&self, other: Self) -> bool { + self.base.contains(other.base) && self.inheriting.contains(other.inheriting) } /// Returns base rights. @@ -100,7 +100,7 @@ pub trait Handle { let file_type = self.get_file_type(); let rights = self.get_rights(); let required_rights = HandleRights::from_base(Rights::FD_SEEK | Rights::FD_TELL); - file_type == Filetype::CharacterDevice && rights.contains(&required_rights) + file_type == Filetype::CharacterDevice && rights.contains(required_rights) } // TODO perhaps should be a separate trait? // FdOps diff --git a/crates/wasi-common/src/path.rs b/crates/wasi-common/src/path.rs index b2e4b19ba0..df04e48f41 100644 --- a/crates/wasi-common/src/path.rs +++ b/crates/wasi-common/src/path.rs @@ -11,7 +11,7 @@ pub(crate) use crate::sys::path::{from_host, open_rights}; /// This is a workaround for not having Capsicum support in the OS. pub(crate) fn get( entry: &Entry, - required_rights: &HandleRights, + required_rights: HandleRights, dirflags: Lookupflags, path: &str, needs_final_component: bool, @@ -140,7 +140,7 @@ pub(crate) fn get( } continue; - } else if ends_with_slash || dirflags.contains(&Lookupflags::SYMLINK_FOLLOW) + } else if ends_with_slash || dirflags.contains(Lookupflags::SYMLINK_FOLLOW) { // if there's a trailing slash, or if `LOOKUP_SYMLINK_FOLLOW` is set, attempt // symlink expansion diff --git a/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs b/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs index 8bb41a903a..794be79c9f 100644 --- a/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs +++ b/crates/wasi-common/src/snapshots/wasi_snapshot_preview1.rs @@ -60,7 +60,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let required_rights = HandleRights::from_base(types::Rights::FD_ADVISE); let entry = self.get_entry(fd)?; entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .advise(advice, offset, len) } @@ -72,7 +72,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { ) -> Result<()> { let required_rights = HandleRights::from_base(types::Rights::FD_ALLOCATE); let entry = self.get_entry(fd)?; - entry.as_handle(&required_rights)?.allocate(offset, len) + entry.as_handle(required_rights)?.allocate(offset, len) } fn fd_close(&self, fd: types::Fd) -> Result<()> { @@ -89,12 +89,12 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { fn fd_datasync(&self, fd: types::Fd) -> Result<()> { let required_rights = HandleRights::from_base(types::Rights::FD_DATASYNC); let entry = self.get_entry(fd)?; - entry.as_handle(&required_rights)?.datasync() + entry.as_handle(required_rights)?.datasync() } fn fd_fdstat_get(&self, fd: types::Fd) -> Result { let entry = self.get_entry(fd)?; - let file = entry.as_handle(&HandleRights::empty())?; + let file = entry.as_handle(HandleRights::empty())?; let fs_flags = file.fdstat_get()?; let rights = entry.get_rights(); let fdstat = types::Fdstat { @@ -109,7 +109,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<()> { let required_rights = HandleRights::from_base(types::Rights::FD_FDSTAT_SET_FLAGS); let entry = self.get_entry(fd)?; - entry.as_handle(&required_rights)?.fdstat_set_flags(flags) + entry.as_handle(required_rights)?.fdstat_set_flags(flags) } fn fd_fdstat_set_rights( @@ -120,7 +120,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { ) -> Result<()> { let rights = HandleRights::new(fs_rights_base, fs_rights_inheriting); let entry = self.get_entry(fd)?; - if !entry.get_rights().contains(&rights) { + if !entry.get_rights().contains(rights) { return Err(Error::Notcapable); } entry.set_rights(rights); @@ -130,14 +130,14 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { fn fd_filestat_get(&self, fd: types::Fd) -> Result { let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_GET); let entry = self.get_entry(fd)?; - let host_filestat = entry.as_handle(&required_rights)?.filestat_get()?; + let host_filestat = entry.as_handle(required_rights)?.filestat_get()?; Ok(host_filestat) } fn fd_filestat_set_size(&self, fd: types::Fd, size: types::Filesize) -> Result<()> { let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_SET_SIZE); let entry = self.get_entry(fd)?; - entry.as_handle(&required_rights)?.filestat_set_size(size) + entry.as_handle(required_rights)?.filestat_set_size(size) } fn fd_filestat_set_times( @@ -150,7 +150,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_SET_TIMES); let entry = self.get_entry(fd)?; entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .filestat_set_times(atim, mtim, fst_flags) } @@ -180,7 +180,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { .map(|s| io::IoSliceMut::new(&mut *s)) .collect::>>(); entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .preadv(&mut buf, offset)? .try_into()? }; @@ -255,7 +255,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let buf: Vec = guest_slices.iter().map(|s| io::IoSlice::new(&*s)).collect(); entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .pwritev(&buf, offset)? .try_into()? }; @@ -278,7 +278,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { .map(|s| io::IoSliceMut::new(&mut *s)) .collect(); entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .read_vectored(&mut slices)? .try_into()? }; @@ -298,7 +298,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let mut bufused = 0; let mut buf = buf.clone(); - for pair in entry.as_handle(&required_rights)?.readdir(cookie)? { + for pair in entry.as_handle(required_rights)?.readdir(cookie)? { let (dirent, name) = pair?; let dirent_raw = dirent.as_bytes()?; let dirent_len: types::Size = dirent_raw.len().try_into()?; @@ -379,21 +379,21 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { types::Whence::End => SeekFrom::End(offset), types::Whence::Set => SeekFrom::Start(offset as u64), }; - let host_newoffset = entry.as_handle(&required_rights)?.seek(pos)?; + let host_newoffset = entry.as_handle(required_rights)?.seek(pos)?; Ok(host_newoffset) } fn fd_sync(&self, fd: types::Fd) -> Result<()> { let required_rights = HandleRights::from_base(types::Rights::FD_SYNC); let entry = self.get_entry(fd)?; - entry.as_handle(&required_rights)?.sync() + entry.as_handle(required_rights)?.sync() } fn fd_tell(&self, fd: types::Fd) -> Result { let required_rights = HandleRights::from_base(types::Rights::FD_TELL); let entry = self.get_entry(fd)?; let host_offset = entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .seek(SeekFrom::Current(0))?; Ok(host_offset) } @@ -411,7 +411,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let slices: Vec = guest_slices.iter().map(|s| io::IoSlice::new(&*s)).collect(); entry - .as_handle(&required_rights)? + .as_handle(required_rights)? .write_vectored(&slices)? .try_into()? }; @@ -426,7 +426,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let path = path.as_str()?; let (dirfd, path) = path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), path.deref(), false, @@ -443,9 +443,9 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let required_rights = HandleRights::from_base(types::Rights::PATH_FILESTAT_GET); let entry = self.get_entry(dirfd)?; let path = path.as_str()?; - let (dirfd, path) = path::get(&entry, &required_rights, flags, path.deref(), false)?; + let (dirfd, path) = path::get(&entry, required_rights, flags, path.deref(), false)?; let host_filestat = - dirfd.filestat_get_at(&path, flags.contains(&types::Lookupflags::SYMLINK_FOLLOW))?; + dirfd.filestat_get_at(&path, flags.contains(types::Lookupflags::SYMLINK_FOLLOW))?; Ok(host_filestat) } @@ -461,13 +461,13 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let required_rights = HandleRights::from_base(types::Rights::PATH_FILESTAT_SET_TIMES); let entry = self.get_entry(dirfd)?; let path = path.as_str()?; - let (dirfd, path) = path::get(&entry, &required_rights, flags, path.deref(), false)?; + let (dirfd, path) = path::get(&entry, required_rights, flags, path.deref(), false)?; dirfd.filestat_set_times_at( &path, atim, mtim, fst_flags, - flags.contains(&types::Lookupflags::SYMLINK_FOLLOW), + flags.contains(types::Lookupflags::SYMLINK_FOLLOW), )?; Ok(()) } @@ -487,7 +487,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let old_path = old_path.as_str()?; path::get( &old_entry, - &required_rights, + required_rights, types::Lookupflags::empty(), old_path.deref(), false, @@ -500,7 +500,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let new_path = new_path.as_str()?; path::get( &new_entry, - &required_rights, + required_rights, types::Lookupflags::empty(), new_path.deref(), false, @@ -510,7 +510,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { &old_path, new_dirfd, &new_path, - old_flags.contains(&types::Lookupflags::SYMLINK_FOLLOW), + old_flags.contains(types::Lookupflags::SYMLINK_FOLLOW), ) } @@ -535,7 +535,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let path = path.as_str()?; path::get( &entry, - &needed_rights, + needed_rights, dirflags, path.deref(), oflags & types::Oflags::CREAT != types::Oflags::empty(), @@ -581,7 +581,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let path = path.as_str()?; path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), path.deref(), false, @@ -599,7 +599,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let path = path.as_str()?; path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), path.deref(), true, @@ -621,7 +621,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let old_path = old_path.as_str()?; path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), old_path.deref(), true, @@ -633,7 +633,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let new_path = new_path.as_str()?; path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), new_path.deref(), true, @@ -654,7 +654,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let new_path = new_path.as_str()?; path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), new_path.deref(), true, @@ -672,7 +672,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx { let path = path.as_str()?; path::get( &entry, - &required_rights, + required_rights, types::Lookupflags::empty(), path.deref(), false, @@ -815,7 +815,7 @@ impl WasiCtx { } }; fd_events.push(sched::FdEventData { - handle: entry.as_handle(&required_rights)?, + handle: entry.as_handle(required_rights)?, r#type: types::Eventtype::FdRead, userdata: subscription.userdata, }); @@ -841,7 +841,7 @@ impl WasiCtx { } }; fd_events.push(sched::FdEventData { - handle: entry.as_handle(&required_rights)?, + handle: entry.as_handle(required_rights)?, r#type: types::Eventtype::FdWrite, userdata: subscription.userdata, }); diff --git a/crates/wasi-common/src/sys/fd.rs b/crates/wasi-common/src/sys/fd.rs index 8603c22a67..bcee2956bc 100644 --- a/crates/wasi-common/src/sys/fd.rs +++ b/crates/wasi-common/src/sys/fd.rs @@ -12,10 +12,10 @@ pub(crate) fn filestat_set_times( st_mtim: Timestamp, fst_flags: Fstflags, ) -> Result<()> { - let set_atim = fst_flags.contains(&Fstflags::ATIM); - let set_atim_now = fst_flags.contains(&Fstflags::ATIM_NOW); - let set_mtim = fst_flags.contains(&Fstflags::MTIM); - let set_mtim_now = fst_flags.contains(&Fstflags::MTIM_NOW); + let set_atim = fst_flags.contains(Fstflags::ATIM); + let set_atim_now = fst_flags.contains(Fstflags::ATIM_NOW); + let set_mtim = fst_flags.contains(Fstflags::MTIM); + let set_mtim_now = fst_flags.contains(Fstflags::MTIM_NOW); if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) { return Err(Error::Inval); diff --git a/crates/wasi-common/src/sys/unix/mod.rs b/crates/wasi-common/src/sys/unix/mod.rs index 84d8ec581e..9c7fd5ece8 100644 --- a/crates/wasi-common/src/sys/unix/mod.rs +++ b/crates/wasi-common/src/sys/unix/mod.rs @@ -147,19 +147,19 @@ impl From for ClockId { impl From for OFlags { fn from(fdflags: Fdflags) -> Self { let mut nix_flags = Self::empty(); - if fdflags.contains(&Fdflags::APPEND) { + if fdflags.contains(Fdflags::APPEND) { nix_flags.insert(Self::APPEND); } - if fdflags.contains(&Fdflags::DSYNC) { + if fdflags.contains(Fdflags::DSYNC) { nix_flags.insert(Self::DSYNC); } - if fdflags.contains(&Fdflags::NONBLOCK) { + if fdflags.contains(Fdflags::NONBLOCK) { nix_flags.insert(Self::NONBLOCK); } - if fdflags.contains(&Fdflags::RSYNC) { + if fdflags.contains(Fdflags::RSYNC) { nix_flags.insert(O_RSYNC); } - if fdflags.contains(&Fdflags::SYNC) { + if fdflags.contains(Fdflags::SYNC) { nix_flags.insert(Self::SYNC); } nix_flags @@ -191,16 +191,16 @@ impl From for Fdflags { impl From for OFlags { fn from(oflags: Oflags) -> Self { let mut nix_flags = Self::empty(); - if oflags.contains(&Oflags::CREAT) { + if oflags.contains(Oflags::CREAT) { nix_flags.insert(Self::CREAT); } - if oflags.contains(&Oflags::DIRECTORY) { + if oflags.contains(Oflags::DIRECTORY) { nix_flags.insert(Self::DIRECTORY); } - if oflags.contains(&Oflags::EXCL) { + if oflags.contains(Oflags::EXCL) { nix_flags.insert(Self::EXCL); } - if oflags.contains(&Oflags::TRUNC) { + if oflags.contains(Oflags::TRUNC) { nix_flags.insert(Self::TRUNC); } nix_flags diff --git a/crates/wasi-common/src/sys/unix/path.rs b/crates/wasi-common/src/sys/unix/path.rs index bbe084d32b..d952790eeb 100644 --- a/crates/wasi-common/src/sys/unix/path.rs +++ b/crates/wasi-common/src/sys/unix/path.rs @@ -239,10 +239,10 @@ pub(crate) fn filestat_set_times_at( use std::time::{Duration, UNIX_EPOCH}; use yanix::filetime::*; - let set_atim = fst_flags.contains(&Fstflags::ATIM); - let set_atim_now = fst_flags.contains(&Fstflags::ATIM_NOW); - let set_mtim = fst_flags.contains(&Fstflags::MTIM); - let set_mtim_now = fst_flags.contains(&Fstflags::MTIM_NOW); + let set_atim = fst_flags.contains(Fstflags::ATIM); + let set_atim_now = fst_flags.contains(Fstflags::ATIM_NOW); + let set_mtim = fst_flags.contains(Fstflags::MTIM); + let set_mtim_now = fst_flags.contains(Fstflags::MTIM_NOW); if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) { return Err(Error::Inval); diff --git a/crates/wasi-common/src/sys/windows/fd.rs b/crates/wasi-common/src/sys/windows/fd.rs index 4e3e16021c..09659ac22e 100644 --- a/crates/wasi-common/src/sys/windows/fd.rs +++ b/crates/wasi-common/src/sys/windows/fd.rs @@ -86,7 +86,7 @@ fn file_access_mode_from_fdflags(fdflags: Fdflags, read: bool, write: bool) -> A // For append, grant the handle FILE_APPEND_DATA access but *not* FILE_WRITE_DATA. // This makes the handle "append only". // Changes to the file pointer will be ignored (like POSIX's O_APPEND behavior). - if fdflags.contains(&Fdflags::APPEND) { + if fdflags.contains(Fdflags::APPEND) { access_mode.insert(AccessMode::FILE_APPEND_DATA); access_mode.remove(AccessMode::FILE_WRITE_DATA); } diff --git a/crates/wasi-common/src/sys/windows/mod.rs b/crates/wasi-common/src/sys/windows/mod.rs index bd31ea89da..500c16dbfa 100644 --- a/crates/wasi-common/src/sys/windows/mod.rs +++ b/crates/wasi-common/src/sys/windows/mod.rs @@ -147,13 +147,13 @@ impl TryFrom<&File> for Filestat { impl From for CreationDisposition { fn from(oflags: Oflags) -> Self { - if oflags.contains(&Oflags::CREAT) { - if oflags.contains(&Oflags::EXCL) { + if oflags.contains(Oflags::CREAT) { + if oflags.contains(Oflags::EXCL) { CreationDisposition::CREATE_NEW } else { CreationDisposition::CREATE_ALWAYS } - } else if oflags.contains(&Oflags::TRUNC) { + } else if oflags.contains(Oflags::TRUNC) { CreationDisposition::TRUNCATE_EXISTING } else { CreationDisposition::OPEN_EXISTING @@ -171,9 +171,9 @@ impl From for Flags { // treat I/O operations on files as synchronous. WASI might have an async-io API in the future. // Technically, Windows only supports __WASI_FDFLAGS_SYNC, but treat all the flags as the same. - if fdflags.contains(&Fdflags::DSYNC) - || fdflags.contains(&Fdflags::RSYNC) - || fdflags.contains(&Fdflags::SYNC) + if fdflags.contains(Fdflags::DSYNC) + || fdflags.contains(Fdflags::RSYNC) + || fdflags.contains(Fdflags::SYNC) { flags.insert(Flags::FILE_FLAG_WRITE_THROUGH); } diff --git a/crates/wasi-common/src/sys/windows/path.rs b/crates/wasi-common/src/sys/windows/path.rs index 70b9e9b42f..088e59c86f 100644 --- a/crates/wasi-common/src/sys/windows/path.rs +++ b/crates/wasi-common/src/sys/windows/path.rs @@ -72,7 +72,7 @@ fn file_access_mode_from_fdflags(fdflags: Fdflags, read: bool, write: bool) -> A // For append, grant the handle FILE_APPEND_DATA access but *not* FILE_WRITE_DATA. // This makes the handle "append only". // Changes to the file pointer will be ignored (like POSIX's O_APPEND behavior). - if fdflags.contains(&Fdflags::APPEND) { + if fdflags.contains(Fdflags::APPEND) { access_mode.insert(AccessMode::FILE_APPEND_DATA); access_mode.remove(AccessMode::FILE_WRITE_DATA); } @@ -100,16 +100,16 @@ pub(crate) fn open_rights( let mut needed_inheriting = input_rights.base | input_rights.inheriting; // convert open flags - if oflags.contains(&Oflags::CREAT) { + if oflags.contains(Oflags::CREAT) { needed_base |= Rights::PATH_CREATE_FILE; - } else if oflags.contains(&Oflags::TRUNC) { + } else if oflags.contains(Oflags::TRUNC) { needed_base |= Rights::PATH_FILESTAT_SET_SIZE; } // convert file descriptor flags - if fdflags.contains(&Fdflags::DSYNC) - || fdflags.contains(&Fdflags::RSYNC) - || fdflags.contains(&Fdflags::SYNC) + if fdflags.contains(Fdflags::DSYNC) + || fdflags.contains(Fdflags::RSYNC) + || fdflags.contains(Fdflags::SYNC) { needed_inheriting |= Rights::FD_DATASYNC; needed_inheriting |= Rights::FD_SYNC; @@ -211,13 +211,13 @@ pub(crate) fn open( ) -> Result> { use winx::file::{AccessMode, CreationDisposition, Flags}; - let is_trunc = oflags.contains(&Oflags::TRUNC); + let is_trunc = oflags.contains(Oflags::TRUNC); if is_trunc { // Windows does not support append mode when opening for truncation // This is because truncation requires `GENERIC_WRITE` access, which will override the removal // of the `FILE_WRITE_DATA` permission. - if fdflags.contains(&Fdflags::APPEND) { + if fdflags.contains(Fdflags::APPEND) { return Err(Error::Notsup); } } @@ -246,7 +246,7 @@ pub(crate) fn open( return Err(Error::Loop); } // check if we are trying to open a file as a dir - if file_type.is_file() && oflags.contains(&Oflags::DIRECTORY) { + if file_type.is_file() && oflags.contains(Oflags::DIRECTORY) { return Err(Error::Notdir); } } diff --git a/crates/wasi-common/src/virtfs.rs b/crates/wasi-common/src/virtfs.rs index dae91de485..a219cff719 100644 --- a/crates/wasi-common/src/virtfs.rs +++ b/crates/wasi-common/src/virtfs.rs @@ -299,7 +299,7 @@ impl Handle for InMemoryFile { trace!("write_vectored(iovs={:?})", iovs); let mut data = self.data.borrow_mut(); - let append_mode = self.fd_flags.get().contains(&Fdflags::APPEND); + let append_mode = self.fd_flags.get().contains(Fdflags::APPEND); trace!(" | fd_flags={}", self.fd_flags.get()); // If this file is in append mode, we write to the end. @@ -353,7 +353,7 @@ impl Handle for InMemoryFile { oflags: Oflags, _fd_flags: Fdflags, ) -> Result> { - if oflags.contains(&Oflags::DIRECTORY) { + if oflags.contains(Oflags::DIRECTORY) { tracing::trace!( "InMemoryFile::openat was passed oflags DIRECTORY, but {:?} is a file.", path @@ -652,7 +652,7 @@ impl Handle for VirtualDir { return Err(Error::Exist); } - if oflags.contains(&Oflags::DIRECTORY) + if oflags.contains(Oflags::DIRECTORY) && e.get().get_file_type() != Filetype::Directory { tracing::trace!( @@ -665,7 +665,7 @@ impl Handle for VirtualDir { e.get().try_clone().map_err(Into::into) } Entry::Vacant(v) => { - if oflags.contains(&Oflags::CREAT) { + if oflags.contains(Oflags::CREAT) { if self.writable { // Enforce a hard limit at `u32::MAX - 2` files. // This is to have a constant limit (rather than target-dependent limit we diff --git a/crates/wiggle/Cargo.toml b/crates/wiggle/Cargo.toml index 2255e8023d..3845fa71a6 100644 --- a/crates/wiggle/Cargo.toml +++ b/crates/wiggle/Cargo.toml @@ -15,6 +15,7 @@ thiserror = "1" witx = { path = "../wasi-common/WASI/tools/witx", version = "0.8.7", optional = true } wiggle-macro = { path = "macro", version = "0.22.0" } tracing = "0.1.15" +bitflags = "1.2" [badges] maintenance = { status = "actively-developed" } diff --git a/crates/wiggle/generate/src/funcs.rs b/crates/wiggle/generate/src/funcs.rs index 5cdf59eda0..50f5eec640 100644 --- a/crates/wiggle/generate/src/funcs.rs +++ b/crates/wiggle/generate/src/funcs.rs @@ -169,7 +169,7 @@ pub fn define_func( let func_name = &func.name.as_str(); if func.noreturn { - quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, wiggle::Trap> { + quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, #rt::Trap> { let _span = #rt::tracing::span!( #rt::tracing::Level::TRACE, "wiggle abi", @@ -184,7 +184,7 @@ pub fn define_func( Err(trap) }) } else { - quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, wiggle::Trap> { + quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, #rt::Trap> { let _span = #rt::tracing::span!( #rt::tracing::Level::TRACE, "wiggle abi", diff --git a/crates/wiggle/generate/src/lib.rs b/crates/wiggle/generate/src/lib.rs index 1ba4b6ebae..b9a07f93ce 100644 --- a/crates/wiggle/generate/src/lib.rs +++ b/crates/wiggle/generate/src/lib.rs @@ -40,7 +40,7 @@ pub fn generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> T let abi_typename = names.type_ref(&errtype.abi_type(), anon_lifetime()); let user_typename = errtype.typename(); let methodname = names.user_error_conversion_method(&errtype); - quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, wiggle::Trap>;) + quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, #rt::Trap>;) }); let user_error_conversion = quote! { pub trait UserErrorConversion { diff --git a/crates/wiggle/generate/src/module_trait.rs b/crates/wiggle/generate/src/module_trait.rs index e42551a70b..a7a7289d09 100644 --- a/crates/wiggle/generate/src/module_trait.rs +++ b/crates/wiggle/generate/src/module_trait.rs @@ -69,7 +69,8 @@ pub fn define_module_trait(names: &Names, m: &Module, errxform: &ErrorTransform) .unwrap_or(quote!(())); quote!( Result<(#(#rets),*), #err> ) } else { - quote!(wiggle::Trap) + let rt = names.runtime_mod(); + quote!(#rt::Trap) }; if is_anonymous { diff --git a/crates/wiggle/generate/src/types/flags.rs b/crates/wiggle/generate/src/types/flags.rs index f87261abca..cda13a2bfa 100644 --- a/crates/wiggle/generate/src/types/flags.rs +++ b/crates/wiggle/generate/src/types/flags.rs @@ -27,102 +27,31 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty } quote! { - #[repr(transparent)] - #[derive(Copy, Clone, Debug, ::std::hash::Hash, Eq, PartialEq)] - pub struct #ident(#repr); - - impl #ident { - #(pub const #names_: #ident = #ident(#values_);)* - - #[inline] - pub const fn empty() -> Self { - #ident(0) - } - - #[inline] - pub const fn all() -> Self { - #ident(#(#values_)|*) - } - - #[inline] - pub fn contains(&self, other: &#ident) -> bool { - !*self & *other == Self::empty() + #rt::bitflags::bitflags! { + pub struct #ident: #repr { + #(const #names_ = #values_;)* } } impl ::std::fmt::Display for #ident { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - let mut first = true; - #( - if self.0 & #values_ == #values_ { - if !first { - f.write_str("|")?; - } - first = false; - f.write_fmt(format_args!("{}", stringify!(#names_).to_lowercase()))?; - } - )* - if first { - f.write_str("empty")?; - } - f.write_fmt(format_args!(" ({:#x})", self.0))?; + f.write_str(stringify!(#ident))?; + f.write_str("(")?; + ::std::fmt::Debug::fmt(self, f)?; + f.write_str(" (0x")?; + ::std::fmt::LowerHex::fmt(&self.bits, f)?; + f.write_str("))")?; Ok(()) } } - impl ::std::ops::BitAnd for #ident { - type Output = Self; - fn bitand(self, rhs: Self) -> Self::Output { - #ident(self.0 & rhs.0) - } - } - - impl ::std::ops::BitAndAssign for #ident { - fn bitand_assign(&mut self, rhs: Self) { - *self = *self & rhs - } - } - - impl ::std::ops::BitOr for #ident { - type Output = Self; - fn bitor(self, rhs: Self) -> Self::Output { - #ident(self.0 | rhs.0) - } - } - - impl ::std::ops::BitOrAssign for #ident { - fn bitor_assign(&mut self, rhs: Self) { - *self = *self | rhs - } - } - - impl ::std::ops::BitXor for #ident { - type Output = Self; - fn bitxor(self, rhs: Self) -> Self::Output { - #ident(self.0 ^ rhs.0) - } - } - - impl ::std::ops::BitXorAssign for #ident { - fn bitxor_assign(&mut self, rhs: Self) { - *self = *self ^ rhs - } - } - - impl ::std::ops::Not for #ident { - type Output = Self; - fn not(self) -> Self::Output { - #ident(!self.0) - } - } - impl ::std::convert::TryFrom<#repr> for #ident { type Error = #rt::GuestError; fn try_from(value: #repr) -> Result { if #repr::from(!#ident::all()) & value != 0 { Err(#rt::GuestError::InvalidFlagValue(stringify!(#ident))) } else { - Ok(#ident(value)) + Ok(#ident { bits: value }) } } } @@ -136,7 +65,7 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty impl From<#ident> for #repr { fn from(e: #ident) -> #repr { - e.0 + e.bits } } diff --git a/crates/wiggle/src/lib.rs b/crates/wiggle/src/lib.rs index 102bcb0e7b..4ecbf27da5 100644 --- a/crates/wiggle/src/lib.rs +++ b/crates/wiggle/src/lib.rs @@ -6,6 +6,7 @@ use std::slice; use std::str; use std::sync::Arc; +pub use bitflags; pub use wiggle_macro::from_witx; #[cfg(feature = "wiggle_metadata")] diff --git a/crates/wiggle/tests/flags.rs b/crates/wiggle/tests/flags.rs index e12b64a457..1a2bb0019f 100644 --- a/crates/wiggle/tests/flags.rs +++ b/crates/wiggle/tests/flags.rs @@ -103,11 +103,11 @@ proptest! { #[test] fn flags_fmt() { let empty = format!("{}", types::CarConfig::empty()); - assert_eq!(empty, "empty (0x0)"); + assert_eq!(empty, "CarConfig((empty) (0x0))"); let one_flag = format!("{}", types::CarConfig::AWD); - assert_eq!(one_flag, "awd (0x2)"); + assert_eq!(one_flag, "CarConfig(AWD (0x2))"); let two_flags = format!("{}", types::CarConfig::AUTOMATIC | types::CarConfig::SUV); - assert_eq!(two_flags, "automatic|suv (0x5)"); + assert_eq!(two_flags, "CarConfig(AUTOMATIC | SUV (0x5))"); let all = format!("{}", types::CarConfig::all()); - assert_eq!(all, "automatic|awd|suv (0x7)"); + assert_eq!(all, "CarConfig(AUTOMATIC | AWD | SUV (0x7))"); }