redesign how caps fit into entries!
This commit is contained in:
@@ -26,36 +26,23 @@ impl WasiCtx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_file(
|
pub fn insert_file(&self, fd: u32, file: Box<dyn WasiFile>, caps: FileCaps) {
|
||||||
&self,
|
self.table()
|
||||||
fd: u32,
|
.insert_at(fd, Box::new(FileEntry::new(caps, file)));
|
||||||
file: Box<dyn WasiFile>,
|
|
||||||
base_caps: FileCaps,
|
|
||||||
inheriting_caps: FileCaps,
|
|
||||||
) {
|
|
||||||
let e = FileEntry {
|
|
||||||
base_caps,
|
|
||||||
inheriting_caps,
|
|
||||||
file,
|
|
||||||
};
|
|
||||||
self.table().insert_at(fd, Box::new(e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_dir(
|
pub fn insert_dir(
|
||||||
&self,
|
&self,
|
||||||
fd: u32,
|
fd: u32,
|
||||||
dir: Box<dyn WasiDir>,
|
dir: Box<dyn WasiDir>,
|
||||||
base_caps: DirCaps,
|
caps: DirCaps,
|
||||||
inheriting_caps: DirCaps,
|
file_caps: FileCaps,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
) {
|
) {
|
||||||
let e = DirEntry {
|
self.table().insert_at(
|
||||||
base_caps,
|
fd,
|
||||||
inheriting_caps,
|
Box::new(DirEntry::new(caps, file_caps, Some(path), dir)),
|
||||||
preopen_path: Some(path),
|
);
|
||||||
dir,
|
|
||||||
};
|
|
||||||
self.table().insert_at(fd, Box::new(e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table(&self) -> RefMut<Table> {
|
pub fn table(&self) -> RefMut<Table> {
|
||||||
@@ -79,8 +66,7 @@ impl WasiCtxBuilder {
|
|||||||
self.0.insert_file(
|
self.0.insert_file(
|
||||||
0,
|
0,
|
||||||
f,
|
f,
|
||||||
FileCaps::READ, // XXX probably more rights are ok
|
FileCaps::READ, // XXX fixme: more rights are ok, but this is read-only
|
||||||
FileCaps::READ,
|
|
||||||
);
|
);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -89,8 +75,7 @@ impl WasiCtxBuilder {
|
|||||||
self.0.insert_file(
|
self.0.insert_file(
|
||||||
1,
|
1,
|
||||||
f,
|
f,
|
||||||
FileCaps::WRITE, // XXX probably more rights are ok
|
FileCaps::WRITE, // XXX fixme: more rights are ok, but this is append only
|
||||||
FileCaps::WRITE,
|
|
||||||
);
|
);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -99,8 +84,7 @@ impl WasiCtxBuilder {
|
|||||||
self.0.insert_file(
|
self.0.insert_file(
|
||||||
2,
|
2,
|
||||||
f,
|
f,
|
||||||
FileCaps::WRITE, // XXX probably more rights are ok
|
FileCaps::WRITE, // XXX fixme: more rights are ok, but this is append only
|
||||||
FileCaps::WRITE,
|
|
||||||
);
|
);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -116,14 +100,14 @@ impl WasiCtxBuilder {
|
|||||||
dir: Box<dyn WasiDir>,
|
dir: Box<dyn WasiDir>,
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
) -> Result<&mut Self, Error> {
|
) -> Result<&mut Self, Error> {
|
||||||
let base_caps = DirCaps::OPEN;
|
let caps = DirCaps::OPEN | DirCaps::CREATE_FILE; // XXX more base caps
|
||||||
let inheriting_caps = DirCaps::OPEN;
|
let file_caps = FileCaps::READ | FileCaps::WRITE; // XXX more base caps
|
||||||
self.0.table().push(Box::new(DirEntry {
|
self.0.table().push(Box::new(DirEntry::new(
|
||||||
base_caps,
|
caps,
|
||||||
inheriting_caps,
|
file_caps,
|
||||||
preopen_path: Some(path.as_ref().to_owned()),
|
Some(path.as_ref().to_owned()),
|
||||||
dir,
|
dir,
|
||||||
}))?;
|
)))?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use crate::error::Error;
|
|||||||
use crate::file::{FileCaps, OFlags, WasiFile};
|
use crate::file::{FileCaps, OFlags, WasiFile};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
pub trait WasiDir {
|
pub trait WasiDir {
|
||||||
fn open_file(
|
fn open_file(
|
||||||
@@ -24,27 +23,60 @@ pub trait WasiDir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct DirEntry {
|
pub(crate) struct DirEntry {
|
||||||
pub(crate) base_caps: DirCaps,
|
caps: DirCaps,
|
||||||
pub(crate) inheriting_caps: DirCaps,
|
file_caps: FileCaps,
|
||||||
pub(crate) preopen_path: Option<PathBuf>, // precondition: PathBuf is valid unicode
|
preopen_path: Option<PathBuf>, // precondition: PathBuf is valid unicode
|
||||||
pub(crate) dir: Box<dyn WasiDir>,
|
dir: Box<dyn WasiDir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirEntry {
|
impl DirEntry {
|
||||||
|
pub fn new(
|
||||||
|
caps: DirCaps,
|
||||||
|
file_caps: FileCaps,
|
||||||
|
preopen_path: Option<PathBuf>,
|
||||||
|
dir: Box<dyn WasiDir>,
|
||||||
|
) -> Self {
|
||||||
|
DirEntry {
|
||||||
|
caps,
|
||||||
|
file_caps,
|
||||||
|
preopen_path,
|
||||||
|
dir,
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn get_cap(&self, caps: DirCaps) -> Result<&dyn WasiDir, Error> {
|
pub fn get_cap(&self, caps: DirCaps) -> Result<&dyn WasiDir, Error> {
|
||||||
if self.base_caps.contains(&caps) && self.inheriting_caps.contains(&caps) {
|
if self.caps.contains(&caps) {
|
||||||
Ok(self.dir.deref())
|
Ok(self.dir.deref())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::DirNotCapable(caps))
|
Err(Error::DirNotCapable {
|
||||||
|
desired: caps,
|
||||||
|
has: self.caps,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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) {
|
||||||
|
self.caps = caps;
|
||||||
|
self.file_caps = file_caps;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::NotCapable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn child_dir_caps(&self, desired_caps: DirCaps) -> DirCaps {
|
||||||
|
self.caps.intersection(&desired_caps)
|
||||||
|
}
|
||||||
|
pub fn child_file_caps(&self, desired_caps: FileCaps) -> FileCaps {
|
||||||
|
self.file_caps.intersection(&desired_caps)
|
||||||
|
}
|
||||||
pub fn get_dirstat(&self) -> DirStat {
|
pub fn get_dirstat(&self) -> DirStat {
|
||||||
DirStat {
|
DirStat {
|
||||||
base_caps: self.base_caps,
|
dir_caps: self.caps,
|
||||||
inheriting_caps: self.inheriting_caps,
|
file_caps: self.file_caps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn preopen_path(&self) -> &Option<PathBuf> {
|
||||||
|
&self.preopen_path
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@@ -62,6 +94,12 @@ impl DirCaps {
|
|||||||
self.flags & other.flags == other.flags
|
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_DIRECTORY: Self = DirCaps { flags: 1 };
|
||||||
pub const CREATE_FILE: Self = DirCaps { flags: 2 };
|
pub const CREATE_FILE: Self = DirCaps { flags: 2 };
|
||||||
pub const LINK_SOURCE: Self = DirCaps { flags: 4 };
|
pub const LINK_SOURCE: Self = DirCaps { flags: 4 };
|
||||||
@@ -86,8 +124,8 @@ impl std::ops::BitOr for DirCaps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DirStat {
|
pub struct DirStat {
|
||||||
pub base_caps: DirCaps,
|
pub file_caps: FileCaps,
|
||||||
pub inheriting_caps: DirCaps,
|
pub dir_caps: DirCaps,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for DirCaps {
|
impl std::fmt::Display for DirCaps {
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ pub enum Error {
|
|||||||
GetRandom(#[from] getrandom::Error),
|
GetRandom(#[from] getrandom::Error),
|
||||||
|
|
||||||
/// Errno::Notcapable: Extension: Capabilities insufficient
|
/// Errno::Notcapable: Extension: Capabilities insufficient
|
||||||
#[error("File not capable: {0}")]
|
#[error("File not capable: desired {desired}, has {has}")]
|
||||||
FileNotCapable(FileCaps),
|
FileNotCapable { desired: FileCaps, has: FileCaps },
|
||||||
|
|
||||||
/// Errno::Notcapable: Extension: Capabilities insufficient
|
/// Errno::Notcapable: Extension: Capabilities insufficient
|
||||||
#[error("Directory not capable: {0}")]
|
#[error("Directory not capable: desired {desired}, has {has}")]
|
||||||
DirNotCapable(DirCaps),
|
DirNotCapable { desired: DirCaps, has: DirCaps },
|
||||||
|
|
||||||
/// Idk what the deal with this guy is yet
|
/// Idk what the deal with this guy is yet
|
||||||
#[error("Table overflow")]
|
#[error("Table overflow")]
|
||||||
|
|||||||
@@ -98,25 +98,39 @@ pub struct Filestat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct FileEntry {
|
pub(crate) struct FileEntry {
|
||||||
pub(crate) base_caps: FileCaps,
|
caps: FileCaps,
|
||||||
pub(crate) inheriting_caps: FileCaps,
|
file: Box<dyn WasiFile>,
|
||||||
pub(crate) file: Box<dyn WasiFile>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileEntry {
|
impl FileEntry {
|
||||||
|
pub fn new(caps: FileCaps, file: Box<dyn WasiFile>) -> Self {
|
||||||
|
FileEntry { caps, file }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_cap(&self, caps: FileCaps) -> Result<&dyn WasiFile, Error> {
|
pub fn get_cap(&self, caps: FileCaps) -> Result<&dyn WasiFile, Error> {
|
||||||
if self.base_caps.contains(&caps) && self.inheriting_caps.contains(&caps) {
|
if self.caps.contains(&caps) {
|
||||||
Ok(self.file.deref())
|
Ok(self.file.deref())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::FileNotCapable(caps))
|
Err(Error::FileNotCapable {
|
||||||
|
desired: caps,
|
||||||
|
has: self.caps,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drop_caps_to(&mut self, caps: FileCaps) -> Result<(), Error> {
|
||||||
|
if self.caps.contains(&caps) {
|
||||||
|
self.caps = caps;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::NotCapable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fdstat(&self) -> Result<FdStat, Error> {
|
pub fn get_fdstat(&self) -> Result<FdStat, Error> {
|
||||||
Ok(FdStat {
|
Ok(FdStat {
|
||||||
filetype: self.file.get_filetype()?,
|
filetype: self.file.get_filetype()?,
|
||||||
base_caps: self.base_caps,
|
caps: self.caps,
|
||||||
inheriting_caps: self.inheriting_caps,
|
|
||||||
flags: self.file.get_fdflags()?,
|
flags: self.file.get_fdflags()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -137,6 +151,13 @@ impl FileCaps {
|
|||||||
self.flags & other.flags == other.flags
|
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 DATASYNC: Self = FileCaps { flags: 1 };
|
||||||
pub const READ: Self = FileCaps { flags: 2 };
|
pub const READ: Self = FileCaps { flags: 2 };
|
||||||
pub const SEEK: Self = FileCaps { flags: 4 };
|
pub const SEEK: Self = FileCaps { flags: 4 };
|
||||||
@@ -168,8 +189,7 @@ impl std::fmt::Display for FileCaps {
|
|||||||
|
|
||||||
pub struct FdStat {
|
pub struct FdStat {
|
||||||
pub filetype: Filetype,
|
pub filetype: Filetype,
|
||||||
pub base_caps: FileCaps,
|
pub caps: FileCaps,
|
||||||
pub inheriting_caps: FileCaps,
|
|
||||||
pub flags: FdFlags,
|
pub flags: FdFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
} else if table.is::<DirEntry>(fd) {
|
} else if table.is::<DirEntry>(fd) {
|
||||||
// We cannot close preopened directories
|
// We cannot close preopened directories
|
||||||
let dir_entry: RefMut<DirEntry> = table.get(fd).unwrap();
|
let dir_entry: RefMut<DirEntry> = table.get(fd).unwrap();
|
||||||
if dir_entry.preopen_path.is_some() {
|
if dir_entry.preopen_path().is_some() {
|
||||||
return Err(Error::Notsup);
|
return Err(Error::Notsup);
|
||||||
}
|
}
|
||||||
drop(dir_entry);
|
drop(dir_entry);
|
||||||
@@ -230,17 +230,18 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
fs_rights_inheriting: types::Rights,
|
fs_rights_inheriting: types::Rights,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let table = self.table();
|
let table = self.table();
|
||||||
let mut file_entry: RefMut<FileEntry> = table.get(u32::from(fd))?;
|
let fd = u32::from(fd);
|
||||||
let base_caps = FileCaps::try_from(&fs_rights_base)?;
|
if table.is::<FileEntry>(fd) {
|
||||||
let inheriting_caps = FileCaps::try_from(&fs_rights_inheriting)?;
|
let mut file_entry: RefMut<FileEntry> = table.get(fd)?;
|
||||||
if file_entry.base_caps.contains(&base_caps)
|
let file_caps = FileCaps::from(&fs_rights_base);
|
||||||
&& file_entry.inheriting_caps.contains(&inheriting_caps)
|
file_entry.drop_caps_to(file_caps)
|
||||||
{
|
} else if table.is::<DirEntry>(fd) {
|
||||||
file_entry.base_caps = base_caps;
|
let mut dir_entry: RefMut<DirEntry> = table.get(fd)?;
|
||||||
file_entry.inheriting_caps = inheriting_caps;
|
let dir_caps = DirCaps::from(&fs_rights_base);
|
||||||
Ok(())
|
let file_caps = FileCaps::from(&fs_rights_inheriting);
|
||||||
|
dir_entry.drop_caps_to(dir_caps, file_caps)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotCapable)
|
Err(Error::Badf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +413,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
fn fd_prestat_get(&self, fd: types::Fd) -> Result<types::Prestat, Error> {
|
fn fd_prestat_get(&self, fd: types::Fd) -> Result<types::Prestat, Error> {
|
||||||
let table = self.table();
|
let table = self.table();
|
||||||
let dir_entry: RefMut<DirEntry> = table.get(u32::from(fd)).map_err(|_| Error::Badf)?;
|
let dir_entry: RefMut<DirEntry> = table.get(u32::from(fd)).map_err(|_| Error::Badf)?;
|
||||||
if let Some(ref preopen) = dir_entry.preopen_path {
|
if let Some(ref preopen) = dir_entry.preopen_path() {
|
||||||
let path_str = preopen.to_str().ok_or(Error::Notsup)?;
|
let path_str = preopen.to_str().ok_or(Error::Notsup)?;
|
||||||
let pr_name_len =
|
let pr_name_len =
|
||||||
u32::try_from(path_str.as_bytes().len()).map_err(|_| Error::Overflow)?;
|
u32::try_from(path_str.as_bytes().len()).map_err(|_| Error::Overflow)?;
|
||||||
@@ -430,7 +431,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let table = self.table();
|
let table = self.table();
|
||||||
let dir_entry: RefMut<DirEntry> = table.get(u32::from(fd)).map_err(|_| Error::Notdir)?;
|
let dir_entry: RefMut<DirEntry> = table.get(u32::from(fd)).map_err(|_| Error::Notdir)?;
|
||||||
if let Some(ref preopen) = dir_entry.preopen_path {
|
if let Some(ref preopen) = dir_entry.preopen_path() {
|
||||||
let path_bytes = preopen.to_str().ok_or(Error::Notsup)?.as_bytes();
|
let path_bytes = preopen.to_str().ok_or(Error::Notsup)?.as_bytes();
|
||||||
let path_len = path_bytes.len();
|
let path_len = path_bytes.len();
|
||||||
if path_len < path_max_len as usize {
|
if path_len < path_max_len as usize {
|
||||||
@@ -573,7 +574,6 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
) -> Result<types::Fd, Error> {
|
) -> Result<types::Fd, Error> {
|
||||||
let mut table = self.table();
|
let mut table = self.table();
|
||||||
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
|
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
|
||||||
let dir = dir_entry.get_cap(DirCaps::OPEN)?;
|
|
||||||
|
|
||||||
let symlink_follow = dirflags.contains(&types::Lookupflags::SYMLINK_FOLLOW);
|
let symlink_follow = dirflags.contains(&types::Lookupflags::SYMLINK_FOLLOW);
|
||||||
|
|
||||||
@@ -587,33 +587,28 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
{
|
{
|
||||||
return Err(Error::Inval);
|
return Err(Error::Inval);
|
||||||
}
|
}
|
||||||
|
let dir = dir_entry.get_cap(DirCaps::OPEN)?;
|
||||||
let child_dir = dir.open_dir(symlink_follow, path.deref())?;
|
let child_dir = dir.open_dir(symlink_follow, path.deref())?;
|
||||||
|
let file_caps = dir_entry.child_file_caps(FileCaps::from(&fs_rights_base));
|
||||||
let base_caps = DirCaps::from(&fs_rights_base);
|
let dir_caps = dir_entry.child_dir_caps(DirCaps::from(&fs_rights_inheriting));
|
||||||
let inheriting_caps = DirCaps::from(&fs_rights_inheriting);
|
|
||||||
drop(dir);
|
drop(dir);
|
||||||
drop(dir_entry);
|
drop(dir_entry);
|
||||||
let fd = table.push(Box::new(DirEntry {
|
let fd = table.push(Box::new(DirEntry::new(
|
||||||
dir: child_dir,
|
dir_caps, file_caps, None, child_dir,
|
||||||
base_caps,
|
)))?;
|
||||||
inheriting_caps,
|
|
||||||
preopen_path: None,
|
|
||||||
}))?;
|
|
||||||
Ok(types::Fd::from(fd))
|
Ok(types::Fd::from(fd))
|
||||||
} else {
|
} else {
|
||||||
// XXX go back and check these caps conversions - probably need to validate them
|
let mut required_caps = DirCaps::OPEN;
|
||||||
// against ???
|
if oflags.contains(&OFlags::CREATE) {
|
||||||
let base_caps = FileCaps::from(&fs_rights_base);
|
required_caps = required_caps | DirCaps::CREATE_FILE;
|
||||||
let inheriting_caps = FileCaps::from(&fs_rights_inheriting);
|
}
|
||||||
|
|
||||||
let file = dir.open_file(symlink_follow, path.deref(), oflags, base_caps)?;
|
let dir = dir_entry.get_cap(required_caps)?;
|
||||||
|
let file_caps = dir_entry.child_file_caps(FileCaps::from(&fs_rights_base));
|
||||||
|
let file = dir.open_file(symlink_follow, path.deref(), oflags, file_caps)?;
|
||||||
drop(dir);
|
drop(dir);
|
||||||
drop(dir_entry);
|
drop(dir_entry);
|
||||||
let fd = table.push(Box::new(FileEntry {
|
let fd = table.push(Box::new(FileEntry::new(file_caps, file)))?;
|
||||||
file,
|
|
||||||
base_caps,
|
|
||||||
inheriting_caps,
|
|
||||||
}))?;
|
|
||||||
Ok(types::Fd::from(fd))
|
Ok(types::Fd::from(fd))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -724,8 +719,8 @@ impl From<&FdStat> for types::Fdstat {
|
|||||||
fn from(fdstat: &FdStat) -> types::Fdstat {
|
fn from(fdstat: &FdStat) -> types::Fdstat {
|
||||||
types::Fdstat {
|
types::Fdstat {
|
||||||
fs_filetype: types::Filetype::from(&fdstat.filetype),
|
fs_filetype: types::Filetype::from(&fdstat.filetype),
|
||||||
fs_rights_base: types::Rights::from(&fdstat.base_caps),
|
fs_rights_base: types::Rights::from(&fdstat.caps),
|
||||||
fs_rights_inheriting: types::Rights::from(&fdstat.inheriting_caps),
|
fs_rights_inheriting: types::Rights::empty(),
|
||||||
fs_flags: types::Fdflags::from(&fdstat.flags),
|
fs_flags: types::Fdflags::from(&fdstat.flags),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -735,8 +730,8 @@ impl From<&DirStat> for types::Fdstat {
|
|||||||
fn from(dirstat: &DirStat) -> types::Fdstat {
|
fn from(dirstat: &DirStat) -> types::Fdstat {
|
||||||
types::Fdstat {
|
types::Fdstat {
|
||||||
fs_filetype: types::Filetype::Directory,
|
fs_filetype: types::Filetype::Directory,
|
||||||
fs_rights_base: types::Rights::from(&dirstat.base_caps),
|
fs_rights_base: types::Rights::from(&dirstat.file_caps),
|
||||||
fs_rights_inheriting: types::Rights::from(&dirstat.inheriting_caps),
|
fs_rights_inheriting: types::Rights::from(&dirstat.dir_caps),
|
||||||
fs_flags: types::Fdflags::empty(),
|
fs_flags: types::Fdflags::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user