From 6896ed383dbd3a847ef39b713449fc0393292828 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 09:47:58 +0300 Subject: [PATCH 01/21] use wasi crate --- src/libstd/sys/wasi/args.rs | 16 +- src/libstd/sys/wasi/ext/fs.rs | 8 +- src/libstd/sys/wasi/ext/io.rs | 8 +- src/libstd/sys/wasi/fd.rs | 302 +++++++++++----------------------- src/libstd/sys/wasi/fs.rs | 176 +++++++++----------- src/libstd/sys/wasi/io.rs | 11 +- src/libstd/sys/wasi/mod.rs | 31 ++-- src/libstd/sys/wasi/os.rs | 29 +--- src/libstd/sys/wasi/stdio.rs | 11 +- src/libstd/sys/wasi/thread.rs | 4 +- src/libstd/sys/wasi/time.rs | 29 ++-- 11 files changed, 249 insertions(+), 376 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 8b4b354d9fc20..679bb1b2cbe30 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -27,14 +27,24 @@ pub fn args() -> Args { }) } +fn cvt_wasi(r: u16) -> crate::io::Result<()> { + if r != 0 { + Err(Error::from_raw_os_error(r as i32)) + } else { + Ok(()) + } +} + fn maybe_args() -> io::Result { + // FIXME: replace with safe functions + use wasi::wasi_unstable::raw::{__wasi_args_sizes_get, __wasi_args_get}; unsafe { let (mut argc, mut argv_buf_size) = (0, 0); - cvt_wasi(libc::__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?; + cvt_wasi(__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?; - let mut argc = vec![core::ptr::null_mut::(); argc]; + let mut argc = vec![core::ptr::null_mut::(); 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()))?; + cvt_wasi(__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()) diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs index 0ec4122f385da..ecd509f01dabd 100644 --- a/src/libstd/sys/wasi/ext/fs.rs +++ b/src/libstd/sys/wasi/ext/fs.rs @@ -336,16 +336,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 } } diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs index 12afd1d42dc19..c843144f0c406 100644 --- a/src/libstd/sys/wasi/ext/io.rs +++ b/src/libstd/sys/wasi/ext/io.rs @@ -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 } } diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 25692ec086801..93fe8add326c8 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -3,348 +3,240 @@ 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 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: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] { assert_eq!( mem::size_of::>(), - mem::size_of::() + mem::size_of::() ); assert_eq!( mem::align_of::>(), - mem::align_of::() + mem::align_of::() ); - (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: &[IoSlice<'_>]) -> &[wasi::CIoVec] { assert_eq!( mem::size_of::>(), - mem::size_of::() + mem::size_of::() ); assert_eq!( mem::align_of::>(), - mem::align_of::() + mem::align_of::() ); - (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) }) + wasi::fd_datasync(self.fd).map_err(From::from) } pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - 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) + wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(From::from) } pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - 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) + wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(From::from) } pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - let mut read = 0; - let (ptr, len) = iovec(bufs); - cvt_wasi(unsafe { libc::__wasi_fd_read(self.fd, ptr, len, &mut read) })?; - Ok(read) + wasi::fd_read(self.fd, iovec(bufs)).map_err(From::from) } pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - let mut read = 0; - let (ptr, len) = ciovec(bufs); - cvt_wasi(unsafe { libc::__wasi_fd_write(self.fd, ptr, len, &mut read) })?; - Ok(read) + wasi::fd_write(self.fd, ciovec(bufs)).map_err(From::from) } pub fn seek(&self, pos: SeekFrom) -> io::Result { 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) + wasi::fd_seek(self.fd, offset, whence).map_err(From::from) } pub fn tell(&self) -> io::Result { - let mut pos = 0; - cvt_wasi(unsafe { libc::__wasi_fd_tell(self.fd, &mut pos) })?; - Ok(pos) + wasi::fd_tell(self.fd).map_err(From::from) } // 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<()> { + wasi::fd_fdstat_set_flags(self.fd, flags).map_err(From::from) } - 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<()> { + wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(From::from) } pub fn sync(&self) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_sync(self.fd) }) + wasi::fd_sync(self.fd).map_err(From::from) } - 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<()> { + wasi::fd_advise(self.fd, offset, len, advice).map_err(From::from) } pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_allocate(self.fd, offset, len) }) + wasi::fd_allocate(self.fd, offset, len).map_err(From::from) } 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()) - }) + wasi::path_create_directory(self.fd, path).map_err(From::from) } 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(), - ) - }) + wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) + .map_err(From::from) } 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 { - unsafe { - let mut fd = 0; - cvt_wasi(libc::__wasi_path_open( - self.fd, - dirflags, - path.as_ptr() as *const c_char, - path.len(), - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - &mut fd, - ))?; - Ok(WasiFd::from_raw(fd)) - } - } - - pub fn readdir(&self, buf: &mut [u8], cookie: DirCookie) -> io::Result { - 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) + let fd = wasi_path_open( + self.fd, + dirflags, + path, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + )?; + Ok(WasiFd::from_raw(fd)) + } + + pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { + wasi::fd_readdir(self.fd, buf, cookie).map_err(From::from) } pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { - 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) + wasi::path_readlink(self.fd, path, buf).map_err(From::from) } 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(), - ) - }) + wasi::path_rename(self.fd, old_path, new_fd.fd, new_path) + .map_err(From::from) } - 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::fd_filestat_get(self.fd, buf).map_err(From::from) } 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) }) + wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags) + .map_err(From::from) } pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_size(self.fd, size) }) + wasi::fd_filestat_set_size(self.fd, size).map_err(From::from) } 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::path_filestat_get(self.fd, flags, path).map_err(From::from) } 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( - self.fd, - flags, - path.as_ptr() as *const c_char, - path.len(), - atim, - mtim, - fstflags, - ) - }) + wasi::path_filestat_set_times( + self.fd, + flags, + path, + atim, + mtim, + fstflags, + ).map_err(From::from) } 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(), - ) - }) + wasi::path_symlink(old_path, self.fd, new_path).map_err(From::from) } 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()) - }) + wasi::path_unlink_file(self.fd, path).map_err(From::from) } 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()) - }) + wasi::path_remove_directory(self.fd, path).map_err(From::from) } 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)> { + wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(From::from) } - pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: SiFlags) -> io::Result { - 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 { + wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(From::from) } 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(()) + wasi::sock_shutdown(self.fd, how).map_err(From::from) } } 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 _ = wasi::fd_close(self.fd); } } diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 172c60385b317..f23ecfc2bcd22 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -15,13 +15,15 @@ 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 { @@ -38,7 +40,7 @@ struct ReadDirInner { } pub struct DirEntry { - meta: libc::__wasi_dirent_t, + meta: wasi::Dirent, name: Vec, inner: Arc, } @@ -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, - rights_inheriting: Option, + dirflags: wasi::LookupFlags, + fdflags: wasi::FdFlags, + oflags: wasi::OFlags, + rights_base: Option, + rights_inheriting: Option, } #[derive(Clone, PartialEq, Eq, Debug)] @@ -61,7 +63,7 @@ pub struct FilePermissions { #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] pub struct FileType { - bits: libc::__wasi_filetype_t, + bits: wasi::FileType, } #[derive(Debug)] @@ -101,7 +103,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 +120,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 +175,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::(); + let dirent_size = mem::size_of::(); if data.len() < dirent_size { assert!(self.cookie.is_some()); assert!(self.buf.len() >= dirent_size); @@ -182,7 +184,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 +243,7 @@ impl DirEntry { }) } - pub fn ino(&self) -> libc::__wasi_inode_t { + pub fn ino(&self) -> wasi::Inode { self.meta.d_ino } } @@ -249,7 +251,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 +264,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 +289,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 +316,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 +336,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 { - 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 +390,12 @@ impl File { } pub fn file_attr(&self) -> io::Result { - let mut ret = FileAttr::zero(); - self.fd.filestat_get(&mut ret.meta)?; - Ok(ret) + self.fd.filestat_get().map_ok(|meta| FileAttr { meta }) } pub fn metadata_at( &self, - flags: libc::__wasi_lookupflags_t, + flags: wasi::LookupFlags, path: &Path, ) -> io::Result { metadata_at(&self.fd, flags, path) @@ -477,7 +477,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 +508,13 @@ pub fn readdir(p: &Path) -> io::Result { } 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 +529,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 { - 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 +570,15 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result { } 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 +586,22 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> { } pub fn stat(p: &Path) -> io::Result { - 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 { - 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 { - 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_ok(|meta| FileAttr { meta }) } pub fn canonicalize(_p: &Path) -> io::Result { @@ -652,12 +651,12 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result { /// to any preopened file descriptor. fn open_parent( p: &Path, - rights: libc::__wasi_rights_t, + rights: wasi::Rights, ) -> io::Result<(ManuallyDrop, 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 +676,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; - } } diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs index ffecca5d1b6ff..ebea3a03e439f 100644 --- a/src/libstd/sys/wasi/io.rs +++ b/src/libstd/sys/wasi/io.rs @@ -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() }, diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index f842869e08ee6..0a16c29e5af53 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -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; use crate::mem; use crate::os::raw::c_char; +use wasi::wasi_unstable as wasi; pub mod alloc; pub mod args; @@ -60,12 +60,12 @@ pub fn unsupported() -> crate::io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> Error { - Error::new(ErrorKind::Other, "operation not supported on wasm yet") +pub fn unsupported_err() -> io::Error { + io::Error::new(io::ErrorKind::Other, "operation not supported on wasm yet") } -pub fn decode_error_kind(_code: i32) -> ErrorKind { - ErrorKind::Other +pub fn decode_error_kind(_code: i32) -> io::ErrorKind { + io::ErrorKind::Other } // This enum is used as the storage for a bunch of types which can't actually @@ -83,15 +83,18 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize { } pub unsafe fn abort_internal() -> ! { - libc::abort() + wasi::proc_exit(127) } 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 } @@ -113,16 +116,14 @@ impl_is_minus_one! { i8 i16 i32 i64 isize } pub fn cvt(t: T) -> crate::io::Result { if t.is_minus_one() { - Err(Error::last_os_error()) + Err(io::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(()) +impl From for io::Error { + fn from(err: wasi::Error) -> Self { + Self::from_raw_os_error(err as i32) } } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 822ea02a11b89..026ff71de345b 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -12,6 +12,8 @@ use crate::sys::memchr; use crate::sys::{cvt, unsupported, Void}; use crate::vec; +use wasi::wasi_unstable as wasi; + #[cfg(not(target_feature = "atomics"))] pub unsafe fn env_lock() -> impl Any { // No need for a lock if we're single-threaded, but this function will need @@ -19,29 +21,11 @@ pub unsafe fn env_lock() -> impl Any { } pub fn errno() -> i32 { - extern { - #[thread_local] - static errno: libc::c_int; - } - - unsafe { errno as i32 } + panic!("unsupported") } 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 { - panic!("strerror_r failure"); - } - str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() - } + wasi::error_string(errno).to_string() } pub fn getcwd() -> io::Result { @@ -105,6 +89,7 @@ impl Iterator for Env { pub fn env() -> Env { unsafe { let _guard = env_lock(); + // FIXME: replace with wasi::environ_get let mut environ = libc::environ; let mut result = Vec::new(); while environ != ptr::null_mut() && *environ != ptr::null_mut() { @@ -174,9 +159,7 @@ pub fn home_dir() -> Option { } pub fn exit(code: i32) -> ! { - unsafe { - libc::exit(code) - } + unsafe { wasi::proc_exit(code as u32) } } pub fn getpid() -> u32 { diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs index 2bf8d803c01bb..dc6a6ef375a1c 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -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 { - 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 { - 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 { - 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 as i32) } pub fn panic_output() -> Option { diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 5e69e4d948fee..9e0726432d9c4 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -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) { diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs index 3f14c80928c67..4c89a1781b9ef 100644 --- a/src/libstd/sys/wasi/time.rs +++ b/src/libstd/sys/wasi/time.rs @@ -1,7 +1,6 @@ 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 +11,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 +49,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)) } From 23cc850ff18652c7b75fa423f9dfff5526a239a7 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 10:44:08 +0300 Subject: [PATCH 02/21] return 0 from errno function --- src/libstd/sys/wasi/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 026ff71de345b..8411878eeccd9 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -21,7 +21,7 @@ pub unsafe fn env_lock() -> impl Any { } pub fn errno() -> i32 { - panic!("unsupported") + 0 } pub fn error_string(errno: i32) -> String { From cb52065d55e5ba1383aa155880a5e6661e6415a7 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 13:31:41 +0300 Subject: [PATCH 03/21] replace libc::nanosleep with wasi::poll_oneoff --- src/libstd/sys/wasi/thread.rs | 37 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 9e0726432d9c4..eedc584dde500 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -1,7 +1,7 @@ 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; @@ -28,19 +28,28 @@ impl Thread { } pub fn sleep(dur: Duration) { - let mut secs = dur.as_secs(); - let mut nsecs = dur.subsec_nanos() as i32; - - 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; - } + let nanos = dur.as_nanos(); + assert!(nanos <= u64::max_value() as u128); + + let clock = wasi::raw::__wasi_subscription_u_clock_t { + identifier: 0, + 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 mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }]; + let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); + let wasi::Event { userdata, error, type_, .. } = out[0]; + match (n, userdata, error) { + (1, 0, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + _ => panic!("thread::sleep(): unexpected result of poll_oneof"), } } From 75a553fa27ffa293a21be5c5138b2b9fd69adfd2 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 13:50:22 +0300 Subject: [PATCH 04/21] remove to_string --- src/libstd/sys/wasi/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 8411878eeccd9..091ff3480bf85 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -25,7 +25,7 @@ pub fn errno() -> i32 { } pub fn error_string(errno: i32) -> String { - wasi::error_string(errno).to_string() + wasi::error_string(errno) } pub fn getcwd() -> io::Result { From 7a4f0aece871f9850f83db4760a6fea4f595dc8d Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 14:54:37 +0300 Subject: [PATCH 05/21] use wasi::get_args --- src/libstd/sys/wasi/args.rs | 42 +++++-------------------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 679bb1b2cbe30..e2fe0548f1266 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -13,47 +13,15 @@ pub unsafe fn cleanup() { } pub struct Args { - iter: vec::IntoIter, + iter: vec::IntoIter>, _dont_send_or_sync_me: PhantomData<*mut ()>, } /// 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 cvt_wasi(r: u16) -> crate::io::Result<()> { - if r != 0 { - Err(Error::from_raw_os_error(r as i32)) - } else { - Ok(()) - } -} - -fn maybe_args() -> io::Result { - // FIXME: replace with safe functions - use wasi::wasi_unstable::raw::{__wasi_args_sizes_get, __wasi_args_get}; - unsafe { - let (mut argc, mut argv_buf_size) = (0, 0); - cvt_wasi(__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?; - - let mut argc = vec![core::ptr::null_mut::(); argc]; - let mut argv_buf = vec![0; argv_buf_size]; - cvt_wasi(__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::>(); - Ok(Args { - iter: args.into_iter(), - _dont_send_or_sync_me: PhantomData, - }) + Args { + iter: wasi::get_args().unwrap_or(Vec::new()), + _dont_send_or_sync_me: PhantomData } } @@ -66,7 +34,7 @@ impl Args { impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - self.iter.next() + self.iter.next().map(OsString::from_vec) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() From 52d2871e10202279b7039f4ad6d4485093fb99cc Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:18:02 +0300 Subject: [PATCH 06/21] use wasi::get_environ --- src/libstd/sys/wasi/args.rs | 1 - src/libstd/sys/wasi/os.rs | 46 ++++++++++++++----------------------- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index e2fe0548f1266..23ab2051bf6f6 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -1,6 +1,5 @@ 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; diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 091ff3480bf85..65c80c838dc82 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -75,45 +75,33 @@ pub fn current_exe() -> io::Result { } pub struct Env { - iter: vec::IntoIter<(OsString, OsString)>, + iter: Vec>, _dont_send_or_sync_me: PhantomData<*mut ()>, } impl Iterator for Env { type Item = (OsString, OsString); - fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() } + fn next(&mut self) -> Option<(OsString, OsString)> { + self.iter.next().and_then(|input| { + // See src/libstd/sys/unix/os.rs, same as that + if input.is_empty() { + return None; + } + let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); + pos.map(|p| ( + OsStringExt::from_vec(input[..p].to_vec()), + OsStringExt::from_vec(input[p+1..].to_vec()), + )) + }) + } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } pub fn env() -> Env { - unsafe { - let _guard = env_lock(); - // FIXME: replace with wasi::environ_get - let mut environ = libc::environ; - let mut result = Vec::new(); - while environ != ptr::null_mut() && *environ != ptr::null_mut() { - if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { - result.push(key_value); - } - environ = environ.offset(1); - } - return Env { - iter: result.into_iter(), - _dont_send_or_sync_me: PhantomData, - } - } - - // See src/libstd/sys/unix/os.rs, same as that - fn parse(input: &[u8]) -> Option<(OsString, OsString)> { - if input.is_empty() { - return None; - } - let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); - pos.map(|p| ( - OsStringExt::from_vec(input[..p].to_vec()), - OsStringExt::from_vec(input[p+1..].to_vec()), - )) + Env { + iter: wasi::get_environ().unwrap_or(Vec::new()), + _dont_send_or_sync_me: PhantomData, } } From 8394dbba7a46cd480b0934331b2654663d487e7b Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:18:39 +0300 Subject: [PATCH 07/21] remove libc import --- src/libstd/sys/wasi/thread.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index eedc584dde500..a399d1f844cb0 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -4,7 +4,6 @@ use crate::io; use crate::mem; use crate::sys::{unsupported, Void}; use crate::time::Duration; -use libc; pub struct Thread(Void); From 338fc7d042ac868e2c92bfedf2b6850bac1970c9 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:32:37 +0300 Subject: [PATCH 08/21] use non-zero clock id --- src/libstd/sys/wasi/thread.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index a399d1f844cb0..7a2246de86c4f 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -31,7 +31,7 @@ impl Thread { assert!(nanos <= u64::max_value() as u128); let clock = wasi::raw::__wasi_subscription_u_clock_t { - identifier: 0, + identifier: 0x0123_45678, clock_id: wasi::CLOCK_MONOTONIC, timeout: nanos as u64, precision: 0, @@ -47,7 +47,7 @@ impl Thread { let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { - (1, 0, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} _ => panic!("thread::sleep(): unexpected result of poll_oneof"), } } From 7658a13c650e3dd931250f6039c4f12bcc77534f Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:33:05 +0300 Subject: [PATCH 09/21] typo fix --- src/libstd/sys/wasi/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 7a2246de86c4f..f9e2433dca064 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -48,7 +48,7 @@ impl Thread { let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} - _ => panic!("thread::sleep(): unexpected result of poll_oneof"), + _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), } } From e5ba80a87c54ab7770d9c300dacd0976f74e563e Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 15:36:30 +0300 Subject: [PATCH 10/21] use const --- src/libstd/sys/wasi/thread.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index f9e2433dca064..a6c8f2487013b 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -30,8 +30,10 @@ impl Thread { let nanos = dur.as_nanos(); assert!(nanos <= u64::max_value() as u128); + const CLOCK_ID: wasi::Userdata = 0x0123_45678; + let clock = wasi::raw::__wasi_subscription_u_clock_t { - identifier: 0x0123_45678, + identifier: CLOCK_ID, clock_id: wasi::CLOCK_MONOTONIC, timeout: nanos as u64, precision: 0, @@ -47,7 +49,7 @@ impl Thread { let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { - (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} + (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), } } From c05237686f994144f2f0bae68dc5b337b06e9a97 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 19 Aug 2019 16:01:21 +0300 Subject: [PATCH 11/21] fix --- src/libstd/sys/wasi/args.rs | 2 +- src/libstd/sys/wasi/os.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 23ab2051bf6f6..14aa391912ed2 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -19,7 +19,7 @@ pub struct Args { /// Returns the command line arguments pub fn args() -> Args { Args { - iter: wasi::get_args().unwrap_or(Vec::new()), + iter: wasi::get_args().unwrap_or(Vec::new()).into_iter(), _dont_send_or_sync_me: PhantomData } } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 65c80c838dc82..04eee3ef28ff1 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -75,7 +75,7 @@ pub fn current_exe() -> io::Result { } pub struct Env { - iter: Vec>, + iter: vec::IntoIter>, _dont_send_or_sync_me: PhantomData<*mut ()>, } @@ -100,7 +100,7 @@ impl Iterator for Env { pub fn env() -> Env { Env { - iter: wasi::get_environ().unwrap_or(Vec::new()), + iter: wasi::get_environ().unwrap_or(Vec::new()).into_iter(), _dont_send_or_sync_me: PhantomData, } } From 744442d19a76c4dd39f5fa2a2bbd74638e8569ec Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 20 Aug 2019 15:43:34 +0300 Subject: [PATCH 12/21] fix C incompatibilities --- src/libstd/sys/wasi/mod.rs | 2 +- src/libstd/sys/wasi/os.rs | 67 ++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 0a16c29e5af53..28b49996d1433 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -83,7 +83,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize { } pub unsafe fn abort_internal() -> ! { - wasi::proc_exit(127) + libc::abort() } pub fn hashmap_random_keys() -> (u64, u64) { diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 04eee3ef28ff1..dca58179e0c8d 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -21,11 +21,24 @@ pub unsafe fn env_lock() -> impl Any { } pub fn errno() -> i32 { - 0 + extern { + #[thread_local] + static errno: libc::c_int; + } + + unsafe { errno as i32 } } pub fn error_string(errno: i32) -> String { - wasi::error_string(errno) + let mut buf = [0 as libc::c_char; 1024]; + + let p = buf.as_mut_ptr(); + unsafe { + 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() + } } pub fn getcwd() -> io::Result { @@ -73,35 +86,45 @@ impl StdError for JoinPathsError { pub fn current_exe() -> io::Result { unsupported() } - pub struct Env { - iter: vec::IntoIter>, + iter: vec::IntoIter<(OsString, OsString)>, _dont_send_or_sync_me: PhantomData<*mut ()>, } impl Iterator for Env { type Item = (OsString, OsString); - fn next(&mut self) -> Option<(OsString, OsString)> { - self.iter.next().and_then(|input| { - // See src/libstd/sys/unix/os.rs, same as that - if input.is_empty() { - return None; - } - let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); - pos.map(|p| ( - OsStringExt::from_vec(input[..p].to_vec()), - OsStringExt::from_vec(input[p+1..].to_vec()), - )) - }) - } + fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } pub fn env() -> Env { - Env { - iter: wasi::get_environ().unwrap_or(Vec::new()).into_iter(), - _dont_send_or_sync_me: PhantomData, + unsafe { + let _guard = env_lock(); + let mut environ = libc::environ; + let mut result = Vec::new(); + while environ != ptr::null_mut() && *environ != ptr::null_mut() { + if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) { + result.push(key_value); + } + environ = environ.offset(1); + } + return Env { + iter: result.into_iter(), + _dont_send_or_sync_me: PhantomData, + } + } + + // See src/libstd/sys/unix/os.rs, same as that + fn parse(input: &[u8]) -> Option<(OsString, OsString)> { + if input.is_empty() { + return None; + } + let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1); + pos.map(|p| ( + OsStringExt::from_vec(input[..p].to_vec()), + OsStringExt::from_vec(input[p+1..].to_vec()), + )) } } @@ -147,7 +170,9 @@ pub fn home_dir() -> Option { } pub fn exit(code: i32) -> ! { - unsafe { wasi::proc_exit(code as u32) } + unsafe { + libc::exit(code) + } } pub fn getpid() -> u32 { From 4dee102a67466ca0c95f540aa458f8779f3a1cb5 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Tue, 20 Aug 2019 19:16:01 +0300 Subject: [PATCH 13/21] use new get_args --- src/libstd/sys/wasi/args.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 14aa391912ed2..2d0ddea385afd 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -12,14 +12,16 @@ pub unsafe fn cleanup() { } pub struct Args { - iter: vec::IntoIter>, + iter: vec::IntoIter, _dont_send_or_sync_me: PhantomData<*mut ()>, } /// Returns the command line arguments pub fn args() -> Args { + let mut buf = Vec::new(); + let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec()))); Args { - iter: wasi::get_args().unwrap_or(Vec::new()).into_iter(), + iter: buf.into_iter(), _dont_send_or_sync_me: PhantomData } } @@ -33,7 +35,7 @@ impl Args { impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - self.iter.next().map(OsString::from_vec) + self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() From 88fd9450aa2111fcbe981006a9c391d57775ec14 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 04:16:05 +0300 Subject: [PATCH 14/21] update args --- src/libstd/sys/wasi/args.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index 2d0ddea385afd..de9ca62469d5d 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -18,8 +18,14 @@ pub struct Args { /// Returns the command line arguments pub fn args() -> Args { - let mut buf = Vec::new(); - let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec()))); + let buf = wasi::args_sizes_get().and_then(|args_sizes| { + let mut buf = Vec::with_capacity(args_sizes.get_count()); + wasi::get_args(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 From a47e3c077cd7f201dbbf12140c12663df0fcda6f Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 17:57:22 +0300 Subject: [PATCH 15/21] fixes --- src/libstd/sys/wasi/args.rs | 6 +-- src/libstd/sys/wasi/ext/fs.rs | 2 + src/libstd/sys/wasi/ext/io.rs | 2 +- src/libstd/sys/wasi/fd.rs | 76 +++++++++++++++++------------------ src/libstd/sys/wasi/fs.rs | 16 +++----- src/libstd/sys/wasi/io.rs | 2 +- src/libstd/sys/wasi/mod.rs | 27 +++++++------ src/libstd/sys/wasi/os.rs | 2 - src/libstd/sys/wasi/stdio.rs | 4 +- src/libstd/sys/wasi/thread.rs | 3 +- src/libstd/sys/wasi/time.rs | 3 +- 11 files changed, 69 insertions(+), 74 deletions(-) diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs index de9ca62469d5d..3280c4990dc66 100644 --- a/src/libstd/sys/wasi/args.rs +++ b/src/libstd/sys/wasi/args.rs @@ -1,10 +1,10 @@ -use crate::ffi::CStr; -use crate::io; 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) { } @@ -20,7 +20,7 @@ pub struct Args { pub fn args() -> Args { let buf = wasi::args_sizes_get().and_then(|args_sizes| { let mut buf = Vec::with_capacity(args_sizes.get_count()); - wasi::get_args(args_sizes, |arg| { + wasi::args_get(args_sizes, |arg| { let arg = OsString::from_vec(arg.to_vec()); buf.push(arg); })?; diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs index ecd509f01dabd..9fa4abfd171b5 100644 --- a/src/libstd/sys/wasi/ext/fs.rs +++ b/src/libstd/sys/wasi/ext/fs.rs @@ -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 diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs index c843144f0c406..f1839df380112 100644 --- a/src/libstd/sys/wasi/ext/io.rs +++ b/src/libstd/sys/wasi/ext/io.rs @@ -8,7 +8,7 @@ use crate::sys; use crate::net; use crate::sys_common::{AsInner, FromInner, IntoInner}; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; /// Raw file descriptors. pub type RawFd = u32; diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 93fe8add326c8..275e1319be6ad 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -3,14 +3,15 @@ use crate::io::{self, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; use crate::net::Shutdown; -use wasi::wasi_unstable as wasi; +use super::err2io; +use ::wasi::wasi_unstable as wasi; #[derive(Debug)] pub struct WasiFd { fd: wasi::Fd, } -fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] { +fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::IoVec] { assert_eq!( mem::size_of::>(), mem::size_of::() @@ -23,7 +24,7 @@ fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] { unsafe { mem::transmute(a) } } -fn ciovec(a: &[IoSlice<'_>]) -> &[wasi::CIoVec] { +fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::CIoVec] { assert_eq!( mem::size_of::>(), mem::size_of::() @@ -52,23 +53,23 @@ impl WasiFd { } pub fn datasync(&self) -> io::Result<()> { - wasi::fd_datasync(self.fd).map_err(From::from) + wasi::fd_datasync(self.fd).map_err(err2io) } pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(From::from) + wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) } pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(From::from) + wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) } pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - wasi::fd_read(self.fd, iovec(bufs)).map_err(From::from) + wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) } pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - wasi::fd_write(self.fd, ciovec(bufs)).map_err(From::from) + wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) } pub fn seek(&self, pos: SeekFrom) -> io::Result { @@ -77,37 +78,37 @@ impl WasiFd { SeekFrom::End(pos) => (wasi::WHENCE_END, pos), SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos), }; - wasi::fd_seek(self.fd, offset, whence).map_err(From::from) + wasi::fd_seek(self.fd, offset, whence).map_err(err2io) } pub fn tell(&self) -> io::Result { - wasi::fd_tell(self.fd).map_err(From::from) + wasi::fd_tell(self.fd).map_err(err2io) } // FIXME: __wasi_fd_fdstat_get pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> { - wasi::fd_fdstat_set_flags(self.fd, flags).map_err(From::from) + wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) } pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> { - wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(From::from) + wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) } pub fn sync(&self) -> io::Result<()> { - wasi::fd_sync(self.fd).map_err(From::from) + wasi::fd_sync(self.fd).map_err(err2io) } pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> { - wasi::fd_advise(self.fd, offset, len, advice).map_err(From::from) + wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) } pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - wasi::fd_allocate(self.fd, offset, len).map_err(From::from) + wasi::fd_allocate(self.fd, offset, len).map_err(err2io) } pub fn create_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_create_directory(self.fd, path).map_err(From::from) + wasi::path_create_directory(self.fd, path).map_err(err2io) } pub fn link( @@ -118,7 +119,7 @@ impl WasiFd { new_path: &[u8], ) -> io::Result<()> { wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) - .map_err(From::from) + .map_err(err2io) } pub fn open( @@ -130,7 +131,7 @@ impl WasiFd { fs_rights_inheriting: wasi::Rights, fs_flags: wasi::FdFlags, ) -> io::Result { - let fd = wasi_path_open( + wasi::path_open( self.fd, dirflags, path, @@ -138,25 +139,24 @@ impl WasiFd { fs_rights_base, fs_rights_inheriting, fs_flags, - )?; - Ok(WasiFd::from_raw(fd)) + ).map(|fd| unsafe { WasiFd::from_raw(fd) }).map_err(err2io) } pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { - wasi::fd_readdir(self.fd, buf, cookie).map_err(From::from) + wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) } pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { - wasi::path_readlink(self.fd, path, buf).map_err(From::from) + 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<()> { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path) - .map_err(From::from) + .map_err(err2io) } - pub fn filestat_get(&self) -> io::Result { - wasi::fd_filestat_get(self.fd, buf).map_err(From::from) + pub fn filestat_get(&self) -> io::Result { + wasi::fd_filestat_get(self.fd).map_err(err2io) } pub fn filestat_set_times( @@ -166,11 +166,11 @@ impl WasiFd { fstflags: wasi::FstFlags, ) -> io::Result<()> { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags) - .map_err(From::from) + .map_err(err2io) } pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - wasi::fd_filestat_set_size(self.fd, size).map_err(From::from) + wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) } pub fn path_filestat_get( @@ -178,7 +178,7 @@ impl WasiFd { flags: wasi::LookupFlags, path: &[u8], ) -> io::Result { - wasi::path_filestat_get(self.fd, flags, path).map_err(From::from) + wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) } pub fn path_filestat_set_times( @@ -196,19 +196,19 @@ impl WasiFd { atim, mtim, fstflags, - ).map_err(From::from) + ).map_err(err2io) } pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> { - wasi::path_symlink(old_path, self.fd, new_path).map_err(From::from) + wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) } pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { - wasi::path_unlink_file(self.fd, path).map_err(From::from) + wasi::path_unlink_file(self.fd, path).map_err(err2io) } pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_remove_directory(self.fd, path).map_err(From::from) + wasi::path_remove_directory(self.fd, path).map_err(err2io) } pub fn sock_recv( @@ -216,20 +216,20 @@ impl WasiFd { ri_data: &mut [IoSliceMut<'_>], ri_flags: wasi::RiFlags, ) -> io::Result<(usize, wasi::RoFlags)> { - wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(From::from) + wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) } pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result { - wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(From::from) + 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 => WASI::SHUT_RD, - Shutdown::Write => WASI::SHUT_WR, - Shutdown::Both => WASI::SHUT_WR | WASI::SHUT_RD, + Shutdown::Read => wasi::SHUT_RD, + Shutdown::Write => wasi::SHUT_WR, + Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD, }; - wasi::sock_shutdown(self.fd, how).map_err(From::from) + wasi::sock_shutdown(self.fd, how).map_err(err2io) } } diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index f23ecfc2bcd22..4113f6a2e09c0 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -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,7 +15,7 @@ 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; +use ::wasi::wasi_unstable as wasi; pub struct File { fd: WasiFd, @@ -28,7 +28,7 @@ pub struct FileAttr { pub struct ReadDir { inner: Arc, - cookie: Option, + cookie: Option, buf: Vec, offset: usize, cap: usize, @@ -70,12 +70,6 @@ pub struct FileType { pub struct DirBuilder {} impl FileAttr { - fn zero() -> FileAttr { - FileAttr { - meta: unsafe { mem::zeroed() }, - } - } - pub fn size(&self) -> u64 { self.meta.st_size } @@ -390,7 +384,7 @@ impl File { } pub fn file_attr(&self) -> io::Result { - self.fd.filestat_get().map_ok(|meta| FileAttr { meta }) + self.fd.filestat_get().map(|meta| FileAttr { meta }) } pub fn metadata_at( @@ -601,7 +595,7 @@ fn metadata_at( path: &Path, ) -> io::Result { fd.path_filestat_get(flags, path.as_os_str().as_bytes()) - .map_ok(|meta| FileAttr { meta }) + .map(|meta| FileAttr { meta }) } pub fn canonicalize(_p: &Path) -> io::Result { diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs index ebea3a03e439f..4be92faed308f 100644 --- a/src/libstd/sys/wasi/io.rs +++ b/src/libstd/sys/wasi/io.rs @@ -1,7 +1,7 @@ use crate::marker::PhantomData; use crate::slice; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; use core::ffi::c_void; #[repr(transparent)] diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 28b49996d1433..89f7c887aafc0 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -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 crate::io; +use crate::io as std_io; use crate::mem; use crate::os::raw::c_char; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; pub mod alloc; pub mod args; @@ -56,16 +56,19 @@ pub mod ext; pub fn init() { } -pub fn unsupported() -> crate::io::Result { +pub fn unsupported() -> std_io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> io::Error { - io::Error::new(io::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(_code: i32) -> io::ErrorKind { - io::ErrorKind::Other +pub fn decode_error_kind(_code: i32) -> std_io::ErrorKind { + std_io::ErrorKind::Other } // This enum is used as the storage for a bunch of types which can't actually @@ -114,16 +117,14 @@ macro_rules! impl_is_minus_one { impl_is_minus_one! { i8 i16 i32 i64 isize } -pub fn cvt(t: T) -> crate::io::Result { +pub fn cvt(t: T) -> std_io::Result { if t.is_minus_one() { - Err(io::Error::last_os_error()) + Err(std_io::Error::last_os_error()) } else { Ok(t) } } -impl From for io::Error { - fn from(err: wasi::Error) -> Self { - Self::from_raw_os_error(err as i32) - } +fn err2io(err: wasi::Error) -> std_io::Error { + std_io::Error::from_raw_os_error(err.get() as i32) } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index dca58179e0c8d..7ee23c9a35ec7 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -12,8 +12,6 @@ use crate::sys::memchr; use crate::sys::{cvt, unsupported, Void}; use crate::vec; -use wasi::wasi_unstable as wasi; - #[cfg(not(target_feature = "atomics"))] pub unsafe fn env_lock() -> impl Any { // No need for a lock if we're single-threaded, but this function will need diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs index dc6a6ef375a1c..1d57b9922e599 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -2,7 +2,7 @@ use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::sys::fd::WasiFd; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; pub struct Stdin; pub struct Stdout; @@ -74,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(wasi::EBADF as i32) + err.raw_os_error() == Some(wasi::EBADF.get() as i32) } pub fn panic_output() -> Option { diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index a6c8f2487013b..dc5a72e82a354 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -1,10 +1,11 @@ -use crate::cmp; use crate::ffi::CStr; use crate::io; use crate::mem; use crate::sys::{unsupported, Void}; use crate::time::Duration; +use ::wasi::wasi_unstable as wasi; + pub struct Thread(Void); pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs index 4c89a1781b9ef..4394a22f9c233 100644 --- a/src/libstd/sys/wasi/time.rs +++ b/src/libstd/sys/wasi/time.rs @@ -1,6 +1,5 @@ use crate::time::Duration; -use crate::mem; -use wasi::wasi_unstable as wasi; +use ::wasi::wasi_unstable as wasi; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Instant(Duration); From 926f36400f1667edec92959d8b640dea5084674c Mon Sep 17 00:00:00 2001 From: newpavlov Date: Wed, 21 Aug 2019 19:36:12 +0300 Subject: [PATCH 16/21] move cvt --- src/libstd/Cargo.toml | 1 + src/libstd/sys/wasi/mod.rs | 23 ----------------------- src/libstd/sys/wasi/os.rs | 25 ++++++++++++++++++++++++- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index bb77a5bdea493..d801b051357a4 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,6 +24,7 @@ compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } +wasi = { git = "https://github.com/newpavlov/rust-wasi", branch = "safe_rework", features = ['rustc-dep-of-std', 'alloc'] } [dependencies.backtrace] version = "0.3.35" diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 89f7c887aafc0..f87e4d16fcdac 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -102,29 +102,6 @@ pub fn hashmap_random_keys() -> (u64, u64) { 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: T) -> std_io::Result { - if t.is_minus_one() { - Err(std_io::Error::last_os_error()) - } else { - Ok(t) - } -} - fn err2io(err: wasi::Error) -> std_io::Error { std_io::Error::from_raw_os_error(err.get() as i32) } diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs index 7ee23c9a35ec7..feee840782550 100644 --- a/src/libstd/sys/wasi/os.rs +++ b/src/libstd/sys/wasi/os.rs @@ -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"))] @@ -176,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: T) -> io::Result { + if t.is_minus_one() { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} From 6374b8458f0796a1ff3ee2caec41321e801c35d1 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Thu, 29 Aug 2019 20:13:15 +0300 Subject: [PATCH 17/21] update to wasi v0.7 --- Cargo.lock | 12 ++++ src/libstd/Cargo.toml | 2 +- src/libstd/sys/wasi/fd.rs | 104 ++++++++++++++++++---------------- src/libstd/sys/wasi/mod.rs | 13 ++++- src/libstd/sys/wasi/thread.rs | 2 +- 5 files changed, 80 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ae21c8663706..3719b36236797 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,6 +3866,7 @@ dependencies = [ "rustc_msan", "rustc_tsan", "unwind", + "wasi", ] [[package]] @@ -4664,6 +4665,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" diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index d801b051357a4..0d04b7a274037 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,7 +24,7 @@ compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } -wasi = { git = "https://github.com/newpavlov/rust-wasi", branch = "safe_rework", features = ['rustc-dep-of-std', 'alloc'] } +wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } [dependencies.backtrace] version = "0.3.35" diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 275e1319be6ad..5b7a8678b66ea 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -53,23 +53,23 @@ impl WasiFd { } pub fn datasync(&self) -> io::Result<()> { - wasi::fd_datasync(self.fd).map_err(err2io) + unsafe { wasi::fd_datasync(self.fd).map_err(err2io) } } pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) + unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) } } pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) + unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) } } pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) + unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) } } pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) + unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) } } pub fn seek(&self, pos: SeekFrom) -> io::Result { @@ -78,37 +78,37 @@ impl WasiFd { SeekFrom::End(pos) => (wasi::WHENCE_END, pos), SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos), }; - wasi::fd_seek(self.fd, offset, whence).map_err(err2io) + unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) } } pub fn tell(&self) -> io::Result { - wasi::fd_tell(self.fd).map_err(err2io) + unsafe { wasi::fd_tell(self.fd).map_err(err2io) } } // FIXME: __wasi_fd_fdstat_get pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> { - wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) + unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) } } pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> { - wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) + unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) } } pub fn sync(&self) -> io::Result<()> { - wasi::fd_sync(self.fd).map_err(err2io) + unsafe { wasi::fd_sync(self.fd).map_err(err2io) } } pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> { - wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) + unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) } } pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - wasi::fd_allocate(self.fd, offset, len).map_err(err2io) + unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) } } pub fn create_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_create_directory(self.fd, path).map_err(err2io) + unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) } } pub fn link( @@ -118,8 +118,10 @@ impl WasiFd { new_fd: &WasiFd, new_path: &[u8], ) -> io::Result<()> { - wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) - .map_err(err2io) + unsafe { + wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) + .map_err(err2io) + } } pub fn open( @@ -131,32 +133,35 @@ impl WasiFd { fs_rights_inheriting: wasi::Rights, fs_flags: wasi::FdFlags, ) -> io::Result { - wasi::path_open( - self.fd, - dirflags, - path, - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - ).map(|fd| unsafe { WasiFd::from_raw(fd) }).map_err(err2io) + unsafe { + wasi::path_open( + self.fd, + dirflags, + path, + oflags, + fs_rights_base, + fs_rights_inheriting, + fs_flags, + ).map(|fd| WasiFd::from_raw(fd)).map_err(err2io) + } } pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { - wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) + unsafe { wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) } } pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { - wasi::path_readlink(self.fd, path, buf).map_err(err2io) + 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<()> { - wasi::path_rename(self.fd, old_path, new_fd.fd, new_path) - .map_err(err2io) + unsafe { + wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) + } } pub fn filestat_get(&self) -> io::Result { - wasi::fd_filestat_get(self.fd).map_err(err2io) + unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) } } pub fn filestat_set_times( @@ -165,12 +170,13 @@ impl WasiFd { mtim: wasi::Timestamp, fstflags: wasi::FstFlags, ) -> io::Result<()> { - wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags) - .map_err(err2io) + unsafe { + wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) + } } pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) + unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) } } pub fn path_filestat_get( @@ -178,7 +184,7 @@ impl WasiFd { flags: wasi::LookupFlags, path: &[u8], ) -> io::Result { - wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) + unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) } } pub fn path_filestat_set_times( @@ -189,26 +195,28 @@ impl WasiFd { mtim: wasi::Timestamp, fstflags: wasi::FstFlags, ) -> io::Result<()> { - wasi::path_filestat_set_times( - self.fd, - flags, - path, - atim, - mtim, - fstflags, - ).map_err(err2io) + unsafe { + wasi::path_filestat_set_times( + self.fd, + flags, + path, + atim, + mtim, + fstflags, + ).map_err(err2io) + } } pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> { - wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) + unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) } } pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { - wasi::path_unlink_file(self.fd, path).map_err(err2io) + unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) } } pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { - wasi::path_remove_directory(self.fd, path).map_err(err2io) + unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) } } pub fn sock_recv( @@ -216,11 +224,11 @@ impl WasiFd { ri_data: &mut [IoSliceMut<'_>], ri_flags: wasi::RiFlags, ) -> io::Result<(usize, wasi::RoFlags)> { - wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) + unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) } } pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result { - wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) + unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) } } pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> { @@ -229,7 +237,7 @@ impl WasiFd { Shutdown::Write => wasi::SHUT_WR, Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD, }; - wasi::sock_shutdown(self.fd, how).map_err(err2io) + unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) } } } @@ -237,6 +245,6 @@ impl Drop for WasiFd { fn drop(&mut self) { // FIXME: can we handle the return code here even though we can't on // unix? - let _ = wasi::fd_close(self.fd); + let _ = unsafe { wasi::fd_close(self.fd) }; } } diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 4007b7ac0ec5f..517e3be9cb58c 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -69,10 +69,17 @@ pub fn unsupported_err() -> std_io::Error { pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { use std_io::ErrorKind::*; - match errno as libc::c_int { + 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 | libc::EACCES => PermissionDenied, + wasi::EPERM | wasi::EACCES => PermissionDenied, wasi::EPIPE => BrokenPipe, wasi::ENOTCONN => NotConnected, wasi::ECONNABORTED => ConnectionAborted, @@ -84,7 +91,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { wasi::ETIMEDOUT => TimedOut, wasi::EEXIST => AlreadyExists, wasi::EAGAIN => WouldBlock, - _ => ErrorKind::Other, + _ => Other, } } diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index dc5a72e82a354..987bf7580838b 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -47,7 +47,7 @@ impl Thread { u: wasi::raw::__wasi_subscription_u { clock: clock }, }]; let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }]; - let n = wasi::poll_oneoff(&in_, &mut out).unwrap(); + let n = unsafe { wasi::poll_oneoff(&in_, &mut out).unwrap() }; let wasi::Event { userdata, error, type_, .. } = out[0]; match (n, userdata, error) { (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {} From 06acfb22e03ff482275e1ffd78f691b0e5d88ffb Mon Sep 17 00:00:00 2001 From: newpavlov Date: Thu, 29 Aug 2019 20:22:24 +0300 Subject: [PATCH 18/21] add wasi license to the licenses whitelist --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index e07a07234c71e..6ca912db5930d 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -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", From 127311b75efd47a6f54aca49523c050566fc9823 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 29 Aug 2019 18:08:13 +0000 Subject: [PATCH 19/21] whitelist wasi crate --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 6ca912db5930d..c31da3c6f4887 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -172,6 +172,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("vcpkg"), Crate("version_check"), Crate("void"), + Crate("wasi"), Crate("winapi"), Crate("winapi-build"), Crate("winapi-i686-pc-windows-gnu"), From 9fd203a01e0fe6fb307809fdfdbfcd3bda350cfc Mon Sep 17 00:00:00 2001 From: newpavlov Date: Fri, 30 Aug 2019 17:30:33 +0300 Subject: [PATCH 20/21] simplify code --- src/libstd/sys/wasi/thread.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 987bf7580838b..28a504f197974 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -46,11 +46,18 @@ impl Thread { type_: wasi::EVENTTYPE_CLOCK, u: wasi::raw::__wasi_subscription_u { clock: clock }, }]; - let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }]; - let n = unsafe { wasi::poll_oneoff(&in_, &mut out).unwrap() }; - let wasi::Event { userdata, error, type_, .. } = out[0]; - match (n, userdata, error) { - (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_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"), } } From 0662fcf4f950ec2800f0b1e02254ef2389b55079 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 3 Sep 2019 14:37:53 +0000 Subject: [PATCH 21/21] make wasi a target-specific dependency --- src/libstd/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 0d04b7a274037..173bcea0846a0 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -24,7 +24,6 @@ compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] } -wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } [dependencies.backtrace] version = "0.3.35" @@ -57,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"