sketchy implementation of readdir
This commit is contained in:
@@ -20,6 +20,11 @@ pub trait WasiDir {
|
|||||||
path: &str,
|
path: &str,
|
||||||
create: bool,
|
create: bool,
|
||||||
) -> Result<Box<dyn WasiDir>, Error>;
|
) -> Result<Box<dyn WasiDir>, Error>;
|
||||||
|
|
||||||
|
fn readdir(
|
||||||
|
&self,
|
||||||
|
cursor: ReaddirCursor,
|
||||||
|
) -> Result<Box<dyn Iterator<Item = Result<(ReaddirEntity, String), Error>>>, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct DirEntry {
|
pub(crate) struct DirEntry {
|
||||||
@@ -84,3 +89,89 @@ impl TableDirExt for crate::table::Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum DirEntityType {
|
||||||
|
File(crate::file::Filetype),
|
||||||
|
Directory,
|
||||||
|
SymbolicLink,
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ReaddirEntity {
|
||||||
|
next: ReaddirCursor,
|
||||||
|
inode: u64,
|
||||||
|
namelen: u64,
|
||||||
|
direnttype: DirEntityType,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ReaddirCursor(u64);
|
||||||
|
impl From<u64> for ReaddirCursor {
|
||||||
|
fn from(c: u64) -> ReaddirCursor {
|
||||||
|
ReaddirCursor(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<ReaddirCursor> for u64 {
|
||||||
|
fn from(c: ReaddirCursor) -> u64 {
|
||||||
|
c.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WasiDir for cap_std::fs::Dir {
|
||||||
|
fn open_file(
|
||||||
|
&self,
|
||||||
|
symlink_follow: bool,
|
||||||
|
path: &str,
|
||||||
|
oflags: file::OFlags,
|
||||||
|
fdflags: file::FdFlags,
|
||||||
|
) -> Result<Box<dyn WasiFile>, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn open_dir(
|
||||||
|
&self,
|
||||||
|
symlink_follow: bool,
|
||||||
|
path: &str,
|
||||||
|
create: bool,
|
||||||
|
) -> Result<Box<dyn WasiDir>, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn readdir(
|
||||||
|
&self,
|
||||||
|
cursor: ReaddirCursor,
|
||||||
|
) -> Result<Box<dyn Iterator<Item = Result<(ReaddirEntity, String), Error>>>, Error> {
|
||||||
|
let rd = self
|
||||||
|
.read_dir(PathBuf::new())?
|
||||||
|
.enumerate()
|
||||||
|
.skip(u64::from(cursor) as usize);
|
||||||
|
Ok(Box::new(rd.map(|(ix, entry)| {
|
||||||
|
let entry = entry?;
|
||||||
|
let file_type = entry.file_type()?;
|
||||||
|
let direnttype = if file_type.is_dir() {
|
||||||
|
DirEntityType::Directory
|
||||||
|
} else if file_type.is_file() {
|
||||||
|
DirEntityType::File(crate::file::Filetype::RegularFile) // XXX unify this with conversion in `impl WasiFile for cap_std::fs::File { get_filetype }`
|
||||||
|
} else if file_type.is_symlink() {
|
||||||
|
DirEntityType::SymbolicLink
|
||||||
|
} 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;
|
||||||
|
// XXX need the metadata casing to be reusable here
|
||||||
|
let inode = todo!();
|
||||||
|
let entity = ReaddirEntity {
|
||||||
|
next: ReaddirCursor::from(ix as u64 + 1),
|
||||||
|
direnttype,
|
||||||
|
inode,
|
||||||
|
namelen,
|
||||||
|
};
|
||||||
|
Ok((entity, name))
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ 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 {
|
||||||
BlockDevice,
|
BlockDevice,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
use crate::dir::{DirCaps, DirEntry, TableDirExt};
|
use crate::dir::{DirCaps, DirEntry, ReaddirCursor, TableDirExt};
|
||||||
use crate::file::{FdFlags, FdStat, FileCaps, FileEntry, Filestat, Filetype, OFlags};
|
use crate::file::{FdFlags, FdStat, FileCaps, FileEntry, Filestat, Filetype, OFlags};
|
||||||
use crate::{Error, WasiCtx};
|
use crate::{Error, WasiCtx};
|
||||||
use fs_set_times::SystemTimeSpec;
|
use fs_set_times::SystemTimeSpec;
|
||||||
@@ -427,17 +427,6 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
Err(Error::Notsup)
|
Err(Error::Notsup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fd_readdir(
|
|
||||||
&self,
|
|
||||||
fd: types::Fd,
|
|
||||||
buf: &GuestPtr<u8>,
|
|
||||||
buf_len: types::Size,
|
|
||||||
cookie: types::Dircookie,
|
|
||||||
) -> Result<types::Size, Error> {
|
|
||||||
todo!("fd_readdir is very complicated")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fd_renumber(&self, from: types::Fd, to: types::Fd) -> Result<(), Error> {
|
fn fd_renumber(&self, from: types::Fd, to: types::Fd) -> Result<(), Error> {
|
||||||
let mut table = self.table();
|
let mut table = self.table();
|
||||||
let from = u32::from(from);
|
let from = u32::from(from);
|
||||||
@@ -499,6 +488,23 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
Ok(offset)
|
Ok(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fd_readdir(
|
||||||
|
&self,
|
||||||
|
dirfd: types::Fd,
|
||||||
|
buf: &GuestPtr<u8>,
|
||||||
|
buf_len: types::Size,
|
||||||
|
cookie: types::Dircookie,
|
||||||
|
) -> Result<types::Size, Error> {
|
||||||
|
let table = self.table();
|
||||||
|
let dir_entry: RefMut<DirEntry> = table.get(u32::from(dirfd))?;
|
||||||
|
let d = dir_entry.get_cap(DirCaps::READDIR)?;
|
||||||
|
for pair in d.readdir(ReaddirCursor::from(cookie))? {
|
||||||
|
let (entity, name) = pair?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
fn path_create_directory(
|
fn path_create_directory(
|
||||||
&self,
|
&self,
|
||||||
dirfd: types::Fd,
|
dirfd: types::Fd,
|
||||||
|
|||||||
Reference in New Issue
Block a user