Skip to content

Commit

Permalink
Merge pull request #650 from wasmerio/feature/wasi-path-rename
Browse files Browse the repository at this point in the history
implement wasi::path_rename
  • Loading branch information
syrusakbary authored Aug 9, 2019
2 parents 4dd9db4 + 61f1df0 commit f909f7e
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 40 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Blocks of changes will separated by version increments.

Special thanks to @YaronWittenstein @penberg for their contributions.

- [#650](https://github.com/wasmerio/wasmer/issues/650) Implement `wasi::path_rename`, improve WASI FS public api, and allow open files to exist even when the underlying file is deleted
- [#643](https://github.com/wasmerio/wasmer/issues/643) Implement `wasi::path_symlink` and improve WASI FS public api IO error reporting
- [#608](https://github.com/wasmerio/wasmer/issues/608) Implement wasi syscalls `fd_allocate`, `fd_sync`, `fd_pread`, `path_link`, `path_filestat_set_times`; update WASI fs API in a WIP way; reduce coupling of WASI code to host filesystem; make debug messages from WASI more readable; improve rights-checking when calling syscalls; implement reference counting on inodes; misc bug fixes and improvements
- [#616](https://github.com/wasmerio/wasmer/issues/616) Create the import object separately from instance instantiation in `runtime-c-api`
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ generate-spectests:
generate-emtests:
WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release

generate-wasitests:
generate-wasitests: wasitests-setup
WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \
&& echo "formatting" \
&& cargo fmt
Expand Down
1 change: 1 addition & 0 deletions lib/wasi-tests/tests/wasitests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod fseek;
mod hello;
mod mapdir;
mod path_link;
mod path_rename;
mod path_symlink;
mod quine;
mod readlink;
Expand Down
14 changes: 14 additions & 0 deletions lib/wasi-tests/tests/wasitests/path_rename.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#[test]
fn test_path_rename() {
assert_wasi_output!(
"../../wasitests/path_rename.wasm",
"path_rename",
vec![],
vec![(
"temp".to_string(),
::std::path::PathBuf::from("wasitests/test_fs/temp")
),],
vec![],
"../../wasitests/path_rename.out"
);
}
2 changes: 2 additions & 0 deletions lib/wasi-tests/wasitests/path_rename.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The original file does not still exist!
柴犬
56 changes: 56 additions & 0 deletions lib/wasi-tests/wasitests/path_rename.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Args:
// mapdir: temp:wasitests/test_fs/temp

use std::fs;
use std::io::{Read, Write};
use std::path::PathBuf;

fn main() {
#[cfg(not(target_os = "wasi"))]
let mut base = PathBuf::from("wasitests/test_fs");
#[cfg(target_os = "wasi")]
let mut base = PathBuf::from("/");

let file_to_create = base.join("temp/path_rename_file.txt");
let file_to_rename_to = base.join("temp/path_renamed_file.txt");

{
let mut f = std::fs::OpenOptions::new()
.create_new(true)
.write(true)
.open(&file_to_create)
.unwrap();

// text from https://ja.wikipedia.org/wiki/柴犬
let shiba_string = "「柴犬」という名前は中央高地で使われていたもので、文献上では、昭和初期の日本犬保存会の会誌「日本犬」で用いられている。一般的には、「柴」は小ぶりな雑木を指す。
由来には諸説があり、
柴藪を巧みにくぐり抜けて猟を助けることから
赤褐色の毛色が枯れ柴に似ている(柴赤)ことから
小さなものを表す古語の「柴」から
の3つの説が代表的。";
let shiba_bytes: Vec<u8> = shiba_string.bytes().collect();
f.write_all(&shiba_bytes[..]).unwrap();
}

std::fs::rename(&file_to_create, &file_to_rename_to).unwrap();
let mut file = fs::File::open(&file_to_rename_to).expect("Could not open file");
if file_to_create.exists() {
println!("The original file still exists!");
return;
} else {
println!("The original file does not still exist!");
}

let mut out_str = String::new();
file.read_to_string(&mut out_str).unwrap();
let mut test_str = String::new();
let mut out_chars = out_str.chars();
out_chars.next().unwrap();
test_str.push(out_chars.next().unwrap());
test_str.push(out_chars.next().unwrap());

println!("{}", test_str);
std::fs::remove_file(file_to_rename_to).unwrap();
}
Binary file added lib/wasi-tests/wasitests/path_rename.wasm
Binary file not shown.
6 changes: 6 additions & 0 deletions lib/wasi/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ macro_rules! wasi_try {
wasi_try!(opt.ok_or($e))
}};
}

macro_rules! get_input_str {
($memory:expr, $data:expr, $len:expr) => {{
wasi_try!($data.get_utf8_string($memory, $len), __WASI_EINVAL)
}};
}
19 changes: 16 additions & 3 deletions lib/wasi/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub enum Kind {
},
}

#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct Fd {
pub rights: __wasi_rights_t,
pub rights_inheriting: __wasi_rights_t,
Expand All @@ -126,6 +126,8 @@ pub struct WasiFs {
pub fd_map: HashMap<u32, Fd>,
pub next_fd: Cell<u32>,
inode_counter: Cell<u64>,
/// for fds still open after the file has been deleted
pub orphan_fds: HashMap<Inode, InodeVal>,

pub stdout: Box<dyn WasiFile>,
pub stderr: Box<dyn WasiFile>,
Expand All @@ -146,6 +148,7 @@ impl WasiFs {
fd_map: HashMap::new(),
next_fd: Cell::new(3),
inode_counter: Cell::new(1024),
orphan_fds: HashMap::new(),

stdin: Box::new(Stdin(io::stdin())),
stdout: Box::new(Stdout(io::stdout())),
Expand Down Expand Up @@ -683,6 +686,16 @@ impl WasiFs {
self.fd_map.get(&fd).ok_or(__WASI_EBADF)
}

/// gets either a normal inode or an orphaned inode
pub fn get_inodeval_mut(&mut self, fd: __wasi_fd_t) -> Result<&mut InodeVal, __wasi_errno_t> {
let inode = self.get_fd(fd)?.inode;
if let Some(iv) = self.inodes.get_mut(inode) {
Ok(iv)
} else {
self.orphan_fds.get_mut(&inode).ok_or(__WASI_EBADF)
}
}

pub fn filestat_fd(&self, fd: __wasi_fd_t) -> Result<__wasi_filestat_t, __wasi_errno_t> {
let fd = self.get_fd(fd)?;

Expand Down Expand Up @@ -818,8 +831,8 @@ impl WasiFs {
/// all refences to the given inode have been removed from the filesystem
///
/// returns true if the inode existed and was removed
pub unsafe fn remove_inode(&mut self, inode: Inode) -> bool {
self.inodes.remove(inode).is_some()
pub unsafe fn remove_inode(&mut self, inode: Inode) -> Option<InodeVal> {
self.inodes.remove(inode)
}

fn create_virtual_root(&mut self) -> Inode {
Expand Down
11 changes: 11 additions & 0 deletions lib/wasi/src/state/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ pub trait WasiFile: std::fmt::Debug + Write + Read + Seek {
fn sync_to_disk(&self) -> Result<(), WasiFsError> {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0. Please implement WasiFile::sync_to_disk for your type before then");
}

/// Moves the file to a new location
/// NOTE: the signature of this function will change before stabilization
// TODO: stablizie this in 0.7.0 or 0.8.0 by removing default impl
fn rename_file(&self, _new_name: &std::path::Path) -> Result<(), WasiFsError> {
panic!("Default implementation for compatibilty in the 0.6.X releases; this will be removed in 0.7.0 or 0.8.0. Please implement WasiFile::rename_file for your type before then");
}
}

pub trait WasiPath {}
Expand Down Expand Up @@ -271,6 +278,10 @@ impl WasiFile for HostFile {
fn sync_to_disk(&self) -> Result<(), WasiFsError> {
self.inner.sync_all().map_err(Into::into)
}

fn rename_file(&self, new_name: &std::path::Path) -> Result<(), WasiFsError> {
std::fs::rename(&self.host_path, new_name).map_err(Into::into)
}
}

impl From<io::Error> for WasiFsError {
Expand Down
Loading

0 comments on commit f909f7e

Please sign in to comment.