implement wasi::readlink

This commit is contained in:
Mark McCaskey 2019-07-12 15:58:28 -07:00
parent bd2a082a78
commit 5119f07ea3
3 changed files with 37 additions and 1 deletions

View File

@ -126,6 +126,15 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
[index as usize..slice_full_len];
Some(cell_ptrs)
}
pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
if self.offset as usize + str_len as usize > memory.size().bytes().0 {
return None;
}
let ptr = unsafe { memory.view::<u8>().as_ptr().add(self.offset as usize) as *const u8 };
let slice: &[u8] = unsafe { std::slice::from_raw_parts(ptr, str_len as usize) };
std::str::from_utf8(slice).ok()
}
}
unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {

View File

@ -75,4 +75,9 @@ impl<T: Copy + ValueType> WasmPtr<T, ptr::Array> {
) -> Result<&'a [Cell<T>], __wasi_errno_t> {
self.0.deref(memory, index, length).ok_or(__WASI_EFAULT)
}
#[inline(always)]
pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
self.0.get_utf8_string(memory, str_len)
}
}

View File

@ -1608,7 +1608,29 @@ pub fn path_readlink(
buf_used: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::path_readlink");
unimplemented!("wasi::path_readlink")
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let base_dir = wasi_try!(state.fs.fd_map.get(&dir_fd).ok_or(__WASI_EBADF));
let path_str = wasi_try!(path.get_utf8_string(memory, path_len).ok_or(__WASI_EINVAL));
let result = wasi_try!(std::fs::read_link(path_str).ok().ok_or(__WASI_EIO));
let result_path_as_str = result.to_string_lossy();
let bytes = result_path_as_str.bytes();
if bytes.len() < buf_len as usize {
return __WASI_EOVERFLOW;
}
let out = wasi_try!(buf.deref(memory, 0, buf_len));
let mut bytes_written = 0;
for b in bytes {
out[bytes_written].set(b);
bytes_written += 1;
}
let bytes_out = wasi_try!(buf_used.deref(memory));
bytes_out.set(bytes_written as u32);
__WASI_ESUCCESS
}
pub fn path_remove_directory(