Browse Source

use bitflags crate to define bitflags, rather than by hand

pull/2577/head
Pat Hickey 4 years ago
parent
commit
b1d32f419c
  1. 1
      Cargo.lock
  2. 1
      crates/wasi-c2/Cargo.toml
  3. 114
      crates/wasi-c2/src/dir.rs
  4. 140
      crates/wasi-c2/src/file.rs
  5. 84
      crates/wasi-c2/src/snapshots/preview_1.rs

1
Cargo.lock

@ -2460,6 +2460,7 @@ name = "wasi-c2"
version = "0.22.0"
dependencies = [
"anyhow",
"bitflags",
"cap-fs-ext",
"cap-rand",
"cap-std",

1
crates/wasi-c2/Cargo.toml

@ -31,6 +31,7 @@ cap-time-ext = "0.9"
cap-rand = "0.9"
fs-set-times = "0.2.2"
cfg-if = "1"
bitflags = "1.2"
[badges]
maintenance = { status = "actively-developed" }

114
crates/wasi-c2/src/dir.rs

@ -1,5 +1,6 @@
use crate::error::Error;
use crate::file::{FdFlags, FileCaps, FileType, Filestat, OFlags, WasiFile};
use bitflags::bitflags;
use cap_fs_ext::SystemTimeSpec;
use std::any::Any;
use std::convert::TryInto;
@ -66,7 +67,7 @@ impl DirEntry {
}
}
pub fn get_cap(&self, caps: DirCaps) -> Result<&dyn WasiDir, Error> {
if self.caps.contains(&caps) {
if self.caps.contains(caps) {
Ok(self.dir.deref())
} else {
Err(Error::DirNotCapable {
@ -76,7 +77,7 @@ impl DirEntry {
}
}
pub fn drop_caps_to(&mut self, caps: DirCaps, file_caps: FileCaps) -> Result<(), Error> {
if self.caps.contains(&caps) && self.file_caps.contains(&file_caps) {
if self.caps.contains(caps) && self.file_caps.contains(file_caps) {
self.caps = caps;
self.file_caps = file_caps;
Ok(())
@ -85,10 +86,10 @@ impl DirEntry {
}
}
pub fn child_dir_caps(&self, desired_caps: DirCaps) -> DirCaps {
self.caps.intersection(&desired_caps)
self.caps & desired_caps
}
pub fn child_file_caps(&self, desired_caps: FileCaps) -> FileCaps {
self.file_caps.intersection(&desired_caps)
self.file_caps & desired_caps
}
pub fn get_dir_fdstat(&self) -> DirFdStat {
DirFdStat {
@ -101,75 +102,24 @@ impl DirEntry {
}
}
#[derive(Debug, Clone, Copy)]
pub struct DirCaps {
flags: u32,
}
impl DirCaps {
pub fn empty() -> Self {
DirCaps { flags: 0 }
}
/// Checks if `other` is a subset of those capabilties:
pub fn contains(&self, other: &Self) -> bool {
self.flags & other.flags == other.flags
}
/// Intersection of two sets of flags (bitwise and)
pub fn intersection(&self, rhs: &Self) -> Self {
DirCaps {
flags: self.flags & rhs.flags,
}
}
pub const CREATE_DIRECTORY: Self = DirCaps { flags: 1 };
pub const CREATE_FILE: Self = DirCaps { flags: 2 };
pub const LINK_SOURCE: Self = DirCaps { flags: 4 };
pub const LINK_TARGET: Self = DirCaps { flags: 8 };
pub const OPEN: Self = DirCaps { flags: 16 };
pub const READDIR: Self = DirCaps { flags: 32 };
pub const READLINK: Self = DirCaps { flags: 64 };
pub const RENAME_SOURCE: Self = DirCaps { flags: 128 };
pub const RENAME_TARGET: Self = DirCaps { flags: 256 };
pub const SYMLINK: Self = DirCaps { flags: 512 };
pub const REMOVE_DIRECTORY: Self = DirCaps { flags: 1024 };
pub const UNLINK_FILE: Self = DirCaps { flags: 2048 };
pub const PATH_FILESTAT_GET: Self = DirCaps { flags: 4096 };
pub const PATH_FILESTAT_SET_TIMES: Self = DirCaps { flags: 8192 };
pub const FILESTAT_GET: Self = DirCaps { flags: 16384 };
pub const FILESTAT_SET_TIMES: Self = DirCaps { flags: 32768 };
// Missing that are in wasi-common directory_base:
// FD_FDSTAT_SET_FLAGS
// FD_SYNC
// FD_ADVISE
pub fn all() -> DirCaps {
Self::CREATE_DIRECTORY
| Self::CREATE_FILE
| Self::LINK_SOURCE
| Self::LINK_TARGET
| Self::OPEN
| Self::READDIR
| Self::READLINK
| Self::RENAME_SOURCE
| Self::RENAME_TARGET
| Self::SYMLINK
| Self::REMOVE_DIRECTORY
| Self::UNLINK_FILE
| Self::PATH_FILESTAT_GET
| Self::PATH_FILESTAT_SET_TIMES
| Self::FILESTAT_GET
| Self::FILESTAT_SET_TIMES
}
}
impl std::ops::BitOr for DirCaps {
type Output = DirCaps;
fn bitor(self, rhs: DirCaps) -> DirCaps {
DirCaps {
flags: self.flags | rhs.flags,
}
bitflags! {
pub struct DirCaps: u32 {
const CREATE_DIRECTORY = 0b1;
const CREATE_FILE = 0b10;
const LINK_SOURCE = 0b100;
const LINK_TARGET = 0b1000;
const OPEN = 0b10000;
const READDIR = 0b100000;
const READLINK = 0b1000000;
const RENAME_SOURCE = 0b10000000;
const RENAME_TARGET = 0b100000000;
const SYMLINK = 0b1000000000;
const REMOVE_DIRECTORY = 0b10000000000;
const UNLINK_FILE = 0b100000000000;
const PATH_FILESTAT_GET = 0b1000000000000;
const PATH_FILESTAT_SET_TIMES = 0b10000000000000;
const FILESTAT_GET = 0b100000000000000;
const FILESTAT_SET_TIMES = 0b1000000000000000;
}
}
@ -229,20 +179,20 @@ impl WasiDir for cap_std::fs::Dir {
let mut opts = cap_std::fs::OpenOptions::new();
if oflags.contains(&(OFlags::CREATE | OFlags::EXCLUSIVE)) {
if oflags.contains(OFlags::CREATE | OFlags::EXCLUSIVE) {
opts.create_new(true);
opts.write(true);
} else if oflags.contains(&OFlags::CREATE) {
} else if oflags.contains(OFlags::CREATE) {
opts.create(true);
opts.write(true);
}
if oflags.contains(&OFlags::TRUNCATE) {
if oflags.contains(OFlags::TRUNCATE) {
opts.truncate(true);
}
if caps.contains(&FileCaps::WRITE)
|| caps.contains(&FileCaps::DATASYNC)
|| caps.contains(&FileCaps::ALLOCATE)
|| caps.contains(&FileCaps::FILESTAT_SET_SIZE)
if caps.contains(FileCaps::WRITE)
|| caps.contains(FileCaps::DATASYNC)
|| caps.contains(FileCaps::ALLOCATE)
|| caps.contains(FileCaps::FILESTAT_SET_SIZE)
{
opts.write(true);
} else {
@ -251,10 +201,10 @@ impl WasiDir for cap_std::fs::Dir {
// get_cap check.
opts.read(true);
}
if caps.contains(&FileCaps::READ) {
if caps.contains(FileCaps::READ) {
opts.read(true);
}
if fdflags.contains(&FdFlags::APPEND) {
if fdflags.contains(FdFlags::APPEND) {
opts.append(true);
}
// XXX what about rest of fdflags - dsync, sync become oflags.

140
crates/wasi-c2/src/file.rs

@ -1,4 +1,5 @@
use crate::Error;
use bitflags::bitflags;
use fs_set_times::SetTimes;
use std::ops::Deref;
use system_interface::fs::FileIoExt;
@ -50,60 +51,22 @@ impl From<&cap_std::fs::FileType> for FileType {
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct FdFlags {
flags: u32,
}
impl FdFlags {
/// Checks if `other` is a subset of those capabilties:
pub fn contains(&self, other: &Self) -> bool {
self.flags & other.flags == other.flags
}
pub fn empty() -> FdFlags {
FdFlags { flags: 0 }
}
pub const APPEND: FdFlags = FdFlags { flags: 1 };
pub const DSYNC: FdFlags = FdFlags { flags: 2 };
pub const NONBLOCK: FdFlags = FdFlags { flags: 4 };
pub const RSYNC: FdFlags = FdFlags { flags: 8 };
pub const SYNC: FdFlags = FdFlags { flags: 16 };
// etc
}
impl std::ops::BitOr for FdFlags {
type Output = FdFlags;
fn bitor(self, rhs: FdFlags) -> FdFlags {
FdFlags {
flags: self.flags | rhs.flags,
}
bitflags! {
pub struct FdFlags: u32 {
const APPEND = 0b1;
const DSYNC = 0b10;
const NONBLOCK = 0b100;
const RSYNC = 0b1000;
const SYNC = 0b10000;
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct OFlags {
flags: u32,
}
impl OFlags {
/// Checks if `other` is a subset of those capabilties:
pub fn contains(&self, other: &Self) -> bool {
self.flags & other.flags == other.flags
}
pub fn empty() -> Self {
OFlags { flags: 0 }
}
pub const CREATE: OFlags = OFlags { flags: 1 };
pub const DIRECTORY: OFlags = OFlags { flags: 2 };
pub const EXCLUSIVE: OFlags = OFlags { flags: 4 };
pub const TRUNCATE: OFlags = OFlags { flags: 8 };
}
impl std::ops::BitOr for OFlags {
type Output = OFlags;
fn bitor(self, rhs: OFlags) -> OFlags {
OFlags {
flags: self.flags | rhs.flags,
}
bitflags! {
pub struct OFlags: u32 {
const CREATE = 0b1;
const DIRECTORY = 0b10;
const EXCLUSIVE = 0b100;
const TRUNCATE = 0b1000;
}
}
@ -130,7 +93,7 @@ impl FileEntry {
}
pub fn get_cap(&self, caps: FileCaps) -> Result<&dyn WasiFile, Error> {
if self.caps.contains(&caps) {
if self.caps.contains(caps) {
Ok(self.file.deref())
} else {
Err(Error::FileNotCapable {
@ -141,7 +104,7 @@ impl FileEntry {
}
pub fn drop_caps_to(&mut self, caps: FileCaps) -> Result<(), Error> {
if self.caps.contains(&caps) {
if self.caps.contains(caps) {
self.caps = caps;
Ok(())
} else {
@ -158,63 +121,20 @@ impl FileEntry {
}
}
#[derive(Debug, Clone, Copy)]
pub struct FileCaps {
flags: u32,
}
impl FileCaps {
pub fn empty() -> Self {
FileCaps { flags: 0 }
}
/// Checks if `other` is a subset of those capabilties:
pub fn contains(&self, other: &Self) -> bool {
self.flags & other.flags == other.flags
}
/// Intersection of two sets of flags (bitwise and)
pub fn intersection(&self, rhs: &Self) -> Self {
FileCaps {
flags: self.flags & rhs.flags,
}
}
pub const DATASYNC: Self = FileCaps { flags: 1 };
pub const READ: Self = FileCaps { flags: 2 };
pub const SEEK: Self = FileCaps { flags: 4 };
pub const FDSTAT_SET_FLAGS: Self = FileCaps { flags: 8 };
pub const SYNC: Self = FileCaps { flags: 16 };
pub const TELL: Self = FileCaps { flags: 32 };
pub const WRITE: Self = FileCaps { flags: 64 };
pub const ADVISE: Self = FileCaps { flags: 128 };
pub const ALLOCATE: Self = FileCaps { flags: 256 };
pub const FILESTAT_GET: Self = FileCaps { flags: 512 };
pub const FILESTAT_SET_SIZE: Self = FileCaps { flags: 1024 };
pub const FILESTAT_SET_TIMES: Self = FileCaps { flags: 2048 };
pub fn all() -> FileCaps {
Self::DATASYNC
| Self::READ
| Self::SEEK
| Self::FDSTAT_SET_FLAGS
| Self::SYNC
| Self::TELL
| Self::WRITE
| Self::ADVISE
| Self::ALLOCATE
| Self::FILESTAT_GET
| Self::FILESTAT_SET_SIZE
| Self::FILESTAT_SET_TIMES
}
}
impl std::ops::BitOr for FileCaps {
type Output = FileCaps;
fn bitor(self, rhs: FileCaps) -> FileCaps {
FileCaps {
flags: self.flags | rhs.flags,
}
bitflags! {
pub struct FileCaps : u32 {
const DATASYNC = 0b1;
const READ = 0b10;
const SEEK = 0b100;
const FDSTAT_SET_FLAGS = 0b1000;
const SYNC = 0b10000;
const TELL = 0b100000;
const WRITE = 0b1000000;
const ADVISE = 0b10000000;
const ALLOCATE = 0b100000000;
const FILESTAT_GET = 0b1000000000;
const FILESTAT_SET_SIZE = 0b10000000000;
const FILESTAT_SET_TIMES = 0b100000000000;
}
}

84
crates/wasi-c2/src/snapshots/preview_1.rs

@ -768,10 +768,10 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
let oflags = OFlags::from(&oflags);
let fdflags = FdFlags::from(&fdflags);
let path = path.as_str()?;
if oflags.contains(&OFlags::DIRECTORY) {
if oflags.contains(&OFlags::CREATE)
|| oflags.contains(&OFlags::EXCLUSIVE)
|| oflags.contains(&OFlags::TRUNCATE)
if oflags.contains(OFlags::DIRECTORY) {
if oflags.contains(OFlags::CREATE)
|| oflags.contains(OFlags::EXCLUSIVE)
|| oflags.contains(OFlags::TRUNCATE)
{
return Err(Error::Inval);
}
@ -787,7 +787,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
Ok(types::Fd::from(fd))
} else {
let mut required_caps = DirCaps::OPEN;
if oflags.contains(&OFlags::CREATE) {
if oflags.contains(OFlags::CREATE) {
required_caps = required_caps | DirCaps::CREATE_FILE;
}
@ -976,40 +976,40 @@ impl From<&DirFdStat> for types::Fdstat {
impl From<&FileCaps> for types::Rights {
fn from(caps: &FileCaps) -> types::Rights {
let mut rights = types::Rights::empty();
if caps.contains(&FileCaps::DATASYNC) {
if caps.contains(FileCaps::DATASYNC) {
rights = rights | types::Rights::FD_DATASYNC;
}
if caps.contains(&FileCaps::READ) {
if caps.contains(FileCaps::READ) {
rights = rights | types::Rights::FD_READ;
}
if caps.contains(&FileCaps::SEEK) {
if caps.contains(FileCaps::SEEK) {
rights = rights | types::Rights::FD_SEEK;
}
if caps.contains(&FileCaps::FDSTAT_SET_FLAGS) {
if caps.contains(FileCaps::FDSTAT_SET_FLAGS) {
rights = rights | types::Rights::FD_FDSTAT_SET_FLAGS;
}
if caps.contains(&FileCaps::SYNC) {
if caps.contains(FileCaps::SYNC) {
rights = rights | types::Rights::FD_SYNC;
}
if caps.contains(&FileCaps::TELL) {
if caps.contains(FileCaps::TELL) {
rights = rights | types::Rights::FD_TELL;
}
if caps.contains(&FileCaps::WRITE) {
if caps.contains(FileCaps::WRITE) {
rights = rights | types::Rights::FD_WRITE;
}
if caps.contains(&FileCaps::ADVISE) {
if caps.contains(FileCaps::ADVISE) {
rights = rights | types::Rights::FD_ADVISE;
}
if caps.contains(&FileCaps::ALLOCATE) {
if caps.contains(FileCaps::ALLOCATE) {
rights = rights | types::Rights::FD_ALLOCATE;
}
if caps.contains(&FileCaps::FILESTAT_GET) {
if caps.contains(FileCaps::FILESTAT_GET) {
rights = rights | types::Rights::FD_FILESTAT_GET;
}
if caps.contains(&FileCaps::FILESTAT_SET_SIZE) {
if caps.contains(FileCaps::FILESTAT_SET_SIZE) {
rights = rights | types::Rights::FD_FILESTAT_SET_SIZE;
}
if caps.contains(&FileCaps::FILESTAT_SET_TIMES) {
if caps.contains(FileCaps::FILESTAT_SET_TIMES) {
rights = rights | types::Rights::FD_FILESTAT_SET_TIMES;
}
rights
@ -1064,52 +1064,52 @@ impl From<&types::Rights> for FileCaps {
impl From<&DirCaps> for types::Rights {
fn from(caps: &DirCaps) -> types::Rights {
let mut rights = types::Rights::empty();
if caps.contains(&DirCaps::CREATE_DIRECTORY) {
if caps.contains(DirCaps::CREATE_DIRECTORY) {
rights = rights | types::Rights::PATH_CREATE_DIRECTORY;
}
if caps.contains(&DirCaps::CREATE_FILE) {
if caps.contains(DirCaps::CREATE_FILE) {
rights = rights | types::Rights::PATH_CREATE_FILE;
}
if caps.contains(&DirCaps::LINK_SOURCE) {
if caps.contains(DirCaps::LINK_SOURCE) {
rights = rights | types::Rights::PATH_LINK_SOURCE;
}
if caps.contains(&DirCaps::LINK_TARGET) {
if caps.contains(DirCaps::LINK_TARGET) {
rights = rights | types::Rights::PATH_LINK_TARGET;
}
if caps.contains(&DirCaps::OPEN) {
if caps.contains(DirCaps::OPEN) {
rights = rights | types::Rights::PATH_OPEN;
}
if caps.contains(&DirCaps::READDIR) {
if caps.contains(DirCaps::READDIR) {
rights = rights | types::Rights::FD_READDIR;
}
if caps.contains(&DirCaps::READLINK) {
if caps.contains(DirCaps::READLINK) {
rights = rights | types::Rights::PATH_READLINK;
}
if caps.contains(&DirCaps::RENAME_SOURCE) {
if caps.contains(DirCaps::RENAME_SOURCE) {
rights = rights | types::Rights::PATH_RENAME_SOURCE;
}
if caps.contains(&DirCaps::RENAME_TARGET) {
if caps.contains(DirCaps::RENAME_TARGET) {
rights = rights | types::Rights::PATH_RENAME_TARGET;
}
if caps.contains(&DirCaps::SYMLINK) {
if caps.contains(DirCaps::SYMLINK) {
rights = rights | types::Rights::PATH_SYMLINK;
}
if caps.contains(&DirCaps::REMOVE_DIRECTORY) {
if caps.contains(DirCaps::REMOVE_DIRECTORY) {
rights = rights | types::Rights::PATH_REMOVE_DIRECTORY;
}
if caps.contains(&DirCaps::UNLINK_FILE) {
if caps.contains(DirCaps::UNLINK_FILE) {
rights = rights | types::Rights::PATH_UNLINK_FILE;
}
if caps.contains(&DirCaps::PATH_FILESTAT_GET) {
if caps.contains(DirCaps::PATH_FILESTAT_GET) {
rights = rights | types::Rights::PATH_FILESTAT_GET;
}
if caps.contains(&DirCaps::PATH_FILESTAT_SET_TIMES) {
if caps.contains(DirCaps::PATH_FILESTAT_SET_TIMES) {
rights = rights | types::Rights::PATH_FILESTAT_SET_TIMES;
}
if caps.contains(&DirCaps::FILESTAT_GET) {
if caps.contains(DirCaps::FILESTAT_GET) {
rights = rights | types::Rights::FD_FILESTAT_GET;
}
if caps.contains(&DirCaps::FILESTAT_SET_TIMES) {
if caps.contains(DirCaps::FILESTAT_SET_TIMES) {
rights = rights | types::Rights::FD_FILESTAT_SET_TIMES;
}
rights
@ -1189,19 +1189,19 @@ impl From<&FileType> for types::Filetype {
impl From<&FdFlags> for types::Fdflags {
fn from(fdflags: &FdFlags) -> types::Fdflags {
let mut out = types::Fdflags::empty();
if fdflags.contains(&FdFlags::APPEND) {
if fdflags.contains(FdFlags::APPEND) {
out = out | types::Fdflags::APPEND;
}
if fdflags.contains(&FdFlags::DSYNC) {
if fdflags.contains(FdFlags::DSYNC) {
out = out | types::Fdflags::DSYNC;
}
if fdflags.contains(&FdFlags::NONBLOCK) {
if fdflags.contains(FdFlags::NONBLOCK) {
out = out | types::Fdflags::NONBLOCK;
}
if fdflags.contains(&FdFlags::RSYNC) {
if fdflags.contains(FdFlags::RSYNC) {
out = out | types::Fdflags::RSYNC;
}
if fdflags.contains(&FdFlags::SYNC) {
if fdflags.contains(FdFlags::SYNC) {
out = out | types::Fdflags::SYNC;
}
out
@ -1252,16 +1252,16 @@ impl From<&types::Oflags> for OFlags {
impl From<&OFlags> for types::Oflags {
fn from(oflags: &OFlags) -> types::Oflags {
let mut out = types::Oflags::empty();
if oflags.contains(&OFlags::CREATE) {
if oflags.contains(OFlags::CREATE) {
out = out | types::Oflags::CREAT;
}
if oflags.contains(&OFlags::DIRECTORY) {
if oflags.contains(OFlags::DIRECTORY) {
out = out | types::Oflags::DIRECTORY;
}
if oflags.contains(&OFlags::EXCLUSIVE) {
if oflags.contains(OFlags::EXCLUSIVE) {
out = out | types::Oflags::EXCL;
}
if oflags.contains(&OFlags::TRUNCATE) {
if oflags.contains(OFlags::TRUNCATE) {
out = out | types::Oflags::TRUNC;
}
out

Loading…
Cancel
Save