diff --git a/lib/wasi/src/state.rs b/lib/wasi/src/state.rs index 9a57e97a3..97d0e276a 100644 --- a/lib/wasi/src/state.rs +++ b/lib/wasi/src/state.rs @@ -464,3 +464,64 @@ pub fn host_file_type_to_wasi_file_type(file_type: fs::FileType) -> __wasi_filet __WASI_FILETYPE_UNKNOWN } } + +pub fn get_stat_for_kind(kind: &Kind) -> Option<__wasi_filestat_t> { + match kind { + Kind::File { handle } => match handle { + WasiFile::HostFile(hf) => { + let md = hf.metadata().ok()?; + + Some(__wasi_filestat_t { + st_filetype: host_file_type_to_wasi_file_type(md.file_type()), + st_size: md.len(), + st_atim: md + .accessed() + .ok()? + .duration_since(SystemTime::UNIX_EPOCH) + .ok()? + .as_nanos() as u64, + st_mtim: md + .modified() + .ok()? + .duration_since(SystemTime::UNIX_EPOCH) + .ok()? + .as_nanos() as u64, + st_ctim: md + .created() + .ok()? + .duration_since(SystemTime::UNIX_EPOCH) + .ok()? + .as_nanos() as u64, + ..__wasi_filestat_t::default() + }) + } + }, + Kind::Dir { path, .. } => { + let md = path.metadata().ok()?; + Some(__wasi_filestat_t { + st_filetype: host_file_type_to_wasi_file_type(md.file_type()), + st_size: md.len(), + st_atim: md + .accessed() + .ok()? + .duration_since(SystemTime::UNIX_EPOCH) + .ok()? + .as_nanos() as u64, + st_mtim: md + .modified() + .ok()? + .duration_since(SystemTime::UNIX_EPOCH) + .ok()? + .as_nanos() as u64, + st_ctim: md + .created() + .ok()? + .duration_since(SystemTime::UNIX_EPOCH) + .ok()? + .as_nanos() as u64, + ..__wasi_filestat_t::default() + }) + } + _ => None, + } +} diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index f313b9664..6d0c2e148 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -9,7 +9,8 @@ use self::types::*; use crate::{ ptr::{Array, WasmPtr}, state::{ - host_file_type_to_wasi_file_type, Fd, InodeVal, Kind, WasiFile, WasiState, MAX_SYMLINKS, + get_stat_for_kind, host_file_type_to_wasi_file_type, Fd, InodeVal, Kind, WasiFile, + WasiState, MAX_SYMLINKS, }, ExitCode, }; @@ -1082,7 +1083,7 @@ pub fn path_create_directory( entries: Default::default(), }; let new_inode = state.fs.inodes.insert(InodeVal { - stat: __wasi_filestat_t::default(), + stat: wasi_try!(get_stat_for_kind(&kind).ok_or(__WASI_EIO)), is_preopened: false, name: path_vec[0].clone(), kind, @@ -1226,10 +1227,7 @@ pub fn path_filestat_get( } let final_path_metadata = wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_EIO)); - __wasi_filestat_t { - st_filetype: host_file_type_to_wasi_file_type(final_path_metadata.file_type()), - ..Default::default() - } + wasi_try!(get_stat_for_kind(&state.fs.inodes[inode].kind).ok_or(__WASI_EIO)) } } _ => { @@ -1533,7 +1531,7 @@ pub fn path_open( // record lazily loaded or newly created fd let new_inode = state.fs.inodes.insert(InodeVal { - stat: __wasi_filestat_t::default(), + stat: wasi_try!(get_stat_for_kind(&kind).ok_or(__WASI_EIO)), is_preopened: false, name: file_name.clone(), kind, diff --git a/lib/wasi/tests/wasitests/file_metadata.rs b/lib/wasi/tests/wasitests/file_metadata.rs index 70bb6de9b..a22dc5127 100644 --- a/lib/wasi/tests/wasitests/file_metadata.rs +++ b/lib/wasi/tests/wasitests/file_metadata.rs @@ -1,5 +1,4 @@ #[test] -#[ignore] fn test_file_metadata() { assert_wasi_output!( "../../wasitests/file_metadata.wasm", diff --git a/lib/wasi/wasitests/file_metadata b/lib/wasi/wasitests/file_metadata index cd3728704..2afc8727f 100755 Binary files a/lib/wasi/wasitests/file_metadata and b/lib/wasi/wasitests/file_metadata differ diff --git a/lib/wasi/wasitests/file_metadata.out b/lib/wasi/wasitests/file_metadata.out index d49e60f1d..6db377d51 100644 --- a/lib/wasi/wasitests/file_metadata.out +++ b/lib/wasi/wasitests/file_metadata.out @@ -1,2 +1,3 @@ is dir: false -file info: FileType(FileType { mode: 33188 }) 419 Ok(SystemTime { tv_sec: 1558132188, tv_nsec: 545288295 }) Ok(SystemTime { tv_sec: 1558132188, tv_nsec: 545243056 }) Ok(SystemTime { tv_sec: 1558132191, tv_nsec: 359031112 }) +filetype: false true false +file info: 491 diff --git a/lib/wasi/wasitests/file_metadata.rs b/lib/wasi/wasitests/file_metadata.rs index 7419a4f82..c64687226 100644 --- a/lib/wasi/wasitests/file_metadata.rs +++ b/lib/wasi/wasitests/file_metadata.rs @@ -6,12 +6,12 @@ fn main() { fs::File::open("wasitests/file_metadata.rs").expect("could not find src file"); let md = this_file.metadata().unwrap(); println!("is dir: {}", md.is_dir()); + let filetype = md.file_type(); println!( - "file info: {:?} {} {:?} {:?} {:?}", - md.file_type(), - md.len(), - md.modified(), - md.created(), - md.accessed() + "filetype: {} {} {}", + filetype.is_dir(), + filetype.is_file(), + filetype.is_symlink() ); + println!("file info: {} {} {}", md.len(), md.modified(), md.created()); } diff --git a/lib/wasi/wasitests/file_metadata.wasm b/lib/wasi/wasitests/file_metadata.wasm index 2e2f702f9..387e4ab03 100755 Binary files a/lib/wasi/wasitests/file_metadata.wasm and b/lib/wasi/wasitests/file_metadata.wasm differ diff --git a/lib/wasi/wasitests/ignores.txt b/lib/wasi/wasitests/ignores.txt index aa48474bf..061ac5e1e 100644 --- a/lib/wasi/wasitests/ignores.txt +++ b/lib/wasi/wasitests/ignores.txt @@ -1,2 +1 @@ -file_metadata create_dir