From 410af0f2477e2744ca4b3cf2a3b68b3aa9ac3350 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Tue, 7 Jan 2020 11:37:12 +0000 Subject: [PATCH] add more wasi patches --- debian/patches/series | 2 + debian/patches/u-wasm32-66750.patch | 1522 +++++++++++++++++++++++++++ debian/patches/u-wasm32-67267.patch | 123 +++ 3 files changed, 1647 insertions(+) create mode 100644 debian/patches/u-wasm32-66750.patch create mode 100644 debian/patches/u-wasm32-67267.patch diff --git a/debian/patches/series b/debian/patches/series index 17766833b6..00878cdfda 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -21,6 +21,8 @@ u-riscv64-cc-430.patch u-riscv64-cc-460.patch u-riscv64-cc-461.patch u-riscv64-cc-465.patch +u-wasm32-66750.patch +u-wasm32-67267.patch u-wasm32-libc-1625.patch # TODO: forward this one u-riscv64-compiletest.patch diff --git a/debian/patches/u-wasm32-66750.patch b/debian/patches/u-wasm32-66750.patch new file mode 100644 index 0000000000..43bbc7b91a --- /dev/null +++ b/debian/patches/u-wasm32-66750.patch @@ -0,0 +1,1522 @@ +commit f3fb1c5e95b9fef29df00f0924a27790b03c524b +Author: Alex Crichton +Date: Mon Nov 25 09:27:25 2019 -0800 + + Update the `wasi` crate for `wasm32-wasi` + + This commit updates the `wasi` crate used by the standard library which + is used to implement most of the functionality of libstd on the + `wasm32-wasi` target. This update comes with a brand new crate structure + in the `wasi` crate which caused quite a few changes for the wasi target + here, but it also comes with a significant change to where the + functionality is coming from. + + The WASI specification is organized into "snapshots" and a new snapshot + happened recently, so the WASI APIs themselves have changed since the + previous revision. This had only minor impact on the public facing + surface area of libstd, only changing on `u32` to a `u64` in an unstable + API. The actual source for all of these types and such, however, is now + coming from the `wasi_preview_snapshot1` module instead of the + `wasi_unstable` module like before. This means that any implementors + generating binaries will need to ensure that their embedding environment + handles the `wasi_preview_snapshot1` module. + +diff --git a/Cargo.lock b/Cargo.lock +index 8fd0285a7e6..5a56bf03f4d 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -1294,7 +1294,7 @@ checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" + dependencies = [ + "cfg-if", + "libc", +- "wasi", ++ "wasi 0.7.0", + ] + + [[package]] +@@ -4301,7 +4301,7 @@ dependencies = [ + "rustc_msan", + "rustc_tsan", + "unwind", +- "wasi", ++ "wasi 0.9.0+wasi-snapshot-preview1", + ] + + [[package]] +@@ -5172,6 +5172,12 @@ name = "wasi" + version = "0.7.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" ++ ++[[package]] ++name = "wasi" ++version = "0.9.0+wasi-snapshot-preview1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", +diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml +index c55911a33f5..a22e162bbff 100644 +--- a/src/libstd/Cargo.toml ++++ b/src/libstd/Cargo.toml +@@ -54,7 +54,7 @@ fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] } + hermit-abi = { version = "0.1", features = ['rustc-dep-of-std'] } + + [target.wasm32-wasi.dependencies] +-wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] } ++wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features = false } + + [features] + default = ["std_detect_file_io", "std_detect_dlsym_getauxval"] +diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs +index 3280c4990dc..3db36f5e132 100644 +--- a/src/libstd/sys/wasi/args.rs ++++ b/src/libstd/sys/wasi/args.rs +@@ -1,15 +1,11 @@ +-use crate::ffi::OsString; ++use crate::ffi::{CStr, OsStr, OsString}; + use crate::marker::PhantomData; +-use crate::os::wasi::ffi::OsStringExt; ++use crate::os::wasi::ffi::OsStrExt; + use crate::vec; + +-use ::wasi::wasi_unstable as wasi; ++pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} + +-pub unsafe fn init(_argc: isize, _argv: *const *const u8) { +-} +- +-pub unsafe fn cleanup() { +-} ++pub unsafe fn cleanup() {} + + pub struct Args { + iter: vec::IntoIter, +@@ -18,17 +14,24 @@ pub struct Args { + + /// Returns the command line arguments + 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::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 ++ iter: maybe_args().unwrap_or(Vec::new()).into_iter(), ++ _dont_send_or_sync_me: PhantomData, ++ } ++} ++ ++fn maybe_args() -> Option> { ++ unsafe { ++ let (argc, buf_size) = wasi::args_sizes_get().ok()?; ++ let mut argv = Vec::with_capacity(argc); ++ let mut buf = Vec::with_capacity(buf_size); ++ wasi::args_get(argv.as_mut_ptr(), buf.as_mut_ptr()).ok()?; ++ let mut ret = Vec::with_capacity(argc); ++ for ptr in argv { ++ let s = CStr::from_ptr(ptr.cast()); ++ ret.push(OsStr::from_bytes(s.to_bytes()).to_owned()); ++ } ++ Some(ret) + } + } + +diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs +index 9fa4abfd171..92d0e60c07e 100644 +--- a/src/libstd/sys/wasi/ext/fs.rs ++++ b/src/libstd/sys/wasi/ext/fs.rs +@@ -4,12 +4,10 @@ + + use crate::fs::{self, File, Metadata, OpenOptions}; + use crate::io::{self, IoSlice, IoSliceMut}; +-use crate::os::wasi::ffi::OsStrExt; + use crate::path::{Path, PathBuf}; ++use crate::sys::fs::osstr2str; + use crate::sys_common::{AsInner, AsInnerMut, FromInner}; + +-use ::wasi::wasi_unstable as wasi; +- + /// WASI-specific extensions to [`File`]. + /// + /// [`File`]: ../../../../std/fs/struct.File.html +@@ -49,62 +47,62 @@ pub trait FileExt { + + /// Returns the current position within the file. + /// +- /// This corresponds to the `__wasi_fd_tell` syscall and is similar to ++ /// This corresponds to the `fd_tell` syscall and is similar to + /// `seek` where you offset 0 bytes from the current position. + fn tell(&self) -> io::Result; + + /// Adjust the flags associated with this file. + /// +- /// This corresponds to the `__wasi_fd_fdstat_set_flags` syscall. ++ /// This corresponds to the `fd_fdstat_set_flags` syscall. + fn fdstat_set_flags(&self, flags: u16) -> io::Result<()>; + + /// Adjust the rights associated with this file. + /// +- /// This corresponds to the `__wasi_fd_fdstat_set_rights` syscall. ++ /// This corresponds to the `fd_fdstat_set_rights` syscall. + fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()>; + + /// Provide file advisory information on a file descriptor. + /// +- /// This corresponds to the `__wasi_fd_advise` syscall. ++ /// This corresponds to the `fd_advise` syscall. + fn advise(&self, offset: u64, len: u64, advice: u8) -> io::Result<()>; + + /// Force the allocation of space in a file. + /// +- /// This corresponds to the `__wasi_fd_allocate` syscall. ++ /// This corresponds to the `fd_allocate` syscall. + fn allocate(&self, offset: u64, len: u64) -> io::Result<()>; + + /// Create a directory. + /// +- /// This corresponds to the `__wasi_path_create_directory` syscall. ++ /// This corresponds to the `path_create_directory` syscall. + fn create_directory>(&self, dir: P) -> io::Result<()>; + + /// Read the contents of a symbolic link. + /// +- /// This corresponds to the `__wasi_path_readlink` syscall. ++ /// This corresponds to the `path_readlink` syscall. + fn read_link>(&self, path: P) -> io::Result; + + /// Return the attributes of a file or directory. + /// +- /// This corresponds to the `__wasi_path_filestat_get` syscall. ++ /// This corresponds to the `path_filestat_get` syscall. + fn metadata_at>(&self, lookup_flags: u32, path: P) -> io::Result; + + /// Unlink a file. + /// +- /// This corresponds to the `__wasi_path_unlink_file` syscall. ++ /// This corresponds to the `path_unlink_file` syscall. + fn remove_file>(&self, path: P) -> io::Result<()>; + + /// Remove a directory. + /// +- /// This corresponds to the `__wasi_path_remove_directory` syscall. ++ /// This corresponds to the `path_remove_directory` syscall. + fn remove_directory>(&self, path: P) -> io::Result<()>; + } + +-// FIXME: bind __wasi_fd_fdstat_get - need to define a custom return type +-// FIXME: bind __wasi_fd_readdir - can't return `ReadDir` since we only have entry name +-// FIXME: bind __wasi_fd_filestat_set_times maybe? - on crates.io for unix +-// FIXME: bind __wasi_path_filestat_set_times maybe? - on crates.io for unix +-// FIXME: bind __wasi_poll_oneoff maybe? - probably should wait for I/O to settle +-// FIXME: bind __wasi_random_get maybe? - on crates.io for unix ++// FIXME: bind fd_fdstat_get - need to define a custom return type ++// FIXME: bind fd_readdir - can't return `ReadDir` since we only have entry name ++// FIXME: bind fd_filestat_set_times maybe? - on crates.io for unix ++// FIXME: bind path_filestat_set_times maybe? - on crates.io for unix ++// FIXME: bind poll_oneoff maybe? - probably should wait for I/O to settle ++// FIXME: bind random_get maybe? - on crates.io for unix + + impl FileExt for fs::File { + fn read_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { +@@ -136,9 +134,7 @@ impl FileExt for fs::File { + } + + fn create_directory>(&self, dir: P) -> io::Result<()> { +- self.as_inner() +- .fd() +- .create_directory(dir.as_ref().as_os_str().as_bytes()) ++ self.as_inner().fd().create_directory(osstr2str(dir.as_ref().as_ref())?) + } + + fn read_link>(&self, path: P) -> io::Result { +@@ -151,15 +147,11 @@ impl FileExt for fs::File { + } + + fn remove_file>(&self, path: P) -> io::Result<()> { +- self.as_inner() +- .fd() +- .unlink_file(path.as_ref().as_os_str().as_bytes()) ++ self.as_inner().fd().unlink_file(osstr2str(path.as_ref().as_ref())?) + } + + fn remove_directory>(&self, path: P) -> io::Result<()> { +- self.as_inner() +- .fd() +- .remove_directory(path.as_ref().as_os_str().as_bytes()) ++ self.as_inner().fd().remove_directory(osstr2str(path.as_ref().as_ref())?) + } + } + +@@ -167,10 +159,10 @@ impl FileExt for fs::File { + /// + /// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html + pub trait OpenOptionsExt { +- /// Pass custom `dirflags` argument to `__wasi_path_open`. ++ /// Pass custom `dirflags` argument to `path_open`. + /// + /// This option configures the `dirflags` argument to the +- /// `__wasi_path_open` syscall which `OpenOptions` will eventually call. The ++ /// `path_open` syscall which `OpenOptions` will eventually call. The + /// `dirflags` argument configures how the file is looked up, currently + /// primarily affecting whether symlinks are followed or not. + /// +@@ -188,31 +180,31 @@ pub trait OpenOptionsExt { + fn directory(&mut self, dir: bool) -> &mut Self; + + /// Indicates whether `__WASI_FDFLAG_DSYNC` is passed in the `fs_flags` +- /// field of `__wasi_path_open`. ++ /// field of `path_open`. + /// + /// This option is by default `false` + fn dsync(&mut self, dsync: bool) -> &mut Self; + + /// Indicates whether `__WASI_FDFLAG_NONBLOCK` is passed in the `fs_flags` +- /// field of `__wasi_path_open`. ++ /// field of `path_open`. + /// + /// This option is by default `false` + fn nonblock(&mut self, nonblock: bool) -> &mut Self; + + /// Indicates whether `__WASI_FDFLAG_RSYNC` is passed in the `fs_flags` +- /// field of `__wasi_path_open`. ++ /// field of `path_open`. + /// + /// This option is by default `false` + fn rsync(&mut self, rsync: bool) -> &mut Self; + + /// Indicates whether `__WASI_FDFLAG_SYNC` is passed in the `fs_flags` +- /// field of `__wasi_path_open`. ++ /// field of `path_open`. + /// + /// This option is by default `false` + fn sync(&mut self, sync: bool) -> &mut Self; + + /// Indicates the value that should be passed in for the `fs_rights_base` +- /// parameter of `__wasi_path_open`. ++ /// parameter of `path_open`. + /// + /// This option defaults based on the `read` and `write` configuration of + /// this `OpenOptions` builder. If this method is called, however, the +@@ -220,7 +212,7 @@ pub trait OpenOptionsExt { + fn fs_rights_base(&mut self, rights: u64) -> &mut Self; + + /// Indicates the value that should be passed in for the +- /// `fs_rights_inheriting` parameter of `__wasi_path_open`. ++ /// `fs_rights_inheriting` parameter of `path_open`. + /// + /// The default for this option is the same value as what will be passed + /// for the `fs_rights_base` parameter but if this method is called then +@@ -229,7 +221,7 @@ pub trait OpenOptionsExt { + + /// Open a file or directory. + /// +- /// This corresponds to the `__wasi_path_open` syscall. ++ /// This corresponds to the `path_open` syscall. + fn open_at>(&self, file: &File, path: P) -> io::Result; + } + +@@ -284,38 +276,38 @@ impl OpenOptionsExt for OpenOptions { + /// + /// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html + pub trait MetadataExt { +- /// Returns the `st_dev` field of the internal `__wasi_filestat_t` ++ /// Returns the `st_dev` field of the internal `filestat_t` + fn dev(&self) -> u64; +- /// Returns the `st_ino` field of the internal `__wasi_filestat_t` ++ /// Returns the `st_ino` field of the internal `filestat_t` + fn ino(&self) -> u64; +- /// Returns the `st_nlink` field of the internal `__wasi_filestat_t` +- fn nlink(&self) -> u32; +- /// Returns the `st_atim` field of the internal `__wasi_filestat_t` ++ /// Returns the `st_nlink` field of the internal `filestat_t` ++ fn nlink(&self) -> u64; ++ /// Returns the `st_atim` field of the internal `filestat_t` + fn atim(&self) -> u64; +- /// Returns the `st_mtim` field of the internal `__wasi_filestat_t` ++ /// Returns the `st_mtim` field of the internal `filestat_t` + fn mtim(&self) -> u64; +- /// Returns the `st_ctim` field of the internal `__wasi_filestat_t` ++ /// Returns the `st_ctim` field of the internal `filestat_t` + fn ctim(&self) -> u64; + } + + impl MetadataExt for fs::Metadata { + fn dev(&self) -> u64 { +- self.as_inner().as_wasi().st_dev ++ self.as_inner().as_wasi().dev + } + fn ino(&self) -> u64 { +- self.as_inner().as_wasi().st_ino ++ self.as_inner().as_wasi().ino + } +- fn nlink(&self) -> u32 { +- self.as_inner().as_wasi().st_nlink ++ fn nlink(&self) -> u64 { ++ self.as_inner().as_wasi().nlink + } + fn atim(&self) -> u64 { +- self.as_inner().as_wasi().st_atim ++ self.as_inner().as_wasi().atim + } + fn mtim(&self) -> u64 { +- self.as_inner().as_wasi().st_mtim ++ self.as_inner().as_wasi().mtim + } + fn ctim(&self) -> u64 { +- self.as_inner().as_wasi().st_ctim ++ self.as_inner().as_wasi().ctim + } + } + +@@ -355,7 +347,7 @@ impl FileTypeExt for fs::FileType { + /// + /// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html + pub trait DirEntryExt { +- /// Returns the underlying `d_ino` field of the `__wasi_dirent_t` ++ /// Returns the underlying `d_ino` field of the `dirent_t` + fn ino(&self) -> u64; + } + +@@ -367,7 +359,7 @@ impl DirEntryExt for fs::DirEntry { + + /// Create a hard link. + /// +-/// This corresponds to the `__wasi_path_link` syscall. ++/// This corresponds to the `path_link` syscall. + pub fn link, U: AsRef>( + old_fd: &File, + old_flags: u32, +@@ -377,15 +369,15 @@ pub fn link, U: AsRef>( + ) -> io::Result<()> { + old_fd.as_inner().fd().link( + old_flags, +- old_path.as_ref().as_os_str().as_bytes(), ++ osstr2str(old_path.as_ref().as_ref())?, + new_fd.as_inner().fd(), +- new_path.as_ref().as_os_str().as_bytes(), ++ osstr2str(new_path.as_ref().as_ref())?, + ) + } + + /// Rename a file or directory. + /// +-/// This corresponds to the `__wasi_path_rename` syscall. ++/// This corresponds to the `path_rename` syscall. + pub fn rename, U: AsRef>( + old_fd: &File, + old_path: P, +@@ -393,22 +385,21 @@ pub fn rename, U: AsRef>( + new_path: U, + ) -> io::Result<()> { + old_fd.as_inner().fd().rename( +- old_path.as_ref().as_os_str().as_bytes(), ++ osstr2str(old_path.as_ref().as_ref())?, + new_fd.as_inner().fd(), +- new_path.as_ref().as_os_str().as_bytes(), ++ osstr2str(new_path.as_ref().as_ref())?, + ) + } + + /// Create a symbolic link. + /// +-/// This corresponds to the `__wasi_path_symlink` syscall. ++/// This corresponds to the `path_symlink` syscall. + pub fn symlink, U: AsRef>( + old_path: P, + fd: &File, + new_path: U, + ) -> io::Result<()> { +- fd.as_inner().fd().symlink( +- old_path.as_ref().as_os_str().as_bytes(), +- new_path.as_ref().as_os_str().as_bytes(), +- ) ++ fd.as_inner() ++ .fd() ++ .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) + } +diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs +index f1839df3801..f678b71a2b9 100644 +--- a/src/libstd/sys/wasi/ext/io.rs ++++ b/src/libstd/sys/wasi/ext/io.rs +@@ -8,8 +8,6 @@ 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; + +@@ -127,18 +125,18 @@ impl IntoRawFd for fs::File { + + impl AsRawFd for io::Stdin { + fn as_raw_fd(&self) -> RawFd { +- wasi::STDIN_FD ++ sys::stdio::Stdin.as_raw_fd() + } + } + + impl AsRawFd for io::Stdout { + fn as_raw_fd(&self) -> RawFd { +- wasi::STDOUT_FD ++ sys::stdio::Stdout.as_raw_fd() + } + } + + impl AsRawFd for io::Stderr { + fn as_raw_fd(&self) -> RawFd { +- wasi::STDERR_FD ++ sys::stdio::Stderr.as_raw_fd() + } + } +diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs +index 5b7a8678b66..00327c1743c 100644 +--- a/src/libstd/sys/wasi/fd.rs ++++ b/src/libstd/sys/wasi/fd.rs +@@ -1,40 +1,31 @@ + #![allow(dead_code)] + ++use super::err2io; + use crate::io::{self, IoSlice, IoSliceMut, SeekFrom}; + use crate::mem; + use crate::net::Shutdown; +-use super::err2io; +-use ::wasi::wasi_unstable as wasi; + + #[derive(Debug)] + pub struct WasiFd { + fd: wasi::Fd, + } + +-fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::IoVec] { +- assert_eq!( +- mem::size_of::>(), +- mem::size_of::() +- ); +- assert_eq!( +- mem::align_of::>(), +- mem::align_of::() +- ); ++fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] { ++ assert_eq!(mem::size_of::>(), mem::size_of::()); ++ assert_eq!(mem::align_of::>(), mem::align_of::()); + /// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout +- unsafe { mem::transmute(a) } ++ unsafe { ++ mem::transmute(a) ++ } + } + +-fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::CIoVec] { +- assert_eq!( +- mem::size_of::>(), +- mem::size_of::() +- ); +- assert_eq!( +- mem::align_of::>(), +- mem::align_of::() +- ); ++fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] { ++ assert_eq!(mem::size_of::>(), mem::size_of::()); ++ assert_eq!(mem::align_of::>(), mem::align_of::()); + /// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout +- unsafe { mem::transmute(a) } ++ unsafe { ++ mem::transmute(a) ++ } + } + + impl WasiFd { +@@ -87,7 +78,7 @@ impl WasiFd { + + // FIXME: __wasi_fd_fdstat_get + +- pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> { ++ pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> { + unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) } + } + +@@ -107,31 +98,30 @@ impl WasiFd { + unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) } + } + +- pub fn create_directory(&self, path: &[u8]) -> io::Result<()> { ++ pub fn create_directory(&self, path: &str) -> io::Result<()> { + unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) } + } + + pub fn link( + &self, +- old_flags: wasi::LookupFlags, +- old_path: &[u8], ++ old_flags: wasi::Lookupflags, ++ old_path: &str, + new_fd: &WasiFd, +- new_path: &[u8], ++ new_path: &str, + ) -> io::Result<()> { + unsafe { +- wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path) +- .map_err(err2io) ++ wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path).map_err(err2io) + } + } + + pub fn open( + &self, +- dirflags: wasi::LookupFlags, +- path: &[u8], +- oflags: wasi::OFlags, ++ dirflags: wasi::Lookupflags, ++ path: &str, ++ oflags: wasi::Oflags, + fs_rights_base: wasi::Rights, + fs_rights_inheriting: wasi::Rights, +- fs_flags: wasi::FdFlags, ++ fs_flags: wasi::Fdflags, + ) -> io::Result { + unsafe { + wasi::path_open( +@@ -142,25 +132,25 @@ impl WasiFd { + fs_rights_base, + fs_rights_inheriting, + fs_flags, +- ).map(|fd| WasiFd::from_raw(fd)).map_err(err2io) ++ ) ++ .map(|fd| WasiFd::from_raw(fd)) ++ .map_err(err2io) + } + } + +- pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result { +- unsafe { wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) } ++ pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result { ++ unsafe { wasi::fd_readdir(self.fd, buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io) } + } + +- pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result { +- unsafe { wasi::path_readlink(self.fd, path, buf).map_err(err2io) } ++ pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result { ++ unsafe { wasi::path_readlink(self.fd, path, buf.as_mut_ptr(), buf.len()).map_err(err2io) } + } + +- pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> { +- unsafe { +- wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) +- } ++ pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> { ++ unsafe { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) } + } + +- pub fn filestat_get(&self) -> io::Result { ++ pub fn filestat_get(&self) -> io::Result { + unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) } + } + +@@ -168,11 +158,9 @@ impl WasiFd { + &self, + atim: wasi::Timestamp, + mtim: wasi::Timestamp, +- fstflags: wasi::FstFlags, ++ fstflags: wasi::Fstflags, + ) -> io::Result<()> { +- unsafe { +- 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<()> { +@@ -181,61 +169,55 @@ impl WasiFd { + + pub fn path_filestat_get( + &self, +- flags: wasi::LookupFlags, +- path: &[u8], +- ) -> io::Result { ++ flags: wasi::Lookupflags, ++ path: &str, ++ ) -> io::Result { + unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) } + } + + pub fn path_filestat_set_times( + &self, +- flags: wasi::LookupFlags, +- path: &[u8], ++ flags: wasi::Lookupflags, ++ path: &str, + atim: wasi::Timestamp, + mtim: wasi::Timestamp, +- fstflags: wasi::FstFlags, ++ fstflags: wasi::Fstflags, + ) -> io::Result<()> { + unsafe { +- wasi::path_filestat_set_times( +- self.fd, +- flags, +- path, +- atim, +- mtim, +- fstflags, +- ).map_err(err2io) ++ 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<()> { ++ pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> { + unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) } + } + +- pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> { ++ pub fn unlink_file(&self, path: &str) -> io::Result<()> { + unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) } + } + +- pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> { ++ pub fn remove_directory(&self, path: &str) -> io::Result<()> { + unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) } + } + + pub fn sock_recv( + &self, + ri_data: &mut [IoSliceMut<'_>], +- ri_flags: wasi::RiFlags, +- ) -> io::Result<(usize, wasi::RoFlags)> { ++ 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: wasi::SiFlags) -> io::Result { ++ pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result { + 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 => wasi::SHUT_RD, +- Shutdown::Write => wasi::SHUT_WR, +- Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD, ++ Shutdown::Read => wasi::SDFLAGS_RD, ++ Shutdown::Write => wasi::SDFLAGS_WR, ++ Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD, + }; + unsafe { 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 4113f6a2e09..fad092e35c3 100644 +--- a/src/libstd/sys/wasi/fs.rs ++++ b/src/libstd/sys/wasi/fs.rs +@@ -15,20 +15,18 @@ 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: wasi::FileStat, ++ meta: wasi::Filestat, + } + + pub struct ReadDir { + inner: Arc, +- cookie: Option, ++ cookie: Option, + buf: Vec, + offset: usize, + cap: usize, +@@ -49,9 +47,9 @@ pub struct DirEntry { + pub struct OpenOptions { + read: bool, + write: bool, +- dirflags: wasi::LookupFlags, +- fdflags: wasi::FdFlags, +- oflags: wasi::OFlags, ++ dirflags: wasi::Lookupflags, ++ fdflags: wasi::Fdflags, ++ oflags: wasi::Oflags, + rights_base: Option, + rights_inheriting: Option, + } +@@ -63,7 +61,7 @@ pub struct FilePermissions { + + #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] + pub struct FileType { +- bits: wasi::FileType, ++ bits: wasi::Filetype, + } + + #[derive(Debug)] +@@ -71,7 +69,7 @@ pub struct DirBuilder {} + + impl FileAttr { + pub fn size(&self) -> u64 { +- self.meta.st_size ++ self.meta.size + } + + pub fn perm(&self) -> FilePermissions { +@@ -80,24 +78,22 @@ impl FileAttr { + } + + pub fn file_type(&self) -> FileType { +- FileType { +- bits: self.meta.st_filetype, +- } ++ FileType { bits: self.meta.filetype } + } + + pub fn modified(&self) -> io::Result { +- Ok(SystemTime::from_wasi_timestamp(self.meta.st_mtim)) ++ Ok(SystemTime::from_wasi_timestamp(self.meta.mtim)) + } + + pub fn accessed(&self) -> io::Result { +- Ok(SystemTime::from_wasi_timestamp(self.meta.st_atim)) ++ Ok(SystemTime::from_wasi_timestamp(self.meta.atim)) + } + + pub fn created(&self) -> io::Result { +- Ok(SystemTime::from_wasi_timestamp(self.meta.st_ctim)) ++ Ok(SystemTime::from_wasi_timestamp(self.meta.ctim)) + } + +- pub fn as_wasi(&self) -> &wasi::FileStat { ++ pub fn as_wasi(&self) -> &wasi::Filestat { + &self.meta + } + } +@@ -125,7 +121,7 @@ impl FileType { + self.bits == wasi::FILETYPE_SYMBOLIC_LINK + } + +- pub fn bits(&self) -> wasi::FileType { ++ pub fn bits(&self) -> wasi::Filetype { + self.bits + } + } +@@ -177,8 +173,7 @@ impl Iterator for ReadDir { + continue; + } + let (dirent, data) = data.split_at(dirent_size); +- let dirent = +- unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) }; ++ let dirent = 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 +@@ -224,17 +219,11 @@ impl DirEntry { + } + + pub fn metadata(&self) -> io::Result { +- metadata_at( +- &self.inner.dir.fd, +- 0, +- OsStr::from_bytes(&self.name).as_ref(), +- ) ++ metadata_at(&self.inner.dir.fd, 0, OsStr::from_bytes(&self.name).as_ref()) + } + + pub fn file_type(&self) -> io::Result { +- Ok(FileType { +- bits: self.meta.d_type, +- }) ++ Ok(FileType { bits: self.meta.d_type }) + } + + pub fn ino(&self) -> wasi::Inode { +@@ -245,7 +234,7 @@ impl DirEntry { + impl OpenOptions { + pub fn new() -> OpenOptions { + let mut base = OpenOptions::default(); +- base.dirflags = wasi::LOOKUP_SYMLINK_FOLLOW; ++ base.dirflags = wasi::LOOKUPFLAGS_SYMLINK_FOLLOW; + return base; + } + +@@ -258,23 +247,23 @@ impl OpenOptions { + } + + pub fn truncate(&mut self, truncate: bool) { +- self.oflag(wasi::O_TRUNC, truncate); ++ self.oflag(wasi::OFLAGS_TRUNC, truncate); + } + + pub fn create(&mut self, create: bool) { +- self.oflag(wasi::O_CREAT, create); ++ self.oflag(wasi::OFLAGS_CREAT, create); + } + + pub fn create_new(&mut self, create_new: bool) { +- self.oflag(wasi::O_EXCL, create_new); +- self.oflag(wasi::O_CREAT, create_new); ++ self.oflag(wasi::OFLAGS_EXCL, create_new); ++ self.oflag(wasi::OFLAGS_CREAT, create_new); + } + + pub fn directory(&mut self, directory: bool) { +- self.oflag(wasi::O_DIRECTORY, directory); ++ self.oflag(wasi::OFLAGS_DIRECTORY, directory); + } + +- fn oflag(&mut self, bit: wasi::OFlags, set: bool) { ++ fn oflag(&mut self, bit: wasi::Oflags, set: bool) { + if set { + self.oflags |= bit; + } else { +@@ -283,26 +272,26 @@ impl OpenOptions { + } + + pub fn append(&mut self, set: bool) { +- self.fdflag(wasi::FDFLAG_APPEND, set); ++ self.fdflag(wasi::FDFLAGS_APPEND, set); + } + + pub fn dsync(&mut self, set: bool) { +- self.fdflag(wasi::FDFLAG_DSYNC, set); ++ self.fdflag(wasi::FDFLAGS_DSYNC, set); + } + + pub fn nonblock(&mut self, set: bool) { +- self.fdflag(wasi::FDFLAG_NONBLOCK, set); ++ self.fdflag(wasi::FDFLAGS_NONBLOCK, set); + } + + pub fn rsync(&mut self, set: bool) { +- self.fdflag(wasi::FDFLAG_RSYNC, set); ++ self.fdflag(wasi::FDFLAGS_RSYNC, set); + } + + pub fn sync(&mut self, set: bool) { +- self.fdflag(wasi::FDFLAG_SYNC, set); ++ self.fdflag(wasi::FDFLAGS_SYNC, set); + } + +- fn fdflag(&mut self, bit: wasi::FdFlags, set: bool) { ++ fn fdflag(&mut self, bit: wasi::Fdflags, set: bool) { + if set { + self.fdflags |= bit; + } else { +@@ -330,36 +319,36 @@ impl OpenOptions { + // based on that. + let mut base = 0; + if self.read { +- base |= wasi::RIGHT_FD_READ; +- base |= wasi::RIGHT_FD_READDIR; ++ base |= wasi::RIGHTS_FD_READ; ++ base |= wasi::RIGHTS_FD_READDIR; + } + if self.write { +- base |= wasi::RIGHT_FD_WRITE; +- base |= wasi::RIGHT_FD_DATASYNC; +- base |= wasi::RIGHT_FD_ALLOCATE; +- base |= wasi::RIGHT_FD_FILESTAT_SET_SIZE; ++ base |= wasi::RIGHTS_FD_WRITE; ++ base |= wasi::RIGHTS_FD_DATASYNC; ++ base |= wasi::RIGHTS_FD_ALLOCATE; ++ base |= wasi::RIGHTS_FD_FILESTAT_SET_SIZE; + } + + // FIXME: some of these should probably be read-only or write-only... +- 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; ++ base |= wasi::RIGHTS_FD_ADVISE; ++ base |= wasi::RIGHTS_FD_FDSTAT_SET_FLAGS; ++ base |= wasi::RIGHTS_FD_FILESTAT_SET_TIMES; ++ base |= wasi::RIGHTS_FD_SEEK; ++ base |= wasi::RIGHTS_FD_SYNC; ++ base |= wasi::RIGHTS_FD_TELL; ++ base |= wasi::RIGHTS_PATH_CREATE_DIRECTORY; ++ base |= wasi::RIGHTS_PATH_CREATE_FILE; ++ base |= wasi::RIGHTS_PATH_FILESTAT_GET; ++ base |= wasi::RIGHTS_PATH_LINK_SOURCE; ++ base |= wasi::RIGHTS_PATH_LINK_TARGET; ++ base |= wasi::RIGHTS_PATH_OPEN; ++ base |= wasi::RIGHTS_PATH_READLINK; ++ base |= wasi::RIGHTS_PATH_REMOVE_DIRECTORY; ++ base |= wasi::RIGHTS_PATH_RENAME_SOURCE; ++ base |= wasi::RIGHTS_PATH_RENAME_TARGET; ++ base |= wasi::RIGHTS_PATH_SYMLINK; ++ base |= wasi::RIGHTS_PATH_UNLINK_FILE; ++ base |= wasi::RIGHTS_POLL_FD_READWRITE; + + return base; + } +@@ -368,14 +357,14 @@ impl OpenOptions { + self.rights_inheriting.unwrap_or_else(|| self.rights_base()) + } + +- pub fn lookup_flags(&mut self, flags: wasi::LookupFlags) { ++ 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, wasi::RIGHT_PATH_OPEN)?; ++ let (dir, file) = open_parent(path, wasi::RIGHTS_PATH_OPEN)?; + open_at(&dir, &file, opts) + } + +@@ -387,11 +376,7 @@ impl File { + self.fd.filestat_get().map(|meta| FileAttr { meta }) + } + +- pub fn metadata_at( +- &self, +- flags: wasi::LookupFlags, +- path: &Path, +- ) -> io::Result { ++ pub fn metadata_at(&self, flags: wasi::Lookupflags, path: &Path) -> io::Result { + metadata_at(&self.fd, flags, path) + } + +@@ -457,11 +442,7 @@ impl File { + + impl FromInner for File { + fn from_inner(fd: u32) -> File { +- unsafe { +- File { +- fd: WasiFd::from_raw(fd), +- } +- } ++ unsafe { File { fd: WasiFd::from_raw(fd) } } + } + } + +@@ -471,16 +452,14 @@ impl DirBuilder { + } + + pub fn mkdir(&self, p: &Path) -> io::Result<()> { +- let (dir, file) = open_parent(p, wasi::RIGHT_PATH_CREATE_DIRECTORY)?; +- dir.create_directory(file.as_os_str().as_bytes()) ++ let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_CREATE_DIRECTORY)?; ++ dir.create_directory(osstr2str(file.as_ref())?) + } + } + + impl fmt::Debug for File { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +- f.debug_struct("File") +- .field("fd", &self.fd.as_raw()) +- .finish() ++ f.debug_struct("File").field("fd", &self.fd.as_raw()).finish() + } + } + +@@ -494,26 +473,19 @@ pub fn readdir(p: &Path) -> io::Result { + buf: vec![0; 128], + offset: 0, + cap: 0, +- inner: Arc::new(ReadDirInner { +- dir, +- root: p.to_path_buf(), +- }), ++ inner: Arc::new(ReadDirInner { dir, root: p.to_path_buf() }), + }) + } + + pub fn unlink(p: &Path) -> io::Result<()> { +- let (dir, file) = open_parent(p, wasi::RIGHT_PATH_UNLINK_FILE)?; +- dir.unlink_file(file.as_os_str().as_bytes()) ++ let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_UNLINK_FILE)?; ++ dir.unlink_file(osstr2str(file.as_ref())?) + } + + pub fn rename(old: &Path, new: &Path) -> io::Result<()> { +- 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, +- new_file.as_os_str().as_bytes(), +- ) ++ let (old, old_file) = open_parent(old, wasi::RIGHTS_PATH_RENAME_SOURCE)?; ++ let (new, new_file) = open_parent(new, wasi::RIGHTS_PATH_RENAME_TARGET)?; ++ old.rename(osstr2str(old_file.as_ref())?, &new, osstr2str(new_file.as_ref())?) + } + + pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { +@@ -523,12 +495,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { + } + + pub fn rmdir(p: &Path) -> io::Result<()> { +- let (dir, file) = open_parent(p, wasi::RIGHT_PATH_REMOVE_DIRECTORY)?; +- dir.remove_directory(file.as_os_str().as_bytes()) ++ let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_REMOVE_DIRECTORY)?; ++ dir.remove_directory(osstr2str(file.as_ref())?) + } + + pub fn readlink(p: &Path) -> io::Result { +- let (dir, file) = open_parent(p, wasi::RIGHT_PATH_READLINK)?; ++ let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_READLINK)?; + read_link(&dir, &file) + } + +@@ -549,7 +521,7 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result { + // Now that we have an initial guess of how big to make our buffer, call + // `readlink` in a loop until it fails or reports it filled fewer bytes than + // we asked for, indicating we got everything. +- let file = file.as_os_str().as_bytes(); ++ let file = osstr2str(file.as_ref())?; + let mut destination = vec![0u8; initial_size]; + loop { + let len = fd.readlink(file, &mut destination)?; +@@ -564,38 +536,34 @@ 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, wasi::RIGHT_PATH_SYMLINK)?; +- dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes()) ++ let (dst, dst_file) = open_parent(dst, wasi::RIGHTS_PATH_SYMLINK)?; ++ dst.symlink(osstr2str(src.as_ref())?, osstr2str(dst_file.as_ref())?) + } + + pub fn link(src: &Path, dst: &Path) -> io::Result<()> { +- let (src, src_file) = open_parent(src, wasi::RIGHT_PATH_LINK_SOURCE)?; +- let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_LINK_TARGET)?; ++ let (src, src_file) = open_parent(src, wasi::RIGHTS_PATH_LINK_SOURCE)?; ++ let (dst, dst_file) = open_parent(dst, wasi::RIGHTS_PATH_LINK_TARGET)?; + src.link( +- wasi::LOOKUP_SYMLINK_FOLLOW, +- src_file.as_os_str().as_bytes(), ++ wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, ++ osstr2str(src_file.as_ref())?, + &dst, +- dst_file.as_os_str().as_bytes(), ++ osstr2str(dst_file.as_ref())?, + ) + } + + pub fn stat(p: &Path) -> io::Result { +- let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?; +- metadata_at(&dir, wasi::LOOKUP_SYMLINK_FOLLOW, &file) ++ let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_FILESTAT_GET)?; ++ metadata_at(&dir, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, &file) + } + + pub fn lstat(p: &Path) -> io::Result { +- let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?; ++ let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_FILESTAT_GET)?; + metadata_at(&dir, 0, &file) + } + +-fn metadata_at( +- fd: &WasiFd, +- flags: wasi::LookupFlags, +- path: &Path, +-) -> io::Result { +- fd.path_filestat_get(flags, path.as_os_str().as_bytes()) +- .map(|meta| FileAttr { meta }) ++fn metadata_at(fd: &WasiFd, flags: wasi::Lookupflags, path: &Path) -> io::Result { ++ let meta = fd.path_filestat_get(flags, osstr2str(path.as_ref())?)?; ++ Ok(FileAttr { meta }) + } + + pub fn canonicalize(_p: &Path) -> io::Result { +@@ -607,7 +575,7 @@ pub fn canonicalize(_p: &Path) -> io::Result { + fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result { + let fd = fd.open( + opts.dirflags, +- path.as_os_str().as_bytes(), ++ osstr2str(path.as_ref())?, + opts.oflags, + opts.rights_base(), + opts.rights_inheriting(), +@@ -643,10 +611,7 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result { + /// + /// Note that this can fail if `p` doesn't look like it can be opened relative + /// to any preopened file descriptor. +-fn open_parent( +- p: &Path, +- rights: wasi::Rights, +-) -> io::Result<(ManuallyDrop, PathBuf)> { ++fn open_parent(p: &Path, rights: wasi::Rights) -> io::Result<(ManuallyDrop, PathBuf)> { + let p = CString::new(p.as_os_str().as_bytes())?; + unsafe { + let mut ret = ptr::null(); +@@ -671,3 +636,7 @@ fn open_parent( + return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path)); + } + } ++ ++pub fn osstr2str(f: &OsStr) -> io::Result<&str> { ++ f.to_str().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "input must be utf-8")) ++} +diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs +index 4be92faed30..41a6e9783c0 100644 +--- a/src/libstd/sys/wasi/io.rs ++++ b/src/libstd/sys/wasi/io.rs +@@ -1,12 +1,9 @@ + use crate::marker::PhantomData; + use crate::slice; + +-use ::wasi::wasi_unstable as wasi; +-use core::ffi::c_void; +- + #[repr(transparent)] + pub struct IoSlice<'a> { +- vec: wasi::CIoVec, ++ vec: wasi::Ciovec, + _p: PhantomData<&'a [u8]>, + } + +@@ -14,8 +11,8 @@ impl<'a> IoSlice<'a> { + #[inline] + pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + IoSlice { +- vec: wasi::CIoVec { +- buf: buf.as_ptr() as *const c_void, ++ vec: wasi::Ciovec { ++ buf: buf.as_ptr(), + buf_len: buf.len(), + }, + _p: PhantomData, +@@ -44,7 +41,7 @@ impl<'a> IoSlice<'a> { + + #[repr(transparent)] + pub struct IoSliceMut<'a> { +- vec: wasi::IoVec, ++ vec: wasi::Iovec, + _p: PhantomData<&'a mut [u8]>, + } + +@@ -52,8 +49,8 @@ impl<'a> IoSliceMut<'a> { + #[inline] + pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + IoSliceMut { +- vec: wasi::IoVec { +- buf: buf.as_mut_ptr() as *mut c_void, ++ vec: wasi::Iovec { ++ buf: buf.as_mut_ptr(), + buf_len: buf.len() + }, + _p: PhantomData, +diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs +index 517e3be9cb5..83f98a19f47 100644 +--- a/src/libstd/sys/wasi/mod.rs ++++ b/src/libstd/sys/wasi/mod.rs +@@ -17,7 +17,6 @@ + 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; +@@ -72,25 +71,21 @@ pub fn decode_error_kind(errno: i32) -> 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, ++ match errno as u16 { ++ wasi::ERRNO_CONNREFUSED => ConnectionRefused, ++ wasi::ERRNO_CONNRESET => ConnectionReset, ++ wasi::ERRNO_PERM | wasi::ERRNO_ACCES => PermissionDenied, ++ wasi::ERRNO_PIPE => BrokenPipe, ++ wasi::ERRNO_NOTCONN => NotConnected, ++ wasi::ERRNO_CONNABORTED => ConnectionAborted, ++ wasi::ERRNO_ADDRNOTAVAIL => AddrNotAvailable, ++ wasi::ERRNO_ADDRINUSE => AddrInUse, ++ wasi::ERRNO_NOENT => NotFound, ++ wasi::ERRNO_INTR => Interrupted, ++ wasi::ERRNO_INVAL => InvalidInput, ++ wasi::ERRNO_TIMEDOUT => TimedOut, ++ wasi::ERRNO_EXIST => AlreadyExists, ++ wasi::ERRNO_AGAIN => WouldBlock, + _ => Other, + } + } +@@ -116,16 +111,13 @@ 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 core::ffi::c_void; ++ let base = &mut ret as *mut (u64, u64) as *mut u8; + let len = mem::size_of_val(&ret); +- let ret = wasi::raw::__wasi_random_get(base, len); +- if ret != 0 { +- panic!("__wasi_random_get failure") +- } ++ wasi::random_get(base, len).expect("random_get failure"); + } + return ret + } + + fn err2io(err: wasi::Error) -> std_io::Error { +- std_io::Error::from_raw_os_error(err.get() as i32) ++ std_io::Error::from_raw_os_error(err.raw_error().into()) + } +diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs +index 1d57b9922e5..1d53884f2d6 100644 +--- a/src/libstd/sys/wasi/stdio.rs ++++ b/src/libstd/sys/wasi/stdio.rs +@@ -2,8 +2,6 @@ use crate::io::{self, IoSlice, IoSliceMut}; + use crate::mem::ManuallyDrop; + use crate::sys::fd::WasiFd; + +-use ::wasi::wasi_unstable as wasi; +- + pub struct Stdin; + pub struct Stdout; + pub struct Stderr; +@@ -18,8 +16,11 @@ impl Stdin { + } + + pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result { +- ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDIN_FD) }) +- .read(data) ++ ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).read(data) ++ } ++ ++ pub fn as_raw_fd(&self) -> u32 { ++ 0 + } + } + +@@ -33,13 +34,16 @@ impl Stdout { + } + + pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { +- ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDOUT_FD) }) +- .write(data) ++ ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data) + } + + pub fn flush(&self) -> io::Result<()> { + Ok(()) + } ++ ++ pub fn as_raw_fd(&self) -> u32 { ++ 1 ++ } + } + + impl Stderr { +@@ -52,13 +56,16 @@ impl Stderr { + } + + pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { +- ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDERR_FD) }) +- .write(data) ++ ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data) + } + + pub fn flush(&self) -> io::Result<()> { + Ok(()) + } ++ ++ pub fn as_raw_fd(&self) -> u32 { ++ 2 ++ } + } + + impl io::Write for Stderr { +@@ -74,7 +81,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.get() as i32) ++ err.raw_os_error() == Some(wasi::ERRNO_BADF.into()) + } + + pub fn panic_output() -> Option { +diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs +index 6ce41420284..0986759b89b 100644 +--- a/src/libstd/sys/wasi/thread.rs ++++ b/src/libstd/sys/wasi/thread.rs +@@ -4,22 +4,18 @@ 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; + + impl Thread { + // unsafe: see thread::Builder::spawn_unchecked for safety requirements +- pub unsafe fn new(_stack: usize, _p: Box) +- -> io::Result +- { ++ pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { + unsupported() + } + + pub fn yield_now() { +- let ret = wasi::sched_yield(); ++ let ret = unsafe { wasi::sched_yield() }; + debug_assert_eq!(ret, Ok(())); + } + +@@ -33,32 +29,30 @@ impl Thread { + + const USERDATA: wasi::Userdata = 0x0123_45678; + +- let clock = wasi::raw::__wasi_subscription_u_clock_t { +- identifier: 0, +- clock_id: wasi::CLOCK_MONOTONIC, ++ let clock = wasi::SubscriptionClock { ++ id: wasi::CLOCKID_MONOTONIC, + timeout: nanos as u64, + precision: 0, + flags: 0, + }; + +- let in_ = [wasi::Subscription { ++ let in_ = wasi::Subscription { + userdata: USERDATA, +- 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]) ++ r#type: wasi::EVENTTYPE_CLOCK, ++ u: wasi::SubscriptionU { clock }, + }; +- match (res, event) { +- (Ok(1), wasi::Event { +- userdata: USERDATA, +- error: 0, +- type_: wasi::EVENTTYPE_CLOCK, +- .. +- }) => {} +- _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), ++ unsafe { ++ let mut event: wasi::Event = mem::zeroed(); ++ let res = wasi::poll_oneoff(&in_, &mut event, 1); ++ match (res, event) { ++ ( ++ Ok(1), ++ wasi::Event { ++ userdata: USERDATA, error: 0, r#type: wasi::EVENTTYPE_CLOCK, .. ++ }, ++ ) => {} ++ _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), ++ } + } + } + +@@ -69,6 +63,10 @@ impl Thread { + + pub mod guard { + pub type Guard = !; +- pub unsafe fn current() -> Option { None } +- pub unsafe fn init() -> Option { None } ++ pub unsafe fn current() -> Option { ++ None ++ } ++ pub unsafe fn init() -> Option { ++ None ++ } + } +diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs +index 4394a22f9c2..80ec317b5a2 100644 +--- a/src/libstd/sys/wasi/time.rs ++++ b/src/libstd/sys/wasi/time.rs +@@ -1,5 +1,4 @@ + use crate::time::Duration; +-use ::wasi::wasi_unstable as wasi; + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + pub struct Instant(Duration); +@@ -10,19 +9,18 @@ pub struct SystemTime(Duration); + pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); + + fn current_time(clock: u32) -> Duration { +- 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, +- ) ++ let ts = unsafe { ++ 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(wasi::CLOCK_MONOTONIC)) ++ Instant(current_time(wasi::CLOCKID_MONOTONIC)) + } + + pub const fn zero() -> Instant { +@@ -48,15 +46,14 @@ impl Instant { + + impl SystemTime { + pub fn now() -> SystemTime { +- SystemTime(current_time(wasi::CLOCK_REALTIME)) ++ SystemTime(current_time(wasi::CLOCKID_REALTIME)) + } + + pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { + SystemTime(Duration::from_nanos(ts)) + } + +- pub fn sub_time(&self, other: &SystemTime) +- -> Result { ++ pub fn sub_time(&self, other: &SystemTime) -> Result { + self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) + } + diff --git a/debian/patches/u-wasm32-67267.patch b/debian/patches/u-wasm32-67267.patch new file mode 100644 index 0000000000..9558a06119 --- /dev/null +++ b/debian/patches/u-wasm32-67267.patch @@ -0,0 +1,123 @@ +commit 641ccd58c168a296f5c36a191660ef63a32a98b9 +Author: Alex Crichton +Date: Thu Dec 12 14:48:47 2019 -0800 + + Fix signature of `__wasilibc_find_relpath` + + Looks like this function changed upstream, so it needs to be adjusted + for when used by libstd. + +diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs +index fad092e35c3..04bfdf67e12 100644 +--- a/src/libstd/sys/wasi/fs.rs ++++ b/src/libstd/sys/wasi/fs.rs +@@ -364,7 +364,7 @@ impl OpenOptions { + + impl File { + pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { +- let (dir, file) = open_parent(path, wasi::RIGHTS_PATH_OPEN)?; ++ let (dir, file) = open_parent(path)?; + open_at(&dir, &file, opts) + } + +@@ -452,7 +452,7 @@ impl DirBuilder { + } + + pub fn mkdir(&self, p: &Path) -> io::Result<()> { +- let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_CREATE_DIRECTORY)?; ++ let (dir, file) = open_parent(p)?; + dir.create_directory(osstr2str(file.as_ref())?) + } + } +@@ -478,13 +478,13 @@ pub fn readdir(p: &Path) -> io::Result { + } + + pub fn unlink(p: &Path) -> io::Result<()> { +- let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_UNLINK_FILE)?; ++ let (dir, file) = open_parent(p)?; + dir.unlink_file(osstr2str(file.as_ref())?) + } + + pub fn rename(old: &Path, new: &Path) -> io::Result<()> { +- let (old, old_file) = open_parent(old, wasi::RIGHTS_PATH_RENAME_SOURCE)?; +- let (new, new_file) = open_parent(new, wasi::RIGHTS_PATH_RENAME_TARGET)?; ++ let (old, old_file) = open_parent(old)?; ++ let (new, new_file) = open_parent(new)?; + old.rename(osstr2str(old_file.as_ref())?, &new, osstr2str(new_file.as_ref())?) + } + +@@ -495,12 +495,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { + } + + pub fn rmdir(p: &Path) -> io::Result<()> { +- let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_REMOVE_DIRECTORY)?; ++ let (dir, file) = open_parent(p)?; + dir.remove_directory(osstr2str(file.as_ref())?) + } + + pub fn readlink(p: &Path) -> io::Result { +- let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_READLINK)?; ++ let (dir, file) = open_parent(p)?; + read_link(&dir, &file) + } + +@@ -536,13 +536,13 @@ 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, wasi::RIGHTS_PATH_SYMLINK)?; ++ let (dst, dst_file) = open_parent(dst)?; + dst.symlink(osstr2str(src.as_ref())?, osstr2str(dst_file.as_ref())?) + } + + pub fn link(src: &Path, dst: &Path) -> io::Result<()> { +- let (src, src_file) = open_parent(src, wasi::RIGHTS_PATH_LINK_SOURCE)?; +- let (dst, dst_file) = open_parent(dst, wasi::RIGHTS_PATH_LINK_TARGET)?; ++ let (src, src_file) = open_parent(src)?; ++ let (dst, dst_file) = open_parent(dst)?; + src.link( + wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, + osstr2str(src_file.as_ref())?, +@@ -552,12 +552,12 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> { + } + + pub fn stat(p: &Path) -> io::Result { +- let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_FILESTAT_GET)?; ++ let (dir, file) = open_parent(p)?; + metadata_at(&dir, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, &file) + } + + pub fn lstat(p: &Path) -> io::Result { +- let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_FILESTAT_GET)?; ++ let (dir, file) = open_parent(p)?; + metadata_at(&dir, 0, &file) + } + +@@ -611,11 +611,11 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result { + /// + /// Note that this can fail if `p` doesn't look like it can be opened relative + /// to any preopened file descriptor. +-fn open_parent(p: &Path, rights: wasi::Rights) -> io::Result<(ManuallyDrop, PathBuf)> { ++fn open_parent(p: &Path) -> io::Result<(ManuallyDrop, PathBuf)> { + let p = CString::new(p.as_os_str().as_bytes())?; + unsafe { + let mut ret = ptr::null(); +- let fd = libc::__wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret); ++ let fd = __wasilibc_find_relpath(p.as_ptr(), &mut ret); + if fd == -1 { + let msg = format!( + "failed to find a preopened file descriptor \ +@@ -635,6 +635,13 @@ fn open_parent(p: &Path, rights: wasi::Rights) -> io::Result<(ManuallyDrop libc::c_int; ++ } + } + + pub fn osstr2str(f: &OsStr) -> io::Result<&str> { -- 2.39.5