Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
On Windows, ignore files for which full_metadata fails.
Browse files Browse the repository at this point in the history
On Windows, `metadata` computes only partial metadata results, which don't
include what WASI needs for the `inode` field in `readdir` results. cap-std
has a `full_metadata` function which is able to include this extra
information, however it has more strict access requirements, so it sometimes
fails even when plain `metadata` would succeed.

Make WASI's `readdir` silently skip over files that can't be accessed by
`full_metadata`. These files wouldn't be openable in any other way by
WASI programs, so the only benefit of listing them would be to
let applications know that they exist. This allows it to avoid failing
and avoid returning bogus results.

This is part of a fix for bytecodealliance/cap-std#169.
sunfishcode committed May 7, 2021
1 parent 002b074 commit 6ba5e16
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions crates/wasi-common/cap-std-sync/src/dir.rs
Original file line number Diff line number Diff line change
@@ -116,9 +116,9 @@ impl WasiDir for Dir {
},
]
.into_iter()
.chain(
.chain({
// Now process the `DirEntry`s:
self.0.entries()?.map(|entry| {
let entries = self.0.entries()?.map(|entry| {
let entry = entry?;
let meta = entry.full_metadata()?;
let inode = meta.ino();
@@ -128,8 +128,27 @@ impl WasiDir for Dir {
.into_string()
.map_err(|_| Error::illegal_byte_sequence().context("filename"))?;
Ok((filetype, inode, name))
}),
)
});

// On Windows, filter out files like `C:\DumpStack.log.tmp` which we
// can't get a full metadata for.
#[cfg(windows)]
let entries = entries.filter(|entry: &Result<_, wasi_common::Error>| {
use winapi::shared::winerror::{ERROR_ACCESS_DENIED, ERROR_SHARING_VIOLATION};
if let Err(err) = entry {
if let Some(err) = err.downcast_ref::<std::io::Error>() {
if err.raw_os_error() == Some(ERROR_SHARING_VIOLATION as i32)
|| err.raw_os_error() == Some(ERROR_ACCESS_DENIED as i32)
{
return false;
}
}
}
true
});

entries
})
// Enumeration of the iterator makes it possible to define the ReaddirCursor
.enumerate()
.map(|(ix, r)| match r {

0 comments on commit 6ba5e16

Please sign in to comment.