Rollup merge of #63676 - newpavlov:wasi, r=alexcrichton

Use wasi crate for Core API

Blocked by: CraneStation/rust-wasi#5

Blocks: rust-lang/libc#1461

cc @sunfishcode @alexcrichton
This commit is contained in:
Mazdak Farrokhzad 2019-09-06 09:36:36 +02:00 committed by GitHub
commit 5b995397db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 339 additions and 433 deletions

View File

@ -3870,6 +3870,7 @@ dependencies = [
"rustc_msan",
"rustc_tsan",
"unwind",
"wasi",
]
[[package]]
@ -4686,6 +4687,17 @@ dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
[[package]]
name = "winapi"
version = "0.2.8"

View File

@ -56,6 +56,9 @@ dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] }
[target.x86_64-fortanix-unknown-sgx.dependencies]
fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
[target.wasm32-wasi.dependencies]
wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] }
[build-dependencies]
cc = "1.0"

View File

@ -1,11 +1,10 @@
use crate::ffi::CStr;
use crate::io;
use crate::sys::cvt_wasi;
use crate::ffi::OsString;
use crate::marker::PhantomData;
use crate::os::wasi::ffi::OsStringExt;
use crate::vec;
use ::wasi::wasi_unstable as wasi;
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
}
@ -19,31 +18,17 @@ pub struct Args {
/// Returns the command line arguments
pub fn args() -> Args {
maybe_args().unwrap_or_else(|_| {
Args {
iter: Vec::new().into_iter(),
_dont_send_or_sync_me: PhantomData
}
})
}
fn maybe_args() -> io::Result<Args> {
unsafe {
let (mut argc, mut argv_buf_size) = (0, 0);
cvt_wasi(libc::__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?;
let mut argc = vec![core::ptr::null_mut::<libc::c_char>(); argc];
let mut argv_buf = vec![0; argv_buf_size];
cvt_wasi(libc::__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?;
let args = argc.into_iter()
.map(|ptr| CStr::from_ptr(ptr).to_bytes().to_vec())
.map(|bytes| OsString::from_vec(bytes))
.collect::<Vec<_>>();
Ok(Args {
iter: args.into_iter(),
_dont_send_or_sync_me: PhantomData,
})
let buf = wasi::args_sizes_get().and_then(|args_sizes| {
let mut buf = Vec::with_capacity(args_sizes.get_count());
wasi::args_get(args_sizes, |arg| {
let arg = OsString::from_vec(arg.to_vec());
buf.push(arg);
})?;
Ok(buf)
}).unwrap_or(vec![]);
Args {
iter: buf.into_iter(),
_dont_send_or_sync_me: PhantomData
}
}

View File

@ -8,6 +8,8 @@ use crate::os::wasi::ffi::OsStrExt;
use crate::path::{Path, PathBuf};
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
use ::wasi::wasi_unstable as wasi;
/// WASI-specific extensions to [`File`].
///
/// [`File`]: ../../../../std/fs/struct.File.html
@ -336,16 +338,16 @@ pub trait FileTypeExt {
impl FileTypeExt for fs::FileType {
fn is_block_device(&self) -> bool {
self.as_inner().bits() == libc::__WASI_FILETYPE_BLOCK_DEVICE
self.as_inner().bits() == wasi::FILETYPE_BLOCK_DEVICE
}
fn is_character_device(&self) -> bool {
self.as_inner().bits() == libc::__WASI_FILETYPE_CHARACTER_DEVICE
self.as_inner().bits() == wasi::FILETYPE_CHARACTER_DEVICE
}
fn is_socket_dgram(&self) -> bool {
self.as_inner().bits() == libc::__WASI_FILETYPE_SOCKET_DGRAM
self.as_inner().bits() == wasi::FILETYPE_SOCKET_DGRAM
}
fn is_socket_stream(&self) -> bool {
self.as_inner().bits() == libc::__WASI_FILETYPE_SOCKET_STREAM
self.as_inner().bits() == wasi::FILETYPE_SOCKET_STREAM
}
}

View File

@ -8,6 +8,8 @@ use crate::sys;
use crate::net;
use crate::sys_common::{AsInner, FromInner, IntoInner};
use ::wasi::wasi_unstable as wasi;
/// Raw file descriptors.
pub type RawFd = u32;
@ -125,18 +127,18 @@ impl IntoRawFd for fs::File {
impl AsRawFd for io::Stdin {
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO as u32
wasi::STDIN_FD
}
}
impl AsRawFd for io::Stdout {
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO as u32
wasi::STDOUT_FD
}
}
impl AsRawFd for io::Stderr {
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO as u32
wasi::STDERR_FD
}
}

View File

@ -3,348 +3,248 @@
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
use crate::mem;
use crate::net::Shutdown;
use crate::sys::cvt_wasi;
use libc::{self, c_char, c_void};
use super::err2io;
use ::wasi::wasi_unstable as wasi;
#[derive(Debug)]
pub struct WasiFd {
fd: libc::__wasi_fd_t,
fd: wasi::Fd,
}
// FIXME: these should probably all be fancier structs, builders, enums, etc
pub type LookupFlags = u32;
pub type FdFlags = u16;
pub type Advice = u8;
pub type Rights = u64;
pub type Oflags = u16;
pub type DirCookie = u64;
pub type Timestamp = u64;
pub type FstFlags = u16;
pub type RiFlags = u16;
pub type RoFlags = u16;
pub type SiFlags = u16;
fn iovec(a: &mut [IoSliceMut<'_>]) -> (*const libc::__wasi_iovec_t, usize) {
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::IoVec] {
assert_eq!(
mem::size_of::<IoSliceMut<'_>>(),
mem::size_of::<libc::__wasi_iovec_t>()
mem::size_of::<wasi::IoVec>()
);
assert_eq!(
mem::align_of::<IoSliceMut<'_>>(),
mem::align_of::<libc::__wasi_iovec_t>()
mem::align_of::<wasi::IoVec>()
);
(a.as_ptr() as *const libc::__wasi_iovec_t, a.len())
/// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
unsafe { mem::transmute(a) }
}
fn ciovec(a: &[IoSlice<'_>]) -> (*const libc::__wasi_ciovec_t, usize) {
fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::CIoVec] {
assert_eq!(
mem::size_of::<IoSlice<'_>>(),
mem::size_of::<libc::__wasi_ciovec_t>()
mem::size_of::<wasi::CIoVec>()
);
assert_eq!(
mem::align_of::<IoSlice<'_>>(),
mem::align_of::<libc::__wasi_ciovec_t>()
mem::align_of::<wasi::CIoVec>()
);
(a.as_ptr() as *const libc::__wasi_ciovec_t, a.len())
/// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
unsafe { mem::transmute(a) }
}
impl WasiFd {
pub unsafe fn from_raw(fd: libc::__wasi_fd_t) -> WasiFd {
pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd {
WasiFd { fd }
}
pub fn into_raw(self) -> libc::__wasi_fd_t {
pub fn into_raw(self) -> wasi::Fd {
let ret = self.fd;
mem::forget(self);
ret
}
pub fn as_raw(&self) -> libc::__wasi_fd_t {
pub fn as_raw(&self) -> wasi::Fd {
self.fd
}
pub fn datasync(&self) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_datasync(self.fd) })
unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
}
pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
let mut read = 0;
let (ptr, len) = iovec(bufs);
cvt_wasi(unsafe { libc::__wasi_fd_pread(self.fd, ptr, len, offset, &mut read) })?;
Ok(read)
unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) }
}
pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
let mut read = 0;
let (ptr, len) = ciovec(bufs);
cvt_wasi(unsafe { libc::__wasi_fd_pwrite(self.fd, ptr, len, offset, &mut read) })?;
Ok(read)
unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) }
}
pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let mut read = 0;
let (ptr, len) = iovec(bufs);
cvt_wasi(unsafe { libc::__wasi_fd_read(self.fd, ptr, len, &mut read) })?;
Ok(read)
unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
}
pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let mut read = 0;
let (ptr, len) = ciovec(bufs);
cvt_wasi(unsafe { libc::__wasi_fd_write(self.fd, ptr, len, &mut read) })?;
Ok(read)
unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
}
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
let (whence, offset) = match pos {
SeekFrom::Start(pos) => (libc::__WASI_WHENCE_SET, pos as i64),
SeekFrom::End(pos) => (libc::__WASI_WHENCE_END, pos),
SeekFrom::Current(pos) => (libc::__WASI_WHENCE_CUR, pos),
SeekFrom::Start(pos) => (wasi::WHENCE_SET, pos as i64),
SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
};
let mut pos = 0;
cvt_wasi(unsafe { libc::__wasi_fd_seek(self.fd, offset, whence, &mut pos) })?;
Ok(pos)
unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
}
pub fn tell(&self) -> io::Result<u64> {
let mut pos = 0;
cvt_wasi(unsafe { libc::__wasi_fd_tell(self.fd, &mut pos) })?;
Ok(pos)
unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
}
// FIXME: __wasi_fd_fdstat_get
pub fn set_flags(&self, flags: FdFlags) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_flags(self.fd, flags) })
pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
}
pub fn set_rights(&self, base: Rights, inheriting: Rights) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_rights(self.fd, base, inheriting) })
pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) }
}
pub fn sync(&self) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_sync(self.fd) })
unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
}
pub fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_advise(self.fd, offset, len, advice as u8) })
pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) }
}
pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_allocate(self.fd, offset, len) })
unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
}
pub fn create_directory(&self, path: &[u8]) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_create_directory(self.fd, path.as_ptr() as *const c_char, path.len())
})
unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
}
pub fn link(
&self,
old_flags: LookupFlags,
old_flags: wasi::LookupFlags,
old_path: &[u8],
new_fd: &WasiFd,
new_path: &[u8],
) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_link(
self.fd,
old_flags,
old_path.as_ptr() as *const c_char,
old_path.len(),
new_fd.fd,
new_path.as_ptr() as *const c_char,
new_path.len(),
)
})
unsafe {
wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path)
.map_err(err2io)
}
}
pub fn open(
&self,
dirflags: LookupFlags,
dirflags: wasi::LookupFlags,
path: &[u8],
oflags: Oflags,
fs_rights_base: Rights,
fs_rights_inheriting: Rights,
fs_flags: FdFlags,
oflags: wasi::OFlags,
fs_rights_base: wasi::Rights,
fs_rights_inheriting: wasi::Rights,
fs_flags: wasi::FdFlags,
) -> io::Result<WasiFd> {
unsafe {
let mut fd = 0;
cvt_wasi(libc::__wasi_path_open(
wasi::path_open(
self.fd,
dirflags,
path.as_ptr() as *const c_char,
path.len(),
path,
oflags,
fs_rights_base,
fs_rights_inheriting,
fs_flags,
&mut fd,
))?;
Ok(WasiFd::from_raw(fd))
).map(|fd| WasiFd::from_raw(fd)).map_err(err2io)
}
}
pub fn readdir(&self, buf: &mut [u8], cookie: DirCookie) -> io::Result<usize> {
let mut used = 0;
cvt_wasi(unsafe {
libc::__wasi_fd_readdir(
self.fd,
buf.as_mut_ptr() as *mut c_void,
buf.len(),
cookie,
&mut used,
)
})?;
Ok(used)
pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result<usize> {
unsafe { wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) }
}
pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result<usize> {
let mut used = 0;
cvt_wasi(unsafe {
libc::__wasi_path_readlink(
self.fd,
path.as_ptr() as *const c_char,
path.len(),
buf.as_mut_ptr() as *mut c_char,
buf.len(),
&mut used,
)
})?;
Ok(used)
unsafe { wasi::path_readlink(self.fd, path, buf).map_err(err2io) }
}
pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_rename(
self.fd,
old_path.as_ptr() as *const c_char,
old_path.len(),
new_fd.fd,
new_path.as_ptr() as *const c_char,
new_path.len(),
)
})
unsafe {
wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io)
}
}
pub fn filestat_get(&self, buf: *mut libc::__wasi_filestat_t) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_filestat_get(self.fd, buf) })
pub fn filestat_get(&self) -> io::Result<wasi::FileStat> {
unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
}
pub fn filestat_set_times(
&self,
atim: Timestamp,
mtim: Timestamp,
fstflags: FstFlags,
atim: wasi::Timestamp,
mtim: wasi::Timestamp,
fstflags: wasi::FstFlags,
) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_times(self.fd, atim, mtim, fstflags) })
unsafe {
wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io)
}
}
pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_size(self.fd, size) })
unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
}
pub fn path_filestat_get(
&self,
flags: LookupFlags,
flags: wasi::LookupFlags,
path: &[u8],
buf: *mut libc::__wasi_filestat_t,
) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_filestat_get(
self.fd,
flags,
path.as_ptr() as *const c_char,
path.len(),
buf,
)
})
) -> io::Result<wasi::FileStat> {
unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
}
pub fn path_filestat_set_times(
&self,
flags: LookupFlags,
flags: wasi::LookupFlags,
path: &[u8],
atim: Timestamp,
mtim: Timestamp,
fstflags: FstFlags,
atim: wasi::Timestamp,
mtim: wasi::Timestamp,
fstflags: wasi::FstFlags,
) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_filestat_set_times(
unsafe {
wasi::path_filestat_set_times(
self.fd,
flags,
path.as_ptr() as *const c_char,
path.len(),
path,
atim,
mtim,
fstflags,
)
})
).map_err(err2io)
}
}
pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_symlink(
old_path.as_ptr() as *const c_char,
old_path.len(),
self.fd,
new_path.as_ptr() as *const c_char,
new_path.len(),
)
})
unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
}
pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_unlink_file(self.fd, path.as_ptr() as *const c_char, path.len())
})
unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
}
pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> {
cvt_wasi(unsafe {
libc::__wasi_path_remove_directory(self.fd, path.as_ptr() as *const c_char, path.len())
})
unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
}
pub fn sock_recv(
&self,
ri_data: &mut [IoSliceMut<'_>],
ri_flags: RiFlags,
) -> io::Result<(usize, RoFlags)> {
let mut ro_datalen = 0;
let mut ro_flags = 0;
let (ptr, len) = iovec(ri_data);
cvt_wasi(unsafe {
libc::__wasi_sock_recv(self.fd, ptr, len, ri_flags, &mut ro_datalen, &mut ro_flags)
})?;
Ok((ro_datalen, ro_flags))
ri_flags: wasi::RiFlags,
) -> io::Result<(usize, wasi::RoFlags)> {
unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
}
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: SiFlags) -> io::Result<usize> {
let mut so_datalen = 0;
let (ptr, len) = ciovec(si_data);
cvt_wasi(unsafe { libc::__wasi_sock_send(self.fd, ptr, len, si_flags, &mut so_datalen) })?;
Ok(so_datalen)
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result<usize> {
unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
}
pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
let how = match how {
Shutdown::Read => libc::__WASI_SHUT_RD,
Shutdown::Write => libc::__WASI_SHUT_WR,
Shutdown::Both => libc::__WASI_SHUT_WR | libc::__WASI_SHUT_RD,
Shutdown::Read => wasi::SHUT_RD,
Shutdown::Write => wasi::SHUT_WR,
Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD,
};
cvt_wasi(unsafe { libc::__wasi_sock_shutdown(self.fd, how) })?;
Ok(())
unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
}
}
impl Drop for WasiFd {
fn drop(&mut self) {
unsafe {
// FIXME: can we handle the return code here even though we can't on
// unix?
libc::__wasi_fd_close(self.fd);
}
// FIXME: can we handle the return code here even though we can't on
// unix?
let _ = unsafe { wasi::fd_close(self.fd) };
}
}

View File

@ -7,7 +7,7 @@ use crate::os::wasi::ffi::{OsStrExt, OsStringExt};
use crate::path::{Path, PathBuf};
use crate::ptr;
use crate::sync::Arc;
use crate::sys::fd::{DirCookie, WasiFd};
use crate::sys::fd::WasiFd;
use crate::sys::time::SystemTime;
use crate::sys::unsupported;
use crate::sys_common::FromInner;
@ -15,18 +15,20 @@ use crate::sys_common::FromInner;
pub use crate::sys_common::fs::copy;
pub use crate::sys_common::fs::remove_dir_all;
use ::wasi::wasi_unstable as wasi;
pub struct File {
fd: WasiFd,
}
#[derive(Clone)]
pub struct FileAttr {
meta: libc::__wasi_filestat_t,
meta: wasi::FileStat,
}
pub struct ReadDir {
inner: Arc<ReadDirInner>,
cookie: Option<DirCookie>,
cookie: Option<wasi::DirCookie>,
buf: Vec<u8>,
offset: usize,
cap: usize,
@ -38,7 +40,7 @@ struct ReadDirInner {
}
pub struct DirEntry {
meta: libc::__wasi_dirent_t,
meta: wasi::Dirent,
name: Vec<u8>,
inner: Arc<ReadDirInner>,
}
@ -47,11 +49,11 @@ pub struct DirEntry {
pub struct OpenOptions {
read: bool,
write: bool,
dirflags: libc::__wasi_lookupflags_t,
fdflags: libc::__wasi_fdflags_t,
oflags: libc::__wasi_oflags_t,
rights_base: Option<libc::__wasi_rights_t>,
rights_inheriting: Option<libc::__wasi_rights_t>,
dirflags: wasi::LookupFlags,
fdflags: wasi::FdFlags,
oflags: wasi::OFlags,
rights_base: Option<wasi::Rights>,
rights_inheriting: Option<wasi::Rights>,
}
#[derive(Clone, PartialEq, Eq, Debug)]
@ -61,19 +63,13 @@ pub struct FilePermissions {
#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
pub struct FileType {
bits: libc::__wasi_filetype_t,
bits: wasi::FileType,
}
#[derive(Debug)]
pub struct DirBuilder {}
impl FileAttr {
fn zero() -> FileAttr {
FileAttr {
meta: unsafe { mem::zeroed() },
}
}
pub fn size(&self) -> u64 {
self.meta.st_size
}
@ -101,7 +97,7 @@ impl FileAttr {
Ok(SystemTime::from_wasi_timestamp(self.meta.st_ctim))
}
pub fn as_wasi(&self) -> &libc::__wasi_filestat_t {
pub fn as_wasi(&self) -> &wasi::FileStat {
&self.meta
}
}
@ -118,18 +114,18 @@ impl FilePermissions {
impl FileType {
pub fn is_dir(&self) -> bool {
self.bits == libc::__WASI_FILETYPE_DIRECTORY
self.bits == wasi::FILETYPE_DIRECTORY
}
pub fn is_file(&self) -> bool {
self.bits == libc::__WASI_FILETYPE_REGULAR_FILE
self.bits == wasi::FILETYPE_REGULAR_FILE
}
pub fn is_symlink(&self) -> bool {
self.bits == libc::__WASI_FILETYPE_SYMBOLIC_LINK
self.bits == wasi::FILETYPE_SYMBOLIC_LINK
}
pub fn bits(&self) -> libc::__wasi_filetype_t {
pub fn bits(&self) -> wasi::FileType {
self.bits
}
}
@ -173,7 +169,7 @@ impl Iterator for ReadDir {
// must have been truncated at the end of the buffer, so reset our
// offset so we can go back and reread into the buffer, picking up
// where we last left off.
let dirent_size = mem::size_of::<libc::__wasi_dirent_t>();
let dirent_size = mem::size_of::<wasi::Dirent>();
if data.len() < dirent_size {
assert!(self.cookie.is_some());
assert!(self.buf.len() >= dirent_size);
@ -182,7 +178,7 @@ impl Iterator for ReadDir {
}
let (dirent, data) = data.split_at(dirent_size);
let dirent =
unsafe { ptr::read_unaligned(dirent.as_ptr() as *const libc::__wasi_dirent_t) };
unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) };
// If the file name was truncated, then we need to reinvoke
// `readdir` so we truncate our buffer to start over and reread this
@ -241,7 +237,7 @@ impl DirEntry {
})
}
pub fn ino(&self) -> libc::__wasi_inode_t {
pub fn ino(&self) -> wasi::Inode {
self.meta.d_ino
}
}
@ -249,7 +245,7 @@ impl DirEntry {
impl OpenOptions {
pub fn new() -> OpenOptions {
let mut base = OpenOptions::default();
base.dirflags = libc::__WASI_LOOKUP_SYMLINK_FOLLOW;
base.dirflags = wasi::LOOKUP_SYMLINK_FOLLOW;
return base;
}
@ -262,23 +258,23 @@ impl OpenOptions {
}
pub fn truncate(&mut self, truncate: bool) {
self.oflag(libc::__WASI_O_TRUNC, truncate);
self.oflag(wasi::O_TRUNC, truncate);
}
pub fn create(&mut self, create: bool) {
self.oflag(libc::__WASI_O_CREAT, create);
self.oflag(wasi::O_CREAT, create);
}
pub fn create_new(&mut self, create_new: bool) {
self.oflag(libc::__WASI_O_EXCL, create_new);
self.oflag(libc::__WASI_O_CREAT, create_new);
self.oflag(wasi::O_EXCL, create_new);
self.oflag(wasi::O_CREAT, create_new);
}
pub fn directory(&mut self, directory: bool) {
self.oflag(libc::__WASI_O_DIRECTORY, directory);
self.oflag(wasi::O_DIRECTORY, directory);
}
fn oflag(&mut self, bit: libc::__wasi_oflags_t, set: bool) {
fn oflag(&mut self, bit: wasi::OFlags, set: bool) {
if set {
self.oflags |= bit;
} else {
@ -287,26 +283,26 @@ impl OpenOptions {
}
pub fn append(&mut self, set: bool) {
self.fdflag(libc::__WASI_FDFLAG_APPEND, set);
self.fdflag(wasi::FDFLAG_APPEND, set);
}
pub fn dsync(&mut self, set: bool) {
self.fdflag(libc::__WASI_FDFLAG_DSYNC, set);
self.fdflag(wasi::FDFLAG_DSYNC, set);
}
pub fn nonblock(&mut self, set: bool) {
self.fdflag(libc::__WASI_FDFLAG_NONBLOCK, set);
self.fdflag(wasi::FDFLAG_NONBLOCK, set);
}
pub fn rsync(&mut self, set: bool) {
self.fdflag(libc::__WASI_FDFLAG_RSYNC, set);
self.fdflag(wasi::FDFLAG_RSYNC, set);
}
pub fn sync(&mut self, set: bool) {
self.fdflag(libc::__WASI_FDFLAG_SYNC, set);
self.fdflag(wasi::FDFLAG_SYNC, set);
}
fn fdflag(&mut self, bit: libc::__wasi_fdflags_t, set: bool) {
fn fdflag(&mut self, bit: wasi::FdFlags, set: bool) {
if set {
self.fdflags |= bit;
} else {
@ -314,15 +310,15 @@ impl OpenOptions {
}
}
pub fn fs_rights_base(&mut self, rights: libc::__wasi_rights_t) {
pub fn fs_rights_base(&mut self, rights: wasi::Rights) {
self.rights_base = Some(rights);
}
pub fn fs_rights_inheriting(&mut self, rights: libc::__wasi_rights_t) {
pub fn fs_rights_inheriting(&mut self, rights: wasi::Rights) {
self.rights_inheriting = Some(rights);
}
fn rights_base(&self) -> libc::__wasi_rights_t {
fn rights_base(&self) -> wasi::Rights {
if let Some(rights) = self.rights_base {
return rights;
}
@ -334,52 +330,52 @@ impl OpenOptions {
// based on that.
let mut base = 0;
if self.read {
base |= libc::__WASI_RIGHT_FD_READ;
base |= libc::__WASI_RIGHT_FD_READDIR;
base |= wasi::RIGHT_FD_READ;
base |= wasi::RIGHT_FD_READDIR;
}
if self.write {
base |= libc::__WASI_RIGHT_FD_WRITE;
base |= libc::__WASI_RIGHT_FD_DATASYNC;
base |= libc::__WASI_RIGHT_FD_ALLOCATE;
base |= libc::__WASI_RIGHT_FD_FILESTAT_SET_SIZE;
base |= wasi::RIGHT_FD_WRITE;
base |= wasi::RIGHT_FD_DATASYNC;
base |= wasi::RIGHT_FD_ALLOCATE;
base |= wasi::RIGHT_FD_FILESTAT_SET_SIZE;
}
// FIXME: some of these should probably be read-only or write-only...
base |= libc::__WASI_RIGHT_FD_ADVISE;
base |= libc::__WASI_RIGHT_FD_FDSTAT_SET_FLAGS;
base |= libc::__WASI_RIGHT_FD_FILESTAT_SET_TIMES;
base |= libc::__WASI_RIGHT_FD_SEEK;
base |= libc::__WASI_RIGHT_FD_SYNC;
base |= libc::__WASI_RIGHT_FD_TELL;
base |= libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY;
base |= libc::__WASI_RIGHT_PATH_CREATE_FILE;
base |= libc::__WASI_RIGHT_PATH_FILESTAT_GET;
base |= libc::__WASI_RIGHT_PATH_LINK_SOURCE;
base |= libc::__WASI_RIGHT_PATH_LINK_TARGET;
base |= libc::__WASI_RIGHT_PATH_OPEN;
base |= libc::__WASI_RIGHT_PATH_READLINK;
base |= libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY;
base |= libc::__WASI_RIGHT_PATH_RENAME_SOURCE;
base |= libc::__WASI_RIGHT_PATH_RENAME_TARGET;
base |= libc::__WASI_RIGHT_PATH_SYMLINK;
base |= libc::__WASI_RIGHT_PATH_UNLINK_FILE;
base |= libc::__WASI_RIGHT_POLL_FD_READWRITE;
base |= wasi::RIGHT_FD_ADVISE;
base |= wasi::RIGHT_FD_FDSTAT_SET_FLAGS;
base |= wasi::RIGHT_FD_FILESTAT_SET_TIMES;
base |= wasi::RIGHT_FD_SEEK;
base |= wasi::RIGHT_FD_SYNC;
base |= wasi::RIGHT_FD_TELL;
base |= wasi::RIGHT_PATH_CREATE_DIRECTORY;
base |= wasi::RIGHT_PATH_CREATE_FILE;
base |= wasi::RIGHT_PATH_FILESTAT_GET;
base |= wasi::RIGHT_PATH_LINK_SOURCE;
base |= wasi::RIGHT_PATH_LINK_TARGET;
base |= wasi::RIGHT_PATH_OPEN;
base |= wasi::RIGHT_PATH_READLINK;
base |= wasi::RIGHT_PATH_REMOVE_DIRECTORY;
base |= wasi::RIGHT_PATH_RENAME_SOURCE;
base |= wasi::RIGHT_PATH_RENAME_TARGET;
base |= wasi::RIGHT_PATH_SYMLINK;
base |= wasi::RIGHT_PATH_UNLINK_FILE;
base |= wasi::RIGHT_POLL_FD_READWRITE;
return base;
}
fn rights_inheriting(&self) -> libc::__wasi_rights_t {
fn rights_inheriting(&self) -> wasi::Rights {
self.rights_inheriting.unwrap_or_else(|| self.rights_base())
}
pub fn lookup_flags(&mut self, flags: libc::__wasi_lookupflags_t) {
pub fn lookup_flags(&mut self, flags: wasi::LookupFlags) {
self.dirflags = flags;
}
}
impl File {
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
let (dir, file) = open_parent(path, libc::__WASI_RIGHT_PATH_OPEN)?;
let (dir, file) = open_parent(path, wasi::RIGHT_PATH_OPEN)?;
open_at(&dir, &file, opts)
}
@ -388,14 +384,12 @@ impl File {
}
pub fn file_attr(&self) -> io::Result<FileAttr> {
let mut ret = FileAttr::zero();
self.fd.filestat_get(&mut ret.meta)?;
Ok(ret)
self.fd.filestat_get().map(|meta| FileAttr { meta })
}
pub fn metadata_at(
&self,
flags: libc::__wasi_lookupflags_t,
flags: wasi::LookupFlags,
path: &Path,
) -> io::Result<FileAttr> {
metadata_at(&self.fd, flags, path)
@ -477,7 +471,7 @@ impl DirBuilder {
}
pub fn mkdir(&self, p: &Path) -> io::Result<()> {
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY)?;
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_CREATE_DIRECTORY)?;
dir.create_directory(file.as_os_str().as_bytes())
}
}
@ -508,13 +502,13 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
}
pub fn unlink(p: &Path) -> io::Result<()> {
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_UNLINK_FILE)?;
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_UNLINK_FILE)?;
dir.unlink_file(file.as_os_str().as_bytes())
}
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
let (old, old_file) = open_parent(old, libc::__WASI_RIGHT_PATH_RENAME_SOURCE)?;
let (new, new_file) = open_parent(new, libc::__WASI_RIGHT_PATH_RENAME_TARGET)?;
let (old, old_file) = open_parent(old, wasi::RIGHT_PATH_RENAME_SOURCE)?;
let (new, new_file) = open_parent(new, wasi::RIGHT_PATH_RENAME_TARGET)?;
old.rename(
old_file.as_os_str().as_bytes(),
&new,
@ -529,12 +523,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
}
pub fn rmdir(p: &Path) -> io::Result<()> {
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY)?;
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_REMOVE_DIRECTORY)?;
dir.remove_directory(file.as_os_str().as_bytes())
}
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_READLINK)?;
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_READLINK)?;
read_link(&dir, &file)
}
@ -570,15 +564,15 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
}
pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_SYMLINK)?;
let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_SYMLINK)?;
dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes())
}
pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
let (src, src_file) = open_parent(src, libc::__WASI_RIGHT_PATH_LINK_SOURCE)?;
let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_LINK_TARGET)?;
let (src, src_file) = open_parent(src, wasi::RIGHT_PATH_LINK_SOURCE)?;
let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_LINK_TARGET)?;
src.link(
libc::__WASI_LOOKUP_SYMLINK_FOLLOW,
wasi::LOOKUP_SYMLINK_FOLLOW,
src_file.as_os_str().as_bytes(),
&dst,
dst_file.as_os_str().as_bytes(),
@ -586,23 +580,22 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
}
pub fn stat(p: &Path) -> io::Result<FileAttr> {
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?;
metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, &file)
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?;
metadata_at(&dir, wasi::LOOKUP_SYMLINK_FOLLOW, &file)
}
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?;
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?;
metadata_at(&dir, 0, &file)
}
fn metadata_at(
fd: &WasiFd,
flags: libc::__wasi_lookupflags_t,
flags: wasi::LookupFlags,
path: &Path,
) -> io::Result<FileAttr> {
let mut ret = FileAttr::zero();
fd.path_filestat_get(flags, path.as_os_str().as_bytes(), &mut ret.meta)?;
Ok(ret)
fd.path_filestat_get(flags, path.as_os_str().as_bytes())
.map(|meta| FileAttr { meta })
}
pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
@ -652,12 +645,12 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
/// to any preopened file descriptor.
fn open_parent(
p: &Path,
rights: libc::__wasi_rights_t,
rights: wasi::Rights,
) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
let p = CString::new(p.as_os_str().as_bytes())?;
unsafe {
let mut ret = ptr::null();
let fd = __wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret);
let fd = libc::__wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret);
if fd == -1 {
let msg = format!(
"failed to find a preopened file descriptor \
@ -677,15 +670,4 @@ fn open_parent(
return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path));
}
// FIXME(rust-lang/libc#1314) use the `libc` crate for this when the API
// there is published
extern "C" {
pub fn __wasilibc_find_relpath(
path: *const libc::c_char,
rights_base: libc::__wasi_rights_t,
rights_inheriting: libc::__wasi_rights_t,
relative_path: *mut *const libc::c_char,
) -> libc::c_int;
}
}

View File

@ -1,11 +1,12 @@
use crate::marker::PhantomData;
use crate::slice;
use libc::{__wasi_ciovec_t, __wasi_iovec_t, c_void};
use ::wasi::wasi_unstable as wasi;
use core::ffi::c_void;
#[repr(transparent)]
pub struct IoSlice<'a> {
vec: __wasi_ciovec_t,
vec: wasi::CIoVec,
_p: PhantomData<&'a [u8]>,
}
@ -13,7 +14,7 @@ impl<'a> IoSlice<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
IoSlice {
vec: __wasi_ciovec_t {
vec: wasi::CIoVec {
buf: buf.as_ptr() as *const c_void,
buf_len: buf.len(),
},
@ -43,7 +44,7 @@ impl<'a> IoSlice<'a> {
#[repr(transparent)]
pub struct IoSliceMut<'a> {
vec: __wasi_iovec_t,
vec: wasi::IoVec,
_p: PhantomData<&'a mut [u8]>,
}
@ -51,7 +52,7 @@ impl<'a> IoSliceMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
IoSliceMut {
vec: __wasi_iovec_t {
vec: wasi::IoVec {
buf: buf.as_mut_ptr() as *mut c_void,
buf_len: buf.len()
},

View File

@ -14,10 +14,10 @@
//! compiling for wasm. That way it's a compile time error for something that's
//! guaranteed to be a runtime error!
use libc;
use crate::io::{Error, ErrorKind};
use crate::io as std_io;
use crate::mem;
use crate::os::raw::c_char;
use ::wasi::wasi_unstable as wasi;
pub mod alloc;
pub mod args;
@ -56,31 +56,42 @@ pub mod ext;
pub fn init() {
}
pub fn unsupported<T>() -> crate::io::Result<T> {
pub fn unsupported<T>() -> std_io::Result<T> {
Err(unsupported_err())
}
pub fn unsupported_err() -> Error {
Error::new(ErrorKind::Other, "operation not supported on wasm yet")
pub fn unsupported_err() -> std_io::Error {
std_io::Error::new(
std_io::ErrorKind::Other,
"operation not supported on wasm yet",
)
}
pub fn decode_error_kind(errno: i32) -> ErrorKind {
match errno as libc::c_int {
libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
libc::ECONNRESET => ErrorKind::ConnectionReset,
libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
libc::EPIPE => ErrorKind::BrokenPipe,
libc::ENOTCONN => ErrorKind::NotConnected,
libc::ECONNABORTED => ErrorKind::ConnectionAborted,
libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
libc::EADDRINUSE => ErrorKind::AddrInUse,
libc::ENOENT => ErrorKind::NotFound,
libc::EINTR => ErrorKind::Interrupted,
libc::EINVAL => ErrorKind::InvalidInput,
libc::ETIMEDOUT => ErrorKind::TimedOut,
libc::EEXIST => ErrorKind::AlreadyExists,
libc::EAGAIN => ErrorKind::WouldBlock,
_ => ErrorKind::Other,
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
use std_io::ErrorKind::*;
if errno > u16::max_value() as i32 || errno < 0 {
return Other;
}
let code = match wasi::Error::new(errno as u16) {
Some(code) => code,
None => return Other,
};
match code {
wasi::ECONNREFUSED => ConnectionRefused,
wasi::ECONNRESET => ConnectionReset,
wasi::EPERM | wasi::EACCES => PermissionDenied,
wasi::EPIPE => BrokenPipe,
wasi::ENOTCONN => NotConnected,
wasi::ECONNABORTED => ConnectionAborted,
wasi::EADDRNOTAVAIL => AddrNotAvailable,
wasi::EADDRINUSE => AddrInUse,
wasi::ENOENT => NotFound,
wasi::EINTR => Interrupted,
wasi::EINVAL => InvalidInput,
wasi::ETIMEDOUT => TimedOut,
wasi::EEXIST => AlreadyExists,
wasi::EAGAIN => WouldBlock,
_ => Other,
}
}
@ -105,40 +116,16 @@ pub unsafe fn abort_internal() -> ! {
pub fn hashmap_random_keys() -> (u64, u64) {
let mut ret = (0u64, 0u64);
unsafe {
let base = &mut ret as *mut (u64, u64) as *mut libc::c_void;
let base = &mut ret as *mut (u64, u64) as *mut core::ffi::c_void;
let len = mem::size_of_val(&ret);
cvt_wasi(libc::__wasi_random_get(base, len)).unwrap();
let ret = wasi::raw::__wasi_random_get(base, len);
if ret != 0 {
panic!("__wasi_random_get failure")
}
}
return ret
}
#[doc(hidden)]
pub trait IsMinusOne {
fn is_minus_one(&self) -> bool;
}
macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}
impl_is_minus_one! { i8 i16 i32 i64 isize }
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
if t.is_minus_one() {
Err(Error::last_os_error())
} else {
Ok(t)
}
}
pub fn cvt_wasi(r: u16) -> crate::io::Result<()> {
if r != libc::__WASI_ESUCCESS {
Err(Error::from_raw_os_error(r as i32))
} else {
Ok(())
}
fn err2io(err: wasi::Error) -> std_io::Error {
std_io::Error::from_raw_os_error(err.get() as i32)
}

View File

@ -9,7 +9,7 @@ use crate::path::{self, PathBuf};
use crate::ptr;
use crate::str;
use crate::sys::memchr;
use crate::sys::{cvt, unsupported, Void};
use crate::sys::{unsupported, Void};
use crate::vec;
#[cfg(not(target_feature = "atomics"))]
@ -28,16 +28,11 @@ pub fn errno() -> i32 {
}
pub fn error_string(errno: i32) -> String {
extern {
fn strerror_r(errnum: libc::c_int, buf: *mut libc::c_char,
buflen: libc::size_t) -> libc::c_int;
}
let mut buf = [0 as libc::c_char; 1024];
let p = buf.as_mut_ptr();
unsafe {
if strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
@ -89,7 +84,6 @@ impl StdError for JoinPathsError {
pub fn current_exe() -> io::Result<PathBuf> {
unsupported()
}
pub struct Env {
iter: vec::IntoIter<(OsString, OsString)>,
_dont_send_or_sync_me: PhantomData<*mut ()>,
@ -182,3 +176,26 @@ pub fn exit(code: i32) -> ! {
pub fn getpid() -> u32 {
panic!("unsupported");
}
#[doc(hidden)]
pub trait IsMinusOne {
fn is_minus_one(&self) -> bool;
}
macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}
impl_is_minus_one! { i8 i16 i32 i64 isize }
fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
if t.is_minus_one() {
Err(io::Error::last_os_error())
} else {
Ok(t)
}
}

View File

@ -1,8 +1,9 @@
use crate::io::{self, IoSlice, IoSliceMut};
use crate::libc;
use crate::mem::ManuallyDrop;
use crate::sys::fd::WasiFd;
use ::wasi::wasi_unstable as wasi;
pub struct Stdin;
pub struct Stdout;
pub struct Stderr;
@ -17,7 +18,7 @@ impl Stdin {
}
pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDIN_FD) })
.read(data)
}
}
@ -32,7 +33,7 @@ impl Stdout {
}
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDOUT_FILENO as u32) })
ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDOUT_FD) })
.write(data)
}
@ -51,7 +52,7 @@ impl Stderr {
}
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDERR_FILENO as u32) })
ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDERR_FD) })
.write(data)
}
@ -73,7 +74,7 @@ impl io::Write for Stderr {
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
pub fn is_ebadf(err: &io::Error) -> bool {
err.raw_os_error() == Some(libc::__WASI_EBADF as i32)
err.raw_os_error() == Some(wasi::EBADF.get() as i32)
}
pub fn panic_output() -> Option<impl io::Write> {

View File

@ -1,10 +1,10 @@
use crate::cmp;
use crate::ffi::CStr;
use crate::io;
use crate::sys::cvt;
use crate::mem;
use crate::sys::{unsupported, Void};
use crate::time::Duration;
use libc;
use ::wasi::wasi_unstable as wasi;
pub struct Thread(Void);
@ -19,8 +19,8 @@ impl Thread {
}
pub fn yield_now() {
let ret = unsafe { libc::__wasi_sched_yield() };
debug_assert_eq!(ret, 0);
let ret = wasi::sched_yield();
debug_assert_eq!(ret, Ok(()));
}
pub fn set_name(_name: &CStr) {
@ -28,19 +28,37 @@ impl Thread {
}
pub fn sleep(dur: Duration) {
let mut secs = dur.as_secs();
let mut nsecs = dur.subsec_nanos() as i32;
let nanos = dur.as_nanos();
assert!(nanos <= u64::max_value() as u128);
unsafe {
while secs > 0 || nsecs > 0 {
let mut ts = libc::timespec {
tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t,
tv_nsec: nsecs,
};
secs -= ts.tv_sec as u64;
cvt(libc::nanosleep(&ts, &mut ts)).unwrap();
nsecs = 0;
}
const CLOCK_ID: wasi::Userdata = 0x0123_45678;
let clock = wasi::raw::__wasi_subscription_u_clock_t {
identifier: CLOCK_ID,
clock_id: wasi::CLOCK_MONOTONIC,
timeout: nanos as u64,
precision: 0,
flags: 0,
};
let in_ = [wasi::Subscription {
userdata: 0,
type_: wasi::EVENTTYPE_CLOCK,
u: wasi::raw::__wasi_subscription_u { clock: clock },
}];
let (res, event) = unsafe {
let mut out: [wasi::Event; 1] = mem::zeroed();
let res = wasi::poll_oneoff(&in_, &mut out);
(res, out[0])
};
match (res, event) {
(Ok(1), wasi::Event {
userdata: CLOCK_ID,
error: 0,
type_: wasi::EVENTTYPE_CLOCK,
..
}) => {}
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
}
}

View File

@ -1,7 +1,5 @@
use crate::time::Duration;
use crate::mem;
use crate::sys::cvt_wasi;
use libc;
use ::wasi::wasi_unstable as wasi;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Instant(Duration);
@ -12,23 +10,19 @@ pub struct SystemTime(Duration);
pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
fn current_time(clock: u32) -> Duration {
unsafe {
let mut ts = mem::zeroed();
cvt_wasi(libc::__wasi_clock_time_get(
clock,
1, // precision... seems ignored though?
&mut ts,
)).unwrap();
Duration::new(
(ts / 1_000_000_000) as u64,
(ts % 1_000_000_000) as u32,
)
}
let ts = wasi::clock_time_get(
clock,
1, // precision... seems ignored though?
).unwrap();
Duration::new(
(ts / 1_000_000_000) as u64,
(ts % 1_000_000_000) as u32,
)
}
impl Instant {
pub fn now() -> Instant {
Instant(current_time(libc::__WASI_CLOCK_MONOTONIC))
Instant(current_time(wasi::CLOCK_MONOTONIC))
}
pub const fn zero() -> Instant {
@ -54,10 +48,10 @@ impl Instant {
impl SystemTime {
pub fn now() -> SystemTime {
SystemTime(current_time(libc::__WASI_CLOCK_REALTIME))
SystemTime(current_time(wasi::CLOCK_REALTIME))
}
pub fn from_wasi_timestamp(ts: libc::__wasi_timestamp_t) -> SystemTime {
pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
SystemTime(Duration::from_nanos(ts))
}

View File

@ -15,6 +15,7 @@ const LICENSES: &[&str] = &[
"Apache-2.0 / MIT",
"MIT OR Apache-2.0",
"Apache-2.0 OR MIT",
"Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license
"MIT",
"Unlicense/MIT",
"Unlicense OR MIT",
@ -172,6 +173,7 @@ const WHITELIST: &[Crate<'_>] = &[
Crate("vcpkg"),
Crate("version_check"),
Crate("void"),
Crate("wasi"),
Crate("winapi"),
Crate("winapi-build"),
Crate("winapi-i686-pc-windows-gnu"),