diff --git a/lib/wasi/src/fs/mod.rs b/lib/wasi/src/fs/mod.rs index f2d4fa93d85..db2637e2947 100644 --- a/lib/wasi/src/fs/mod.rs +++ b/lib/wasi/src/fs/mod.rs @@ -73,7 +73,7 @@ pub const MAX_SYMLINKS: u32 = 128; pub struct Inode(u64); impl Inode { - fn as_u64(&self) -> u64 { + pub fn as_u64(&self) -> u64 { self.0 } } diff --git a/lib/wasi/src/syscalls/wasi/path_filestat_get.rs b/lib/wasi/src/syscalls/wasi/path_filestat_get.rs index b277aee1612..ed77433c6f8 100644 --- a/lib/wasi/src/syscalls/wasi/path_filestat_get.rs +++ b/lib/wasi/src/syscalls/wasi/path_filestat_get.rs @@ -82,10 +82,13 @@ pub(crate) fn path_filestat_get_internal( path_string, flags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0, )?; - if file_inode.is_preopened { - Ok(*file_inode.stat.read().unwrap().deref()) + let st_ino = file_inode.ino().as_u64(); + let mut stat = if file_inode.is_preopened { + *file_inode.stat.read().unwrap().deref() } else { let guard = file_inode.read(); - state.fs.get_stat_for_kind(guard.deref()) - } + state.fs.get_stat_for_kind(guard.deref())? + }; + stat.st_ino = st_ino; + Ok(stat) } diff --git a/tests/wasi-wast/wasi/snapshot1/inode.wasm b/tests/wasi-wast/wasi/snapshot1/inode.wasm new file mode 100755 index 00000000000..68122603cab Binary files /dev/null and b/tests/wasi-wast/wasi/snapshot1/inode.wasm differ diff --git a/tests/wasi-wast/wasi/snapshot1/inode.wast b/tests/wasi-wast/wasi/snapshot1/inode.wast new file mode 100644 index 00000000000..c7eec7c7fee --- /dev/null +++ b/tests/wasi-wast/wasi/snapshot1/inode.wast @@ -0,0 +1,7 @@ +;; This file was generated by https://github.com/wasmerio/wasi-tests + +(wasi_test "inode.wasm" + (preopens "test_fs") + (assert_return (i64.const 0)) + (assert_stdout "all done\n") +) diff --git a/tests/wasi-wast/wasi/tests/inode.rs b/tests/wasi-wast/wasi/tests/inode.rs new file mode 100644 index 00000000000..1c2e00ac69e --- /dev/null +++ b/tests/wasi-wast/wasi/tests/inode.rs @@ -0,0 +1,31 @@ +// WASI: +// dir: test_fs + +use std::fs; +use std::io; +#[cfg(target = "wasi")] +use std::os::wasi::fs::MetadataExt; + +// `test_fs` will be implicit. +// this need experimentat MetadataExt +// this program does nothing in native +// it only tests things in wasi +fn main() { + #[cfg(target = "wasi")] + { + let meta1 = fs::metadata("test_fs/hamlet/act1/scene1.txt").expect("could not find src file"); + let meta2 = fs::metadata("test_fs/hamlet/act1/scene2.txt").expect("could not find src file"); + if meta1.dev() == meta2.dev() && meta1.ino() == meta2.ino() { + println!("Warning, different files from same folder have same dev/inod"); + } + let meta3 = fs::metadata("test_fs/hamlet/act2/scene1.txt").expect("could not find src file"); + if meta1.dev() == meta3.dev() && meta1.ino() == meta3.ino() { + println!("Warning, different files from different folder with same name have same dev/inod"); + } + let meta4 = fs::metadata("test_fs/hamlet/act1/../act1/scene1.txt").expect("could not find src file"); + if meta1.dev() != meta4.dev() || meta1.ino() != meta4.ino() { + println!("Warning, same files have different dev/inod"); + } + } + println!("all done"); +}