diff --git a/.appveyor.yml b/.appveyor.yml index f411b1fd753..00ccff954e6 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -18,7 +18,7 @@ environment: cache: - 'C:\Users\appveyor\.cargo' - target - - 'wapm-cli\target' + - wapm-cli-target install: # # Install LLVM @@ -53,7 +53,17 @@ build_script: # Now we build wapm - git submodule init - git submodule update + # Cache wapm cli target in dir above to prevent breaking git submodule on windows + - if not exist wapm-cli-target mkdir wapm-cli-target + - move wapm-cli-target wapm-cli + - cd wapm-cli + - rename wapm-cli-target target + - cd .. - cargo build --release --manifest-path wapm-cli/Cargo.toml --features telemetry + - cd wapm-cli + - rename target wapm-cli-target + - cd .. + - move wapm-cli\wapm-cli-target wapm-cli-target test_script: - cargo test --manifest-path lib/spectests/Cargo.toml --features clif diff --git a/CHANGELOG.md b/CHANGELOG.md index 23c4ffcc8e0..1b4051de1a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Blocks of changes will separated by version increments. ## 0.4.2 - 2019-05-16 +- [#457](https://github.com/wasmerio/wasmer/pull/457) Implement file metadata for WASI, fix bugs in WASI clock code for Unix platforms - [#416](https://github.com/wasmerio/wasmer/pull/416) Remote code loading framework - [#449](https://github.com/wasmerio/wasmer/pull/449) Fix bugs: opening host files in filestat and opening with write permissions unconditionally in path_open - [#442](https://github.com/wasmerio/wasmer/pull/442) Misc. WASI FS fixes and implement readdir diff --git a/lib/wasi/src/state.rs b/lib/wasi/src/state.rs index 9a57e97a33f..97d0e276a22 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 f313b966479..429ec1da80e 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, }; @@ -187,7 +188,10 @@ pub fn clock_time_get( precision: __wasi_timestamp_t, time: WasmPtr<__wasi_timestamp_t>, ) -> __wasi_errno_t { - debug!("wasi::clock_time_get"); + debug!( + "wasi::clock_time_get clock_id: {}, precision: {}", + clock_id, precision + ); let memory = ctx.memory(0); let out_addr = wasi_try!(time.deref(memory)); @@ -1082,7 +1086,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 +1230,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 +1534,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/src/syscalls/types.rs b/lib/wasi/src/syscalls/types.rs index d484db08b55..7971fb50332 100644 --- a/lib/wasi/src/syscalls/types.rs +++ b/lib/wasi/src/syscalls/types.rs @@ -24,9 +24,9 @@ pub struct __wasi_ciovec_t { unsafe impl ValueType for __wasi_ciovec_t {} pub type __wasi_clockid_t = u32; -pub const __WASI_CLOCK_MONOTONIC: u32 = 0; -pub const __WASI_CLOCK_PROCESS_CPUTIME_ID: u32 = 1; -pub const __WASI_CLOCK_REALTIME: u32 = 2; +pub const __WASI_CLOCK_REALTIME: u32 = 0; +pub const __WASI_CLOCK_MONOTONIC: u32 = 1; +pub const __WASI_CLOCK_PROCESS_CPUTIME_ID: u32 = 2; pub const __WASI_CLOCK_THREAD_CPUTIME_ID: u32 = 3; pub type __wasi_device_t = u64; diff --git a/lib/wasi/src/syscalls/unix/mod.rs b/lib/wasi/src/syscalls/unix/mod.rs index 4c9cfada321..43a79319fb5 100644 --- a/lib/wasi/src/syscalls/unix/mod.rs +++ b/lib/wasi/src/syscalls/unix/mod.rs @@ -23,7 +23,8 @@ pub fn platform_clock_res_get( (clock_getres(unix_clock_id, &mut timespec_out), timespec_out) }; - resolution.set(timespec_out.tv_nsec as __wasi_timestamp_t); + let t_out = (timespec_out.tv_sec * 1_000_000_000).wrapping_add(timespec_out.tv_nsec); + resolution.set(t_out as __wasi_timestamp_t); // TODO: map output of clock_getres to __wasi_errno_t __WASI_ESUCCESS @@ -50,9 +51,8 @@ pub fn platform_clock_time_get( ) }; - // TODO: adjust output by precision... - - time.set(timespec_out.tv_nsec as __wasi_timestamp_t); + let t_out = (timespec_out.tv_sec * 1_000_000_000).wrapping_add(timespec_out.tv_nsec); + time.set(t_out as __wasi_timestamp_t); // TODO: map output of clock_gettime to __wasi_errno_t __WASI_ESUCCESS diff --git a/lib/wasi/tests/wasitests/file_metadata.rs b/lib/wasi/tests/wasitests/file_metadata.rs index 70bb6de9bc1..a22dc51275e 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 cd3728704a2..2afc8727f24 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 d49e60f1d80..6db377d5161 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 7419a4f8297..c6468722661 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 2e2f702f994..387e4ab03e2 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 aa48474bfa7..061ac5e1e6d 100644 --- a/lib/wasi/wasitests/ignores.txt +++ b/lib/wasi/wasitests/ignores.txt @@ -1,2 +1 @@ -file_metadata create_dir