From 2de5a5da2ba00a4252be96d45a67662122f146ab Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 2 Apr 2019 15:29:32 -0700 Subject: [PATCH] implement datasync --- lib/wasi/src/state.rs | 26 ++++++++++++++++++++++++++ lib/wasi/src/syscalls/mod.rs | 8 +++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/wasi/src/state.rs b/lib/wasi/src/state.rs index 556df8319..80ba38bd8 100644 --- a/lib/wasi/src/state.rs +++ b/lib/wasi/src/state.rs @@ -7,6 +7,7 @@ use generational_arena::{Arena, Index as Inode}; use hashbrown::hash_map::{Entry, HashMap}; use std::{ cell::{Cell, RefCell}, + io::{self, Write}, ops::{Index, IndexMut}, path::PathBuf, rc::Rc, @@ -212,6 +213,31 @@ impl WasiFs { Err(__WASI_EBADF) } } + + pub fn flush(&mut self, fd: __wasi_fd_t) -> Result<(), __wasi_errno_t> { + match fd { + 0 => (), + 1 => io::stdout().flush().map_err(|_| __WASI_EIO)?, + 2 => io::stderr().flush().map_err(|_| __WASI_EIO)?, + _ => { + let fd = self.fd_map.get(&fd).ok_or(__WASI_EBADF)?; + if fd.rights & __WASI_RIGHT_FD_DATASYNC == 0 { + return Err(__WASI_EACCES); + } + + let inode = &mut self.inodes[fd.inode]; + + match &mut inode.kind { + Kind::File { handle } => handle.flush().map_err(|_| __WASI_EIO)?, + // TODO: verify this behavior + Kind::Dir { .. } => return Err(__WASI_EISDIR), + Kind::Symlink { .. } => unimplemented!(), + Kind::Buffer { .. } => (), + } + } + } + Ok(()) + } } pub struct WasiState<'a> { diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 7db140453..f1845482e 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -256,7 +256,13 @@ pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { /// The file descriptor to sync pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { debug!("wasi::fd_datasync"); - unimplemented!() + let state = get_wasi_state(ctx); + + if let Err(e) = state.fs.flush(fd) { + e + } else { + __WASI_ESUCCESS + } } /// ### `fd_fdstat_get()`