mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-01 23:41:03 +00:00
implement fd_write for files
This commit is contained in:
parent
242f9f679d
commit
6278ced7fc
@ -17,10 +17,10 @@ use zbox::{init_env as zbox_init_env, File, FileType, OpenOptions, Repo, RepoOpe
|
|||||||
pub const MAX_SYMLINKS: usize = 100;
|
pub const MAX_SYMLINKS: usize = 100;
|
||||||
|
|
||||||
pub struct InodeVal {
|
pub struct InodeVal {
|
||||||
stat: __wasi_filestat_t,
|
pub stat: __wasi_filestat_t,
|
||||||
is_preopened: bool,
|
pub is_preopened: bool,
|
||||||
name: String,
|
pub name: String,
|
||||||
kind: Kind,
|
pub kind: Kind,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Kind {
|
pub enum Kind {
|
||||||
@ -41,19 +41,19 @@ pub enum Kind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Fd {
|
pub struct Fd {
|
||||||
rights: __wasi_rights_t,
|
pub rights: __wasi_rights_t,
|
||||||
flags: __wasi_fdflags_t,
|
pub flags: __wasi_fdflags_t,
|
||||||
offset: u64,
|
pub offset: u64,
|
||||||
inode: Inode,
|
pub inode: Inode,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WasiFs {
|
pub struct WasiFs {
|
||||||
repo: Repo,
|
pub repo: Repo,
|
||||||
name_map: HashMap<String, Inode>,
|
pub name_map: HashMap<String, Inode>,
|
||||||
inodes: Arena<InodeVal>,
|
pub inodes: Arena<InodeVal>,
|
||||||
fd_map: HashMap<u32, Fd>,
|
pub fd_map: HashMap<u32, Fd>,
|
||||||
next_fd: Cell<u32>,
|
pub next_fd: Cell<u32>,
|
||||||
inode_counter: Cell<u64>,
|
pub inode_counter: Cell<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WasiFs {
|
impl WasiFs {
|
||||||
|
@ -8,9 +8,10 @@ pub mod windows;
|
|||||||
use self::types::*;
|
use self::types::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
ptr::{Array, WasmPtr},
|
ptr::{Array, WasmPtr},
|
||||||
state::WasiState,
|
state::{Kind, WasiState},
|
||||||
};
|
};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
use std::cell::Cell;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use wasmer_runtime_core::{debug, memory::Memory, vm::Ctx};
|
use wasmer_runtime_core::{debug, memory::Memory, vm::Ctx};
|
||||||
|
|
||||||
@ -619,46 +620,65 @@ pub fn fd_write(
|
|||||||
debug!("wasi::fd_write: fd={}", fd);
|
debug!("wasi::fd_write: fd={}", fd);
|
||||||
let memory = ctx.memory(0);
|
let memory = ctx.memory(0);
|
||||||
// TODO: check __WASI_RIGHT_FD_WRITE
|
// TODO: check __WASI_RIGHT_FD_WRITE
|
||||||
// return __WASI_EISDIR if dir (probably)
|
|
||||||
let iovs_arr_cell = wasi_try!(iovs.deref(memory, 0, iovs_len));
|
let iovs_arr_cell = wasi_try!(iovs.deref(memory, 0, iovs_len));
|
||||||
let nwritten_cell = wasi_try!(nwritten.deref(memory));
|
let nwritten_cell = wasi_try!(nwritten.deref(memory));
|
||||||
let mut bytes_written = 0;
|
|
||||||
|
|
||||||
match fd {
|
fn write_bytes<T: Write>(
|
||||||
0 => unimplemented!(),
|
mut write_loc: T,
|
||||||
|
memory: &Memory,
|
||||||
|
iovs_arr_cell: &[Cell<__wasi_ciovec_t>],
|
||||||
|
) -> Result<u32, __wasi_errno_t> {
|
||||||
|
let mut bytes_written = 0;
|
||||||
|
for iov in iovs_arr_cell {
|
||||||
|
let iov_inner = iov.get();
|
||||||
|
let bytes = iov_inner.buf.deref(memory, 0, iov_inner.buf_len)?;
|
||||||
|
write_loc
|
||||||
|
.write(&bytes.iter().map(|b_cell| b_cell.get()).collect::<Vec<u8>>())
|
||||||
|
.map_err(|_| __WASI_EIO)?;
|
||||||
|
|
||||||
|
// TODO: handle failure more accurately
|
||||||
|
bytes_written += iov_inner.buf_len;
|
||||||
|
}
|
||||||
|
Ok(bytes_written)
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes_written = match fd {
|
||||||
|
0 => return __WASI_EINVAL,
|
||||||
1 => {
|
1 => {
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
let mut handle = stdout.lock();
|
let mut handle = stdout.lock();
|
||||||
|
|
||||||
for iov in iovs_arr_cell {
|
wasi_try!(write_bytes(handle, memory, iovs_arr_cell))
|
||||||
let iov_inner = iov.get();
|
|
||||||
let bytes = wasi_try!(iov_inner.buf.deref(memory, 0, iov_inner.buf_len));
|
|
||||||
wasi_try!(handle
|
|
||||||
.write(&bytes.iter().map(|b_cell| b_cell.get()).collect::<Vec<u8>>())
|
|
||||||
.map_err(|_| __WASI_EIO));
|
|
||||||
|
|
||||||
// TODO: handle failure more accurately
|
|
||||||
bytes_written += iov_inner.buf_len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
2 => {
|
2 => {
|
||||||
let stderr = io::stderr();
|
let stderr = io::stderr();
|
||||||
let mut handle = stderr.lock();
|
let mut handle = stderr.lock();
|
||||||
|
|
||||||
// TODO: abstract this
|
wasi_try!(write_bytes(handle, memory, iovs_arr_cell))
|
||||||
for iov in iovs_arr_cell {
|
}
|
||||||
let iov_inner = iov.get();
|
_ => {
|
||||||
let bytes = wasi_try!(iov_inner.buf.deref(memory, 0, iov_inner.buf_len));
|
let state = get_wasi_state(ctx);
|
||||||
wasi_try!(handle
|
let fd_entry = wasi_try!(state.fs.fd_map.get(&fd).ok_or(__WASI_EBADF));
|
||||||
.write(&bytes.iter().map(|b_cell| b_cell.get()).collect::<Vec<u8>>())
|
|
||||||
.map_err(|_| __WASI_EIO));
|
|
||||||
|
|
||||||
// TODO: handle failure more accurately
|
if fd_entry.rights & __WASI_RIGHT_FD_WRITE == 0 {
|
||||||
bytes_written += iov_inner.buf_len;
|
// TODO: figure out the error to return when lacking rights
|
||||||
|
return __WASI_EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
let inode = &mut state.fs.inodes[fd_entry.inode];
|
||||||
|
|
||||||
|
match &mut inode.kind {
|
||||||
|
Kind::File { handle } => wasi_try!(write_bytes(handle, memory, iovs_arr_cell)),
|
||||||
|
Kind::Dir { .. } => {
|
||||||
|
// TODO: verify
|
||||||
|
return __WASI_EISDIR;
|
||||||
|
}
|
||||||
|
Kind::Symlink { .. } => unimplemented!(),
|
||||||
|
Kind::Buffer { buffer } => wasi_try!(write_bytes(buffer, memory, iovs_arr_cell)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => unimplemented!(),
|
};
|
||||||
}
|
|
||||||
|
|
||||||
nwritten_cell.set(bytes_written);
|
nwritten_cell.set(bytes_written);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user