about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2021-02-22 14:21:43 -0800
committerDan Gohman <dev@sunfishcode.online>2021-02-23 05:40:08 -0800
commit132ec261b0d215f77b71eeee3d814cd304fc1a29 (patch)
tree65a17c82edeeb35b3d25c17906b4d6313de96a22 /library/std/src
parent446d4533e89db04f9568be4199e56b5fce0d176d (diff)
downloadrust-132ec261b0d215f77b71eeee3d814cd304fc1a29.tar.gz
rust-132ec261b0d215f77b71eeee3d814cd304fc1a29.zip
Enable API documentation for `std::os::wasi`.
This adds API documentation support for `std::os::wasi` modeled after
how `std::os::unix` works, so that WASI can be documented [here] along
with the other platforms.

[here]: https://doc.rust-lang.org/stable/std/os/index.html

Two changes of particular interest:

 - This changes the `AsRawFd` for `io::Stdin` for WASI to return
   `libc::STDIN_FILENO` instead of `sys::stdio::Stdin.as_raw_fd()` (and
   similar for `Stdout` and `Stderr`), which matches how the `unix`
   version works. `STDIN_FILENO` etc. may not always be explicitly
   reserved at the WASI level, but as long as we have Rust's `std` and
   `libc`, I think it's reasonable to guarantee that we'll always use
   `libc::STDIN_FILENO` for stdin.

 - This duplicates the `osstr2str` utility function, rather than
   trying to share it across all the configurations that need it.
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/os/mod.rs3
-rw-r--r--library/std/src/sys/mod.rs30
-rw-r--r--library/std/src/sys/wasi/ext/fs.rs25
-rw-r--r--library/std/src/sys/wasi/ext/io.rs12
-rw-r--r--library/std/src/sys/wasi/ext/mod.rs28
5 files changed, 79 insertions, 19 deletions
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index f61e402e370..fad5886def7 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -22,6 +22,9 @@ pub use crate::sys::windows_ext as windows;
 #[doc(cfg(target_os = "linux"))]
 pub mod linux;
 
+#[cfg(doc)]
+pub use crate::sys::wasi_ext as wasi;
+
 // If we're not documenting libstd then we just expose the main modules as we otherwise would.
 
 #[cfg(not(doc))]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index d48d9cb0efc..d3f53801d2d 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -61,9 +61,9 @@ cfg_if::cfg_if! {
         #[stable(feature = "rust1", since = "1.0.0")]
         pub use self::ext as unix_ext;
     } else if #[cfg(any(target_os = "hermit",
-                        target_arch = "wasm32",
+                        all(target_arch = "wasm32", not(target_os = "wasi")),
                         all(target_vendor = "fortanix", target_env = "sgx")))] {
-        // On wasm right now the module below doesn't compile
+        // On non-WASI wasm right now the module below doesn't compile
         // (missing things in `libc` which is empty) so just omit everything
         // with an empty module
         #[unstable(issue = "none", feature = "std_internals")]
@@ -85,9 +85,9 @@ cfg_if::cfg_if! {
         #[stable(feature = "rust1", since = "1.0.0")]
         pub use self::ext as windows_ext;
     } else if #[cfg(any(target_os = "hermit",
-                        target_arch = "wasm32",
+                        all(target_arch = "wasm32", not(target_os = "wasi")),
                         all(target_vendor = "fortanix", target_env = "sgx")))] {
-        // On wasm right now the shim below doesn't compile, so
+        // On non-WASI wasm right now the shim below doesn't compile, so
         // just omit it
         #[unstable(issue = "none", feature = "std_internals")]
         #[allow(missing_docs)]
@@ -106,3 +106,25 @@ cfg_if::cfg_if! {
         pub mod windows_ext;
     }
 }
+
+#[cfg(doc)]
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "wasi")] {
+        // On WASI we'll document what's already available
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub use self::ext as wasi_ext;
+    } else if #[cfg(any(target_os = "hermit",
+                        target_arch = "wasm32",
+                        all(target_vendor = "fortanix", target_env = "sgx")))] {
+        // On non-WASI wasm right now the module below doesn't compile
+        // (missing things in `libc` which is empty) so just omit everything
+        // with an empty module
+        #[unstable(issue = "none", feature = "std_internals")]
+        #[allow(missing_docs)]
+        pub mod wasi_ext {}
+    } else {
+        // On other platforms like Windows document the bare bones of WASI
+        #[path = "wasi/ext/mod.rs"]
+        pub mod wasi_ext;
+    }
+}
diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs
index a8da003d550..66b6caf2512 100644
--- a/library/std/src/sys/wasi/ext/fs.rs
+++ b/library/std/src/sys/wasi/ext/fs.rs
@@ -3,11 +3,14 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![unstable(feature = "wasi_ext", issue = "none")]
 
+use crate::ffi::OsStr;
 use crate::fs::{self, File, Metadata, OpenOptions};
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::path::{Path, PathBuf};
-use crate::sys::fs::osstr2str;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
+// Used for `File::read` on intra-doc links
+#[allow(unused_imports)]
+use io::{Read, Write};
 
 /// WASI-specific extensions to [`File`].
 pub trait FileExt {
@@ -54,11 +57,11 @@ pub trait FileExt {
     /// # Errors
     ///
     /// If this function encounters an error of the kind
-    /// [`ErrorKind::Interrupted`] then the error is ignored and the operation
+    /// [`io::ErrorKind::Interrupted`] then the error is ignored and the operation
     /// will continue.
     ///
     /// If this function encounters an "end of file" before completely filling
-    /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
+    /// the buffer, it returns an error of the kind [`io::ErrorKind::UnexpectedEof`].
     /// The contents of `buf` are unspecified in this case.
     ///
     /// If any other read error is encountered then this function immediately
@@ -131,16 +134,16 @@ pub trait FileExt {
     /// The current file cursor is not affected by this function.
     ///
     /// This method will continuously call [`write_at`] until there is no more data
-    /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
+    /// to be written or an error of non-[`io::ErrorKind::Interrupted`] kind is
     /// returned. This method will not return until the entire buffer has been
     /// successfully written or such an error occurs. The first error that is
-    /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
+    /// not of [`io::ErrorKind::Interrupted`] kind generated from this method will be
     /// returned.
     ///
     /// # Errors
     ///
     /// This function will return the first error of
-    /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
+    /// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns.
     ///
     /// [`write_at`]: FileExt::write_at
     #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
@@ -426,7 +429,7 @@ impl MetadataExt for fs::Metadata {
     }
 }
 
-/// WASI-specific extensions for [`FileType`].
+/// WASI-specific extensions for [`fs::FileType`].
 ///
 /// Adds support for special WASI file types such as block/character devices,
 /// pipes, and sockets.
@@ -517,8 +520,12 @@ pub fn symlink<P: AsRef<Path>, U: AsRef<Path>>(
 
 /// Create a symbolic link.
 ///
-/// This is a convenience API similar to [`std::os::unix::fs::symlink`] and
-/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir).
+/// This is a convenience API similar to `std::os::unix::fs::symlink` and
+/// `std::os::windows::fs::symlink_file` and `std::os::windows::fs::symlink_dir`.
 pub fn symlink_path<P: AsRef<Path>, U: AsRef<Path>>(old_path: P, new_path: U) -> io::Result<()> {
     crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref())
 }
+
+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/library/std/src/sys/wasi/ext/io.rs b/library/std/src/sys/wasi/ext/io.rs
index 81413f39dc1..d0edfa9f35f 100644
--- a/library/std/src/sys/wasi/ext/io.rs
+++ b/library/std/src/sys/wasi/ext/io.rs
@@ -145,36 +145,36 @@ impl IntoRawFd for fs::File {
 
 impl AsRawFd for io::Stdin {
     fn as_raw_fd(&self) -> RawFd {
-        sys::stdio::Stdin.as_raw_fd()
+        libc::STDIN_FILENO
     }
 }
 
 impl AsRawFd for io::Stdout {
     fn as_raw_fd(&self) -> RawFd {
-        sys::stdio::Stdout.as_raw_fd()
+        libc::STDOUT_FILENO
     }
 }
 
 impl AsRawFd for io::Stderr {
     fn as_raw_fd(&self) -> RawFd {
-        sys::stdio::Stderr.as_raw_fd()
+        libc::STDERR_FILENO
     }
 }
 
 impl<'a> AsRawFd for io::StdinLock<'a> {
     fn as_raw_fd(&self) -> RawFd {
-        sys::stdio::Stdin.as_raw_fd()
+        libc::STDIN_FILENO
     }
 }
 
 impl<'a> AsRawFd for io::StdoutLock<'a> {
     fn as_raw_fd(&self) -> RawFd {
-        sys::stdio::Stdout.as_raw_fd()
+        libc::STDOUT_FILENO
     }
 }
 
 impl<'a> AsRawFd for io::StderrLock<'a> {
     fn as_raw_fd(&self) -> RawFd {
-        sys::stdio::Stderr.as_raw_fd()
+        libc::STDERR_FILENO
     }
 }
diff --git a/library/std/src/sys/wasi/ext/mod.rs b/library/std/src/sys/wasi/ext/mod.rs
index 1cda30edcad..8a83b247003 100644
--- a/library/std/src/sys/wasi/ext/mod.rs
+++ b/library/std/src/sys/wasi/ext/mod.rs
@@ -1,4 +1,32 @@
+//! Platform-specific extensions to `std` for WASI.
+//!
+//! Provides access to platform-level information on WASI, and exposes
+//! WASI-specific functions that would otherwise be inappropriate as
+//! part of the core `std` library.
+//!
+//! It exposes more ways to deal with platform-specific strings (`OsStr`,
+//! `OsString`), allows to set permissions more granularly, extract low-level
+//! file descriptors from files and sockets, and has platform-specific helpers
+//! for spawning processes.
+//!
+//! # Examples
+//!
+//! ```no_run
+//! use std::fs::File;
+//! use std::os::wasi::prelude::*;
+//!
+//! fn main() -> std::io::Result<()> {
+//!     let f = File::create("foo.txt")?;
+//!     let fd = f.as_raw_fd();
+//!
+//!     // use fd with native WASI bindings
+//!
+//!     Ok(())
+//! }
+//! ```
+
 #![deny(unsafe_op_in_unsafe_fn)]
+#![doc(cfg(target_os = "wasi"))]
 
 pub mod ffi;
 pub mod fs;