woo it passes six tests even though its awful
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3131,6 +3131,7 @@ version = "0.22.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cap-std",
|
"cap-std",
|
||||||
|
"tracing",
|
||||||
"wasi-common",
|
"wasi-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -16,3 +16,4 @@ publish = false
|
|||||||
wasi-common = { path = "../", version = "0.22.0" }
|
wasi-common = { path = "../", version = "0.22.0" }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cap-std = "0.12"
|
cap-std = "0.12"
|
||||||
|
tracing = "0.1.19"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use std::io::{Cursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
|
use tracing::trace;
|
||||||
use wasi_common::{
|
use wasi_common::{
|
||||||
clocks::WasiSystemClock,
|
clocks::WasiSystemClock,
|
||||||
dir::{ReaddirCursor, ReaddirEntity, WasiDir},
|
dir::{ReaddirCursor, ReaddirEntity, WasiDir},
|
||||||
@@ -283,7 +284,7 @@ impl WasiFile for File {
|
|||||||
pub struct Dir(Rc<RefCell<DirInode>>);
|
pub struct Dir(Rc<RefCell<DirInode>>);
|
||||||
|
|
||||||
impl Dir {
|
impl Dir {
|
||||||
fn at_path<F, A>(&self, path: &str, f: F) -> Result<A, Error>
|
fn at_path<F, A>(&self, path: &str, accept_trailing_slash: bool, f: F) -> Result<A, Error>
|
||||||
where
|
where
|
||||||
F: FnOnce(&Dir, &str) -> Result<A, Error>,
|
F: FnOnce(&Dir, &str) -> Result<A, Error>,
|
||||||
{
|
{
|
||||||
@@ -292,12 +293,16 @@ impl Dir {
|
|||||||
let dirname = &path[..slash_index];
|
let dirname = &path[..slash_index];
|
||||||
let rest = &path[slash_index + 1..];
|
let rest = &path[slash_index + 1..];
|
||||||
if rest == "" {
|
if rest == "" {
|
||||||
|
if accept_trailing_slash {
|
||||||
|
return f(self, path);
|
||||||
|
} else {
|
||||||
return Err(Error::invalid_argument()
|
return Err(Error::invalid_argument()
|
||||||
.context("empty filename, probably related to trailing slashes"));
|
.context("empty filename, probably related to trailing slashes"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if let Some(inode) = self.0.borrow().contents.get(dirname) {
|
if let Some(inode) = self.0.borrow().contents.get(dirname) {
|
||||||
match inode {
|
match inode {
|
||||||
Inode::Dir(d) => Dir(d.clone()).at_path(rest, f),
|
Inode::Dir(d) => Dir(d.clone()).at_path(rest, accept_trailing_slash, f),
|
||||||
Inode::File { .. } => Err(Error::not_found()),
|
Inode::File { .. } => Err(Error::not_found()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -308,6 +313,9 @@ impl Dir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn child_dir(&self, name: &str) -> Result<Rc<RefCell<DirInode>>, Error> {
|
fn child_dir(&self, name: &str) -> Result<Rc<RefCell<DirInode>>, Error> {
|
||||||
|
if name == "." {
|
||||||
|
return Ok(self.0.clone());
|
||||||
|
}
|
||||||
match self.0.borrow().contents.get(name) {
|
match self.0.borrow().contents.get(name) {
|
||||||
Some(Inode::Dir(d)) => Ok(d.clone()),
|
Some(Inode::Dir(d)) => Ok(d.clone()),
|
||||||
_ => Err(Error::not_found()),
|
_ => Err(Error::not_found()),
|
||||||
@@ -336,15 +344,13 @@ impl WasiDir for Dir {
|
|||||||
) -> Result<Box<dyn WasiFile>, Error> {
|
) -> Result<Box<dyn WasiFile>, Error> {
|
||||||
let mode = if read && write {
|
let mode = if read && write {
|
||||||
FileMode::ReadWrite
|
FileMode::ReadWrite
|
||||||
} else if read {
|
|
||||||
FileMode::ReadOnly
|
|
||||||
} else if write {
|
} else if write {
|
||||||
FileMode::WriteOnly
|
FileMode::WriteOnly
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::invalid_argument().context("must be read or write"));
|
FileMode::ReadOnly
|
||||||
};
|
};
|
||||||
// XXX TERRIBLE CODE DUPLICATION HERE
|
// XXX TERRIBLE CODE DUPLICATION HERE
|
||||||
self.at_path(path, |dir, filename| {
|
self.at_path(path, false, |dir, filename| {
|
||||||
if oflags.contains(OFlags::CREATE | OFlags::EXCLUSIVE) {
|
if oflags.contains(OFlags::CREATE | OFlags::EXCLUSIVE) {
|
||||||
match dir.child_file(filename) {
|
match dir.child_file(filename) {
|
||||||
Err(_notfound) => {
|
Err(_notfound) => {
|
||||||
@@ -421,14 +427,14 @@ impl WasiDir for Dir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_dir(&self, _symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error> {
|
fn open_dir(&self, _symlink_follow: bool, path: &str) -> Result<Box<dyn WasiDir>, Error> {
|
||||||
self.at_path(path, |dir, dirname| {
|
self.at_path(path, true, |dir, dirname| {
|
||||||
let d = dir.child_dir(dirname)?;
|
let d = dir.child_dir(dirname)?;
|
||||||
Ok(Box::new(Dir(d)) as Box<dyn WasiDir>)
|
Ok(Box::new(Dir(d)) as Box<dyn WasiDir>)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_dir(&self, path: &str) -> Result<(), Error> {
|
fn create_dir(&self, path: &str) -> Result<(), Error> {
|
||||||
self.at_path(path, |dir, dirname| {
|
self.at_path(path, true, |dir, dirname| {
|
||||||
let d = dir.0.borrow();
|
let d = dir.0.borrow();
|
||||||
let fs = d.fs.clone();
|
let fs = d.fs.clone();
|
||||||
let serial = d.fs().fresh_serial();
|
let serial = d.fs().fresh_serial();
|
||||||
|
|||||||
Reference in New Issue
Block a user