wasip1 path_remove_directory fails with paths with trailing slashes
Test Case
For the wasi-testsuite test remove_directory_trailing_slashes, we mkdir dir.cleanup, then try to rrmdir dir.cleanup/ (note trailing slash). This fails because it uses the "get the parent then remove the leaf" strategy, and the parent of dir.cleanup/ is dir.cleanup, and the leaf is ..
A trace: https://github.com/WebAssembly/wasi-testsuite/issues/101#issuecomment-3214123363
I would expect that the rmdir removes trailing slashes.
Filing this bug here as I am not sure if this is a failure of cap-std or if callers are required to remove trailing slashes already.
Versions and Environment
Wasmtime version or commit: 1a88c70a6ec088ee213658488549306f8951405d (august 19)
Given that cap-std needs to sometimes normalize paths, consider using some wrapper around std::path::Path for normalized paths. Otherwise it's too easy to pass an absolute path to some routine that needs a normalized relative path.
Same failure in wasip3:
use std::process;
extern crate wit_bindgen;
wit_bindgen::generate!({
inline: r"
package test:test;
world test {
include wasi:filesystem/[email protected];
include wasi:cli/[email protected];
}
",
additional_derives: [PartialEq, Eq, Hash, Clone],
// Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
features:["clocks-timezone"],
async: [
"wasi:cli/[email protected]#run",
],
generate_all
});
use wasi::filesystem::types::{PathFlags,ErrorCode};
async fn test_filesystem() {
match &wasi::filesystem::preopens::get_directories()[..] {
[(dirfd, _)] => {
dirfd.create_directory_at("qqq/".to_string())
.await.expect("mkdir qqq/");
dirfd.remove_directory_at("qqq/".to_string())
.await.expect("rmdir qqq/");
},
[..] => {
eprintln!("usage: run with one open dir");
process::exit(1)
}
}
}
struct Component;
export!(Component);
impl exports::wasi::cli::run::Guest for Component {
async fn run() -> Result<(), ()> {
test_filesystem().await;
Ok(())
}
}
fn main() {
unreachable!("main is a stub");
}
The mkdir qqq/ straces as:
mkdirat(3, "qqq", 0777) = 0
Whereas the rmdir qqq/ straces as:
openat2(3, "qqq/", {flags=O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY, resolve=RESOLVE_NO_MAGICLINKS|RESOLVE_BENEATH}, 24) = 11
unlinkat(11, ".", AT_REMOVEDIR) = -1 EINVAL (Invalid argument)
@sunfishcode are you still interested in investigating this?
Gentle ping here, this is the only wasip1 test in wasi-testsuite that wasmtime fails.