Skip to content

Commit 132ec26

Browse files
committed
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.
1 parent 446d453 commit 132ec26

File tree

5 files changed

+79
-19
lines changed

5 files changed

+79
-19
lines changed

library/std/src/os/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub use crate::sys::windows_ext as windows;
2222
#[doc(cfg(target_os = "linux"))]
2323
pub mod linux;
2424

25+
#[cfg(doc)]
26+
pub use crate::sys::wasi_ext as wasi;
27+
2528
// If we're not documenting libstd then we just expose the main modules as we otherwise would.
2629

2730
#[cfg(not(doc))]

library/std/src/sys/mod.rs

+26-4
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ cfg_if::cfg_if! {
6161
#[stable(feature = "rust1", since = "1.0.0")]
6262
pub use self::ext as unix_ext;
6363
} else if #[cfg(any(target_os = "hermit",
64-
target_arch = "wasm32",
64+
all(target_arch = "wasm32", not(target_os = "wasi")),
6565
all(target_vendor = "fortanix", target_env = "sgx")))] {
66-
// On wasm right now the module below doesn't compile
66+
// On non-WASI wasm right now the module below doesn't compile
6767
// (missing things in `libc` which is empty) so just omit everything
6868
// with an empty module
6969
#[unstable(issue = "none", feature = "std_internals")]
@@ -85,9 +85,9 @@ cfg_if::cfg_if! {
8585
#[stable(feature = "rust1", since = "1.0.0")]
8686
pub use self::ext as windows_ext;
8787
} else if #[cfg(any(target_os = "hermit",
88-
target_arch = "wasm32",
88+
all(target_arch = "wasm32", not(target_os = "wasi")),
8989
all(target_vendor = "fortanix", target_env = "sgx")))] {
90-
// On wasm right now the shim below doesn't compile, so
90+
// On non-WASI wasm right now the shim below doesn't compile, so
9191
// just omit it
9292
#[unstable(issue = "none", feature = "std_internals")]
9393
#[allow(missing_docs)]
@@ -106,3 +106,25 @@ cfg_if::cfg_if! {
106106
pub mod windows_ext;
107107
}
108108
}
109+
110+
#[cfg(doc)]
111+
cfg_if::cfg_if! {
112+
if #[cfg(target_os = "wasi")] {
113+
// On WASI we'll document what's already available
114+
#[stable(feature = "rust1", since = "1.0.0")]
115+
pub use self::ext as wasi_ext;
116+
} else if #[cfg(any(target_os = "hermit",
117+
target_arch = "wasm32",
118+
all(target_vendor = "fortanix", target_env = "sgx")))] {
119+
// On non-WASI wasm right now the module below doesn't compile
120+
// (missing things in `libc` which is empty) so just omit everything
121+
// with an empty module
122+
#[unstable(issue = "none", feature = "std_internals")]
123+
#[allow(missing_docs)]
124+
pub mod wasi_ext {}
125+
} else {
126+
// On other platforms like Windows document the bare bones of WASI
127+
#[path = "wasi/ext/mod.rs"]
128+
pub mod wasi_ext;
129+
}
130+
}

library/std/src/sys/wasi/ext/fs.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
#![deny(unsafe_op_in_unsafe_fn)]
44
#![unstable(feature = "wasi_ext", issue = "none")]
55

6+
use crate::ffi::OsStr;
67
use crate::fs::{self, File, Metadata, OpenOptions};
78
use crate::io::{self, IoSlice, IoSliceMut};
89
use crate::path::{Path, PathBuf};
9-
use crate::sys::fs::osstr2str;
1010
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
11+
// Used for `File::read` on intra-doc links
12+
#[allow(unused_imports)]
13+
use io::{Read, Write};
1114

1215
/// WASI-specific extensions to [`File`].
1316
pub trait FileExt {
@@ -54,11 +57,11 @@ pub trait FileExt {
5457
/// # Errors
5558
///
5659
/// If this function encounters an error of the kind
57-
/// [`ErrorKind::Interrupted`] then the error is ignored and the operation
60+
/// [`io::ErrorKind::Interrupted`] then the error is ignored and the operation
5861
/// will continue.
5962
///
6063
/// If this function encounters an "end of file" before completely filling
61-
/// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
64+
/// the buffer, it returns an error of the kind [`io::ErrorKind::UnexpectedEof`].
6265
/// The contents of `buf` are unspecified in this case.
6366
///
6467
/// If any other read error is encountered then this function immediately
@@ -131,16 +134,16 @@ pub trait FileExt {
131134
/// The current file cursor is not affected by this function.
132135
///
133136
/// This method will continuously call [`write_at`] until there is no more data
134-
/// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
137+
/// to be written or an error of non-[`io::ErrorKind::Interrupted`] kind is
135138
/// returned. This method will not return until the entire buffer has been
136139
/// successfully written or such an error occurs. The first error that is
137-
/// not of [`ErrorKind::Interrupted`] kind generated from this method will be
140+
/// not of [`io::ErrorKind::Interrupted`] kind generated from this method will be
138141
/// returned.
139142
///
140143
/// # Errors
141144
///
142145
/// This function will return the first error of
143-
/// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
146+
/// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns.
144147
///
145148
/// [`write_at`]: FileExt::write_at
146149
#[stable(feature = "rw_exact_all_at", since = "1.33.0")]
@@ -426,7 +429,7 @@ impl MetadataExt for fs::Metadata {
426429
}
427430
}
428431

429-
/// WASI-specific extensions for [`FileType`].
432+
/// WASI-specific extensions for [`fs::FileType`].
430433
///
431434
/// Adds support for special WASI file types such as block/character devices,
432435
/// pipes, and sockets.
@@ -517,8 +520,12 @@ pub fn symlink<P: AsRef<Path>, U: AsRef<Path>>(
517520

518521
/// Create a symbolic link.
519522
///
520-
/// This is a convenience API similar to [`std::os::unix::fs::symlink`] and
521-
/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir).
523+
/// This is a convenience API similar to `std::os::unix::fs::symlink` and
524+
/// `std::os::windows::fs::symlink_file` and `std::os::windows::fs::symlink_dir`.
522525
pub fn symlink_path<P: AsRef<Path>, U: AsRef<Path>>(old_path: P, new_path: U) -> io::Result<()> {
523526
crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref())
524527
}
528+
529+
fn osstr2str(f: &OsStr) -> io::Result<&str> {
530+
f.to_str().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "input must be utf-8"))
531+
}

library/std/src/sys/wasi/ext/io.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -145,36 +145,36 @@ impl IntoRawFd for fs::File {
145145

146146
impl AsRawFd for io::Stdin {
147147
fn as_raw_fd(&self) -> RawFd {
148-
sys::stdio::Stdin.as_raw_fd()
148+
libc::STDIN_FILENO
149149
}
150150
}
151151

152152
impl AsRawFd for io::Stdout {
153153
fn as_raw_fd(&self) -> RawFd {
154-
sys::stdio::Stdout.as_raw_fd()
154+
libc::STDOUT_FILENO
155155
}
156156
}
157157

158158
impl AsRawFd for io::Stderr {
159159
fn as_raw_fd(&self) -> RawFd {
160-
sys::stdio::Stderr.as_raw_fd()
160+
libc::STDERR_FILENO
161161
}
162162
}
163163

164164
impl<'a> AsRawFd for io::StdinLock<'a> {
165165
fn as_raw_fd(&self) -> RawFd {
166-
sys::stdio::Stdin.as_raw_fd()
166+
libc::STDIN_FILENO
167167
}
168168
}
169169

170170
impl<'a> AsRawFd for io::StdoutLock<'a> {
171171
fn as_raw_fd(&self) -> RawFd {
172-
sys::stdio::Stdout.as_raw_fd()
172+
libc::STDOUT_FILENO
173173
}
174174
}
175175

176176
impl<'a> AsRawFd for io::StderrLock<'a> {
177177
fn as_raw_fd(&self) -> RawFd {
178-
sys::stdio::Stderr.as_raw_fd()
178+
libc::STDERR_FILENO
179179
}
180180
}

library/std/src/sys/wasi/ext/mod.rs

+28
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,32 @@
1+
//! Platform-specific extensions to `std` for WASI.
2+
//!
3+
//! Provides access to platform-level information on WASI, and exposes
4+
//! WASI-specific functions that would otherwise be inappropriate as
5+
//! part of the core `std` library.
6+
//!
7+
//! It exposes more ways to deal with platform-specific strings (`OsStr`,
8+
//! `OsString`), allows to set permissions more granularly, extract low-level
9+
//! file descriptors from files and sockets, and has platform-specific helpers
10+
//! for spawning processes.
11+
//!
12+
//! # Examples
13+
//!
14+
//! ```no_run
15+
//! use std::fs::File;
16+
//! use std::os::wasi::prelude::*;
17+
//!
18+
//! fn main() -> std::io::Result<()> {
19+
//! let f = File::create("foo.txt")?;
20+
//! let fd = f.as_raw_fd();
21+
//!
22+
//! // use fd with native WASI bindings
23+
//!
24+
//! Ok(())
25+
//! }
26+
//! ```
27+
128
#![deny(unsafe_op_in_unsafe_fn)]
29+
#![doc(cfg(target_os = "wasi"))]
230

331
pub mod ffi;
432
pub mod fs;

0 commit comments

Comments
 (0)