fixup filetype nonsense

tried to go my own way here, bad idea, stick to the design of wasi buddy
This commit is contained in:
Pat Hickey
2020-12-18 12:30:40 -08:00
parent 82edae32b7
commit 8cc1ab7720
5 changed files with 72 additions and 71 deletions

View File

@@ -1,7 +1,5 @@
// this file is extremely wip
#![allow(dead_code, unused_variables)]
use crate::error::Error; use crate::error::Error;
use crate::file::{FileCaps, OFlags, WasiFile}; use crate::file::{FileCaps, FileType, OFlags, WasiFile};
use std::ops::Deref; use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@@ -171,18 +169,11 @@ impl TableDirExt for crate::table::Table {
} }
} }
pub enum DirEntityType {
File(crate::file::Filetype),
Directory,
SymbolicLink,
Unknown,
}
pub struct ReaddirEntity { pub struct ReaddirEntity {
next: ReaddirCursor, pub next: ReaddirCursor,
inode: u64, pub inode: u64,
namelen: u64, pub namelen: u64,
direnttype: DirEntityType, pub filetype: FileType,
} }
pub struct ReaddirCursor(u64); pub struct ReaddirCursor(u64);
@@ -262,29 +253,19 @@ impl WasiDir for cap_std::fs::Dir {
.enumerate() .enumerate()
.skip(u64::from(cursor) as usize); .skip(u64::from(cursor) as usize);
Ok(Box::new(rd.map(|(ix, entry)| { Ok(Box::new(rd.map(|(ix, entry)| {
use cap_fs_ext::MetadataExt;
let entry = entry?; let entry = entry?;
let file_type = entry.file_type()?; let meta = entry.metadata()?;
let direnttype = if file_type.is_dir() { let inode = meta.ino();
DirEntityType::Directory let filetype = FileType::from(&meta.file_type());
} else if file_type.is_file() { let name = entry
DirEntityType::File(crate::file::Filetype::RegularFile) // XXX unify this with conversion in `impl WasiFile for cap_std::fs::File { get_filetype }` .file_name()
} else if file_type.is_symlink() { .into_string()
DirEntityType::SymbolicLink .map_err(|_| Error::Utf8(todo!()))?;
} else {
DirEntityType::Unknown
};
let name = entry.file_name().into_string().map_err(|_| {
Error::Utf8(todo!(
// XXX
"idk how to make utf8 error out of osstring conversion"
))
})?;
let namelen = name.as_bytes().len() as u64; let namelen = name.as_bytes().len() as u64;
// XXX need the metadata casing to be reusable here
let inode = todo!();
let entity = ReaddirEntity { let entity = ReaddirEntity {
next: ReaddirCursor::from(ix as u64 + 1), next: ReaddirCursor::from(ix as u64 + 1),
direnttype, filetype,
inode, inode,
namelen, namelen,
}; };

View File

@@ -6,7 +6,7 @@ use system_interface::fs::FileIoExt;
pub trait WasiFile: FileIoExt + SetTimes { pub trait WasiFile: FileIoExt + SetTimes {
fn datasync(&self) -> Result<(), Error>; fn datasync(&self) -> Result<(), Error>;
fn sync(&self) -> Result<(), Error>; fn sync(&self) -> Result<(), Error>;
fn get_filetype(&self) -> Result<Filetype, Error>; fn get_filetype(&self) -> Result<FileType, Error>;
fn get_fdflags(&self) -> Result<FdFlags, Error>; fn get_fdflags(&self) -> Result<FdFlags, Error>;
fn set_fdflags(&self, _flags: FdFlags) -> Result<(), Error>; fn set_fdflags(&self, _flags: FdFlags) -> Result<(), Error>;
fn get_oflags(&self) -> Result<OFlags, Error>; fn get_oflags(&self) -> Result<OFlags, Error>;
@@ -15,17 +15,41 @@ pub trait WasiFile: FileIoExt + SetTimes {
fn set_filestat_size(&self, _size: u64) -> Result<(), Error>; fn set_filestat_size(&self, _size: u64) -> Result<(), Error>;
} }
// XXX missing:
// Unknown
// Directory
// SymbolicLink
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum Filetype { pub enum FileType {
Directory,
BlockDevice, BlockDevice,
CharacterDevice, CharacterDevice,
RegularFile, RegularFile,
SocketDgram, SocketDgram,
SocketStream, SocketStream,
SymbolicLink,
Unknown,
}
impl From<&cap_std::fs::FileType> for FileType {
fn from(ft: &cap_std::fs::FileType) -> FileType {
use cap_fs_ext::FileTypeExt;
if ft.is_dir() {
FileType::Directory
} else if ft.is_symlink() {
FileType::SymbolicLink
} else if ft.is_socket() {
if ft.is_block_device() {
FileType::SocketDgram
} else {
FileType::SocketStream
}
} else if ft.is_block_device() {
FileType::BlockDevice
} else if ft.is_char_device() {
FileType::CharacterDevice
} else if ft.is_file() {
FileType::RegularFile
} else {
FileType::Unknown
}
}
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -89,7 +113,7 @@ impl std::ops::BitOr for OFlags {
pub struct Filestat { pub struct Filestat {
pub device_id: u64, pub device_id: u64,
pub inode: u64, pub inode: u64,
pub filetype: Filetype, pub filetype: FileType,
pub nlink: u64, pub nlink: u64,
pub size: u64, pub size: u64,
pub atim: Option<std::time::SystemTime>, pub atim: Option<std::time::SystemTime>,
@@ -197,7 +221,7 @@ impl std::ops::BitOr for FileCaps {
} }
pub struct FdStat { pub struct FdStat {
pub filetype: Filetype, pub filetype: FileType,
pub caps: FileCaps, pub caps: FileCaps,
pub flags: FdFlags, pub flags: FdFlags,
} }
@@ -211,16 +235,9 @@ impl WasiFile for cap_std::fs::File {
self.sync_all()?; self.sync_all()?;
Ok(()) Ok(())
} }
fn get_filetype(&self) -> Result<Filetype, Error> { fn get_filetype(&self) -> Result<FileType, Error> {
let meta = self.metadata()?; let meta = self.metadata()?;
// cap-std's Metadata/FileType only offers booleans indicating whether a file is a directory, Ok(FileType::from(&meta.file_type()))
// symlink, or regular file.
// Directories should be excluded by the type system.
if meta.is_file() {
Ok(Filetype::RegularFile)
} else {
todo!("get_filetype doesnt know how to handle case when not a file");
}
} }
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
// XXX get_fdflags is not implemented but lets lie rather than panic: // XXX get_fdflags is not implemented but lets lie rather than panic:
@@ -241,7 +258,7 @@ impl WasiFile for cap_std::fs::File {
Ok(Filestat { Ok(Filestat {
device_id: meta.dev(), device_id: meta.dev(),
inode: meta.ino(), inode: meta.ino(),
filetype: self.get_filetype()?, filetype: FileType::from(&meta.file_type()),
nlink: meta.nlink(), nlink: meta.nlink(),
size: meta.len(), size: meta.len(),
atim: meta.accessed().map(|t| Some(t.into_std())).unwrap_or(None), atim: meta.accessed().map(|t| Some(t.into_std())).unwrap_or(None),

View File

@@ -1,6 +1,6 @@
#![allow(unused_variables)] #![allow(unused_variables)]
use crate::dir::{DirCaps, DirEntry, DirStat, ReaddirCursor, TableDirExt}; use crate::dir::{DirCaps, DirEntry, DirStat, ReaddirCursor, TableDirExt};
use crate::file::{FdFlags, FdStat, FileCaps, FileEntry, Filestat, Filetype, OFlags}; use crate::file::{FdFlags, FdStat, FileCaps, FileEntry, FileType, Filestat, OFlags};
use crate::{Error, WasiCtx}; use crate::{Error, WasiCtx};
use fs_set_times::SystemTimeSpec; use fs_set_times::SystemTimeSpec;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
@@ -970,14 +970,17 @@ impl From<&types::Rights> for DirCaps {
} }
} }
impl From<&Filetype> for types::Filetype { impl From<&FileType> for types::Filetype {
fn from(ft: &Filetype) -> types::Filetype { fn from(ft: &FileType) -> types::Filetype {
match ft { match ft {
Filetype::BlockDevice => types::Filetype::BlockDevice, FileType::Directory => types::Filetype::Directory,
Filetype::CharacterDevice => types::Filetype::CharacterDevice, FileType::BlockDevice => types::Filetype::BlockDevice,
Filetype::RegularFile => types::Filetype::RegularFile, FileType::CharacterDevice => types::Filetype::CharacterDevice,
Filetype::SocketDgram => types::Filetype::SocketDgram, FileType::RegularFile => types::Filetype::RegularFile,
Filetype::SocketStream => types::Filetype::SocketStream, FileType::SocketDgram => types::Filetype::SocketDgram,
FileType::SocketStream => types::Filetype::SocketStream,
FileType::SymbolicLink => types::Filetype::SymbolicLink,
FileType::Unknown => types::Filetype::Unknown,
} }
} }
} }

View File

@@ -1,4 +1,4 @@
use crate::file::{FdFlags, Filestat, Filetype, OFlags, WasiFile}; use crate::file::{FdFlags, FileType, Filestat, OFlags, WasiFile};
use crate::Error; use crate::Error;
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
@@ -23,8 +23,8 @@ impl WasiFile for Stdin {
fn sync(&self) -> Result<(), Error> { fn sync(&self) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn get_filetype(&self) -> Result<Filetype, Error> { fn get_filetype(&self) -> Result<FileType, Error> {
Ok(Filetype::CharacterDevice) Ok(FileType::CharacterDevice)
} }
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
todo!() todo!()
@@ -66,8 +66,8 @@ impl WasiFile for Stdout {
fn sync(&self) -> Result<(), Error> { fn sync(&self) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn get_filetype(&self) -> Result<Filetype, Error> { fn get_filetype(&self) -> Result<FileType, Error> {
Ok(Filetype::CharacterDevice) Ok(FileType::CharacterDevice)
} }
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
todo!() todo!()
@@ -109,8 +109,8 @@ impl WasiFile for Stderr {
fn sync(&self) -> Result<(), Error> { fn sync(&self) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn get_filetype(&self) -> Result<Filetype, Error> { fn get_filetype(&self) -> Result<FileType, Error> {
Ok(Filetype::CharacterDevice) Ok(FileType::CharacterDevice)
} }
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
todo!() todo!()

View File

@@ -9,7 +9,7 @@
//! Some convenience constructors are included for common backing types like `Vec<u8>` and `String`, //! Some convenience constructors are included for common backing types like `Vec<u8>` and `String`,
//! but the virtual pipes can be instantiated with any `Read` or `Write` type. //! but the virtual pipes can be instantiated with any `Read` or `Write` type.
//! //!
use crate::file::{FdFlags, Filestat, Filetype, OFlags, WasiFile}; use crate::file::{FdFlags, FileType, Filestat, OFlags, WasiFile};
use crate::Error; use crate::Error;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
@@ -174,8 +174,8 @@ impl<R: Read> WasiFile for ReadPipe<R> {
fn sync(&self) -> Result<(), Error> { fn sync(&self) -> Result<(), Error> {
Ok(()) // trivial Ok(()) // trivial
} }
fn get_filetype(&self) -> Result<Filetype, Error> { fn get_filetype(&self) -> Result<FileType, Error> {
Ok(Filetype::CharacterDevice) // XXX wrong Ok(FileType::CharacterDevice) // XXX wrong
} }
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
Ok(FdFlags::empty()) Ok(FdFlags::empty())
@@ -340,8 +340,8 @@ impl<W: Write> WasiFile for WritePipe<W> {
fn sync(&self) -> Result<(), Error> { fn sync(&self) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn get_filetype(&self) -> Result<Filetype, Error> { fn get_filetype(&self) -> Result<FileType, Error> {
Ok(Filetype::CharacterDevice) // XXX Ok(FileType::CharacterDevice) // XXX
} }
fn get_fdflags(&self) -> Result<FdFlags, Error> { fn get_fdflags(&self) -> Result<FdFlags, Error> {
Ok(FdFlags::APPEND) Ok(FdFlags::APPEND)