impl WasiFile for cap_std::fs::File
This commit is contained in:
42
Cargo.lock
generated
42
Cargo.lock
generated
@@ -205,6 +205,31 @@ version = "1.3.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cap-primitives"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9069ed88e23a3fff56577518a238e6975920620cd5d00be8ca73aa46a96d5f5"
|
||||||
|
dependencies = [
|
||||||
|
"errno",
|
||||||
|
"fs-set-times",
|
||||||
|
"ipnet",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"posish",
|
||||||
|
"winapi",
|
||||||
|
"winx 0.20.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cap-std"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eacf34fea6948253011b8771b7ae6258a2ae15c7ba38e78b7dd60a785af354d2"
|
||||||
|
dependencies = [
|
||||||
|
"cap-primitives",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "capstone"
|
name = "capstone"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -897,6 +922,16 @@ version = "1.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fs-set-times"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a37c11eb7933093dd2a56c9c4d934a754b56e672fb8c2b46d50997dd2b4392d"
|
||||||
|
dependencies = [
|
||||||
|
"posish",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fst"
|
name = "fst"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
@@ -1042,6 +1077,12 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnet"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iter-enum"
|
name = "iter-enum"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@@ -2311,6 +2352,7 @@ name = "wasi-c2"
|
|||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"cap-std",
|
||||||
"getrandom 0.2.0",
|
"getrandom 0.2.0",
|
||||||
"libc",
|
"libc",
|
||||||
"system-interface",
|
"system-interface",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ getrandom = { version = "0.2.0", features = ["std"] }
|
|||||||
wiggle = { path = "../wiggle", default-features = false, version = "0.21.0" }
|
wiggle = { path = "../wiggle", default-features = false, version = "0.21.0" }
|
||||||
tracing = "0.1.19"
|
tracing = "0.1.19"
|
||||||
system-interface = { path = "../../../system-interface" }
|
system-interface = { path = "../../../system-interface" }
|
||||||
|
cap-std = "*"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ impl WasiCtx {
|
|||||||
file: Box<dyn WasiFile>,
|
file: Box<dyn WasiFile>,
|
||||||
base_caps: FileCaps,
|
base_caps: FileCaps,
|
||||||
inheriting_caps: FileCaps,
|
inheriting_caps: FileCaps,
|
||||||
path: Option<PathBuf>,
|
|
||||||
) {
|
) {
|
||||||
let e = FileEntry {
|
let e = FileEntry {
|
||||||
base_caps,
|
base_caps,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// this file is extremely wip
|
||||||
|
#![allow(dead_code, unused_variables)]
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub trait WasiDir {}
|
pub trait WasiDir {}
|
||||||
|
|||||||
@@ -3,37 +3,20 @@ use std::ops::Deref;
|
|||||||
use system_interface::fs::FileIoExt;
|
use system_interface::fs::FileIoExt;
|
||||||
|
|
||||||
pub trait WasiFile: FileIoExt {
|
pub trait WasiFile: FileIoExt {
|
||||||
fn allocate(&self, _offset: u64, _len: u64) -> Result<(), Error> {
|
fn datasync(&self) -> Result<(), Error>;
|
||||||
todo!("to implement fd_allocate, FileIoExt needs methods to get and set length of a file")
|
fn sync(&self) -> Result<(), Error>;
|
||||||
}
|
fn get_filetype(&self) -> Result<Filetype, Error>;
|
||||||
fn datasync(&self) -> Result<(), Error> {
|
fn get_fdflags(&self) -> Result<FdFlags, Error>;
|
||||||
todo!("FileIoExt has no facilities for sync");
|
fn get_oflags(&self) -> Result<OFlags, Error>;
|
||||||
}
|
fn set_oflags(&self, _flags: OFlags) -> Result<(), Error>;
|
||||||
fn filetype(&self) -> Filetype {
|
fn get_filestat(&self) -> Result<Filestat, Error>;
|
||||||
todo!("FileIoExt has no facilities for filetype");
|
fn set_filestat_times(
|
||||||
}
|
|
||||||
fn oflags(&self) -> OFlags {
|
|
||||||
todo!("FileIoExt has no facilities for oflags");
|
|
||||||
}
|
|
||||||
fn set_oflags(&self, _flags: OFlags) -> Result<(), Error> {
|
|
||||||
todo!("FileIoExt has no facilities for oflags");
|
|
||||||
}
|
|
||||||
fn filestat_get(&self) -> Result<Filestat, Error> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
fn filestat_set_times(
|
|
||||||
&self,
|
&self,
|
||||||
_atim: Option<FilestatSetTime>,
|
_atim: Option<FilestatSetTime>,
|
||||||
_mtim: Option<FilestatSetTime>,
|
_mtim: Option<FilestatSetTime>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error>;
|
||||||
todo!()
|
fn set_filestat_size(&self, _size: u64) -> Result<(), Error>;
|
||||||
}
|
fn allocate(&self, _offset: u64, _len: u64) -> Result<(), Error>;
|
||||||
fn filestat_set_size(&self, _size: u64) -> Result<(), Error> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
fn sync(&self) -> Result<(), Error> {
|
|
||||||
todo!("FileIoExt has no facilities for sync")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@@ -45,6 +28,24 @@ pub enum Filetype {
|
|||||||
SocketStream,
|
SocketStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 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
|
||||||
|
}
|
||||||
|
|
||||||
pub struct OFlags {
|
pub struct OFlags {
|
||||||
flags: u32,
|
flags: u32,
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ pub struct Filestat {
|
|||||||
inode: u64,
|
inode: u64,
|
||||||
filetype: Filetype,
|
filetype: Filetype,
|
||||||
nlink: u64,
|
nlink: u64,
|
||||||
size: usize,
|
size: u64,
|
||||||
atim: std::time::SystemTime,
|
atim: std::time::SystemTime,
|
||||||
mtim: std::time::SystemTime,
|
mtim: std::time::SystemTime,
|
||||||
ctim: std::time::SystemTime,
|
ctim: std::time::SystemTime,
|
||||||
@@ -101,6 +102,15 @@ impl FileEntry {
|
|||||||
Err(Error::FileNotCapable(caps))
|
Err(Error::FileNotCapable(caps))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_fdstat(&self) -> Result<FdStat, Error> {
|
||||||
|
Ok(FdStat {
|
||||||
|
filetype: self.file.get_filetype()?,
|
||||||
|
base_caps: self.base_caps,
|
||||||
|
inheriting_caps: self.inheriting_caps,
|
||||||
|
flags: self.file.get_fdflags()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@@ -146,3 +156,91 @@ impl std::fmt::Display for FileCaps {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FdStat {
|
||||||
|
pub filetype: Filetype,
|
||||||
|
pub base_caps: FileCaps,
|
||||||
|
pub inheriting_caps: FileCaps,
|
||||||
|
pub flags: FdFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WasiFile for cap_std::fs::File {
|
||||||
|
fn datasync(&self) -> Result<(), Error> {
|
||||||
|
self.sync_data()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn sync(&self) -> Result<(), Error> {
|
||||||
|
self.sync_all()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn get_filetype(&self) -> Result<Filetype, Error> {
|
||||||
|
let meta = self.metadata()?;
|
||||||
|
// cap-std's Metadata/FileType only offers booleans indicating whether a file is a directory,
|
||||||
|
// symlink, or regular file.
|
||||||
|
// Directories should be excluded by the type system.
|
||||||
|
if meta.is_file() {
|
||||||
|
Ok(Filetype::RegularFile)
|
||||||
|
} else {
|
||||||
|
Err(Error::Badf) // XXX idk what to do here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_fdflags(&self) -> Result<FdFlags, Error> {
|
||||||
|
// XXX cap-std doesnt expose append, dsync, nonblock, rsync, sync
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn get_oflags(&self) -> Result<OFlags, Error> {
|
||||||
|
// XXX what if it was opened append, async, nonblock...
|
||||||
|
let perms = self.metadata()?.permissions();
|
||||||
|
if perms.readonly() {
|
||||||
|
Ok(OFlags::RDONLY)
|
||||||
|
} else {
|
||||||
|
Ok(OFlags::RDWR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn set_oflags(&self, _flags: OFlags) -> Result<(), Error> {
|
||||||
|
// XXX cap-std::fs::Permissions does not export a constructor to build this out of
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
self.set_permissions(todo!())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn get_filestat(&self) -> Result<Filestat, Error> {
|
||||||
|
// XXX cap-std does not expose every part of filestat
|
||||||
|
#![allow(unreachable_code, unused_variables)]
|
||||||
|
let meta = self.metadata()?;
|
||||||
|
Ok(Filestat {
|
||||||
|
device_id: todo!(),
|
||||||
|
inode: todo!(),
|
||||||
|
filetype: self.get_filetype()?,
|
||||||
|
nlink: todo!(),
|
||||||
|
size: meta.len(),
|
||||||
|
atim: meta.accessed()?.into_std(),
|
||||||
|
mtim: meta.modified()?.into_std(),
|
||||||
|
ctim: meta.created()?.into_std(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn set_filestat_times(
|
||||||
|
&self,
|
||||||
|
_atim: Option<FilestatSetTime>,
|
||||||
|
_mtim: Option<FilestatSetTime>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// XXX cap-std does not expose a way to set accessed time or modified time
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn set_filestat_size(&self, size: u64) -> Result<(), Error> {
|
||||||
|
self.set_len(size)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn allocate(&self, offset: u64, len: u64) -> Result<(), Error> {
|
||||||
|
let metadata = self.metadata()?;
|
||||||
|
let current_size = metadata.len();
|
||||||
|
let wanted_size = offset.checked_add(len).ok_or(Error::TooBig)?;
|
||||||
|
// This check will be unnecessary when rust-lang/rust#63326 is fixed
|
||||||
|
if wanted_size > i64::max_value() as u64 {
|
||||||
|
return Err(Error::TooBig);
|
||||||
|
}
|
||||||
|
if wanted_size > current_size {
|
||||||
|
self.set_len(wanted_size)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
use crate::dir::{DirEntry, TableDirExt};
|
use crate::dir::{DirEntry, TableDirExt};
|
||||||
use crate::file::{FileCaps, FileEntry, Filestat, FilestatSetTime, Filetype, OFlags};
|
use crate::file::{
|
||||||
|
FdFlags, FdStat, FileCaps, FileEntry, Filestat, FilestatSetTime, Filetype, OFlags,
|
||||||
|
};
|
||||||
use crate::{Error, WasiCtx};
|
use crate::{Error, WasiCtx};
|
||||||
use std::cell::RefMut;
|
use std::cell::RefMut;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -191,7 +193,8 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
fn fd_fdstat_get(&self, fd: types::Fd) -> Result<types::Fdstat, Error> {
|
fn fd_fdstat_get(&self, fd: types::Fd) -> Result<types::Fdstat, Error> {
|
||||||
let table = self.table();
|
let table = self.table();
|
||||||
let file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
let file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
||||||
Ok(types::Fdstat::from(file_entry.deref()))
|
let fdstat = file_entry.get_fdstat()?;
|
||||||
|
Ok(types::Fdstat::from(&fdstat))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<(), Error> {
|
fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<(), Error> {
|
||||||
@@ -227,7 +230,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
let table = self.table();
|
let table = self.table();
|
||||||
let file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
let file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
||||||
let f = file_entry.get_cap(FileCaps::FILESTAT_GET)?;
|
let f = file_entry.get_cap(FileCaps::FILESTAT_GET)?;
|
||||||
let filestat = f.filestat_get()?;
|
let filestat = f.get_filestat()?;
|
||||||
Ok(filestat.into())
|
Ok(filestat.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +238,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
let table = self.table();
|
let table = self.table();
|
||||||
let file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
let file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
||||||
let f = file_entry.get_cap(FileCaps::FILESTAT_SET_SIZE)?;
|
let f = file_entry.get_cap(FileCaps::FILESTAT_SET_SIZE)?;
|
||||||
f.filestat_set_size(size)?;
|
f.set_filestat_size(size)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +281,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
f.filestat_set_times(atim, mtim)?;
|
f.set_filestat_times(atim, mtim)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,13 +652,13 @@ impl From<types::Advice> for system_interface::fs::Advice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&FileEntry> for types::Fdstat {
|
impl From<&FdStat> for types::Fdstat {
|
||||||
fn from(entry: &FileEntry) -> types::Fdstat {
|
fn from(fdstat: &FdStat) -> types::Fdstat {
|
||||||
types::Fdstat {
|
types::Fdstat {
|
||||||
fs_filetype: types::Filetype::from(&entry.file.filetype()),
|
fs_filetype: types::Filetype::from(&fdstat.filetype),
|
||||||
fs_rights_base: types::Rights::from(&entry.base_caps),
|
fs_rights_base: types::Rights::from(&fdstat.base_caps),
|
||||||
fs_rights_inheriting: types::Rights::from(&entry.base_caps),
|
fs_rights_inheriting: types::Rights::from(&fdstat.inheriting_caps),
|
||||||
fs_flags: types::Fdflags::from(&entry.file.oflags()),
|
fs_flags: types::Fdflags::from(&fdstat.flags),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,9 +689,9 @@ impl From<&Filetype> for types::Filetype {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<&OFlags> for types::Fdflags {
|
impl From<&FdFlags> for types::Fdflags {
|
||||||
fn from(caps: &OFlags) -> types::Fdflags {
|
fn from(fdflags: &FdFlags) -> types::Fdflags {
|
||||||
todo!("translate OFlags flags to Fdflags flags")
|
todo!("translate internal to Fdflags")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user