From 7b53b7b659fe1feeb30e768cad8fdadf9531beb6 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Sun, 22 Dec 2019 12:55:09 -0800 Subject: doc: fill out `fs` and remove html links (#2015) also add an async version of `fs::canonicalize` --- tokio/src/fs/canonicalize.rs | 51 +++++ tokio/src/fs/create_dir.rs | 40 +++- tokio/src/fs/create_dir_all.rs | 40 +++- tokio/src/fs/file.rs | 20 +- tokio/src/fs/hard_link.rs | 31 ++- tokio/src/fs/metadata.rs | 38 +++- tokio/src/fs/mod.rs | 3 + tokio/src/fs/open_options.rs | 321 ++++++++++++++++++++++++++++++-- tokio/src/fs/os/unix/symlink.rs | 2 +- tokio/src/fs/os/windows/symlink_dir.rs | 2 +- tokio/src/fs/os/windows/symlink_file.rs | 2 +- tokio/src/fs/read.rs | 39 +++- tokio/src/fs/remove_file.rs | 8 +- tokio/src/io/stderr.rs | 4 +- tokio/src/io/util/copy.rs | 4 +- tokio/src/net/mod.rs | 12 +- tokio/src/park/mod.rs | 69 ++----- tokio/src/park/thread.rs | 4 +- tokio/src/process/mod.rs | 4 +- tokio/src/runtime/enter.rs | 2 - tokio/src/runtime/mod.rs | 12 +- tokio/src/sync/mpsc/bounded.rs | 4 +- tokio/src/sync/mpsc/mod.rs | 4 +- tokio/src/sync/mpsc/unbounded.rs | 4 +- tokio/src/time/driver/mod.rs | 10 +- tokio/src/time/mod.rs | 28 +-- 26 files changed, 605 insertions(+), 153 deletions(-) create mode 100644 tokio/src/fs/canonicalize.rs diff --git a/tokio/src/fs/canonicalize.rs b/tokio/src/fs/canonicalize.rs new file mode 100644 index 00000000..40366268 --- /dev/null +++ b/tokio/src/fs/canonicalize.rs @@ -0,0 +1,51 @@ +use crate::fs::asyncify; + +use std::io; +use std::path::{Path, PathBuf}; + +/// Returns the canonical, absolute form of a path with all intermediate +/// components normalized and symbolic links resolved. +/// +/// This is an async version of [`std::fs::canonicalize`][std] +/// +/// [std]: std::fs::canonicalize +/// +/// # Platform-specific behavior +/// +/// This function currently corresponds to the `realpath` function on Unix +/// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows. +/// Note that, this [may change in the future][changes]. +/// +/// On Windows, this converts the path to use [extended length path][path] +/// syntax, which allows your program to use longer path names, but means you +/// can only join backslash-delimited paths to it, and it may be incompatible +/// with other applications (if passed to the application on the command-line, +/// or written to a file another application may read). +/// +/// [changes]: https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior +/// [path]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// * `path` does not exist. +/// * A non-final component in path is not a directory. +/// +/// # Examples +/// +/// ```no_run +/// use tokio::fs; +/// use std::io; +/// +/// #[tokio::main] +/// async fn main() -> io::Result<()> { +/// let path = fs::canonicalize("../a/../foo.txt").await?; +/// Ok(()) +/// } +/// ``` +pub async fn canonicalize(path: impl AsRef) -> io::Result { + let path = path.as_ref().to_owned(); + asyncify(move || std::fs::canonicalize(path)).await +} diff --git a/tokio/src/fs/create_dir.rs b/tokio/src/fs/create_dir.rs index 99762058..e03b04dc 100644 --- a/tokio/src/fs/create_dir.rs +++ b/tokio/src/fs/create_dir.rs @@ -7,7 +7,45 @@ use std::path::Path; /// /// This is an async version of [`std::fs::create_dir`][std] /// -/// [std]: https://doc.rust-lang.org/std/fs/fn.create_dir.html +/// [std]: std::fs::create_dir +/// +/// # Platform-specific behavior +/// +/// This function currently corresponds to the `mkdir` function on Unix +/// and the `CreateDirectory` function on Windows. +/// Note that, this [may change in the future][changes]. +/// +/// [changes]: https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior +/// +/// **NOTE**: If a parent of the given path doesn't exist, this function will +/// return an error. To create a directory and all its missing parents at the +/// same time, use the [`create_dir_all`] function. +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// * User lacks permissions to create directory at `path`. +/// * A parent of the given path doesn't exist. (To create a directory and all +/// its missing parents at the same time, use the [`create_dir_all`] +/// function.) +/// * `path` already exists. +/// +/// [`create_dir_all`]: super::create_dir_all() +/// +/// # Examples +/// +/// ```no_run +/// use tokio::fs; +/// use std::io; +/// +/// #[tokio::main] +/// async fn main() -> io::Result<()> { +/// fs::create_dir("/some/dir").await?; +/// Ok(()) +/// } +/// ``` pub async fn create_dir(path: impl AsRef) -> io::Result<()> { let path = path.as_ref().to_owned(); asyncify(move || std::fs::create_dir(path)).await diff --git a/tokio/src/fs/create_dir_all.rs b/tokio/src/fs/create_dir_all.rs index 8c0c8df2..7d89280d 100644 --- a/tokio/src/fs/create_dir_all.rs +++ b/tokio/src/fs/create_dir_all.rs @@ -8,7 +8,45 @@ use std::path::Path; /// /// This is an async version of [`std::fs::create_dir_all`][std] /// -/// [std]: https://doc.rust-lang.org/std/fs/fn.create_dir_all.html +/// [std]: std::fs::create_dir_all +/// +/// # Platform-specific behavior +/// +/// This function currently corresponds to the `mkdir` function on Unix +/// and the `CreateDirectory` function on Windows. +/// Note that, this [may change in the future][changes]. +/// +/// [changes]: https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// * If any directory in the path specified by `path` does not already exist +/// and it could not be created otherwise. The specific error conditions for +/// when a directory is being created (after it is determined to not exist) are +/// outlined by [`fs::create_dir`]. +/// +/// Notable exception is made for situations where any of the directories +/// specified in the `path` could not be created as it was being created concurrently. +/// Such cases are considered to be successful. That is, calling `create_dir_all` +/// concurrently from multiple threads or processes is guaranteed not to fail +/// due to a race condition with itself. +/// +/// [`fs::create_dir`]: std::fs::create_dir +/// +/// # Examples +/// +/// ```no_run +/// use tokio::fs; +/// +/// #[tokio::main] +/// async fn main() -> std::io::Result<()> { +/// fs::create_dir_all("/some/dir").await?; +/// Ok(()) +/// } +/// ``` pub async fn create_dir_all(path: impl AsRef) -> io::Result<()> { let path = path.as_ref().to_owned(); asyncify(move || std::fs::create_dir_all(path)).await diff --git a/tokio/src/fs/file.rs b/tokio/src/fs/file.rs index a2f64e56..301d2380 100644 --- a/tokio/src/fs/file.rs +++ b/tokio/src/fs/file.rs @@ -1,6 +1,6 @@ //! Types for working with [`File`]. //! -//! [`File`]: file/struct.File.html +//! [`File`]: File use self::State::*; use crate::fs::{asyncify, sys}; @@ -29,7 +29,7 @@ use std::task::Poll::*; /// /// Files are automatically closed when they go out of scope. /// -/// [std]: https://doc.rust-lang.org/std/fs/struct.File.html +/// [std]: std::fs::File /// /// # Examples /// @@ -90,7 +90,7 @@ impl File { /// /// See [`OpenOptions`] for more details. /// - /// [`OpenOptions`]: struct.OpenOptions.html + /// [`OpenOptions`]: super::OpenOptions /// /// # Errors /// @@ -128,14 +128,14 @@ impl File { /// /// See [`OpenOptions`] for more details. /// - /// [`OpenOptions`]: struct.OpenOptions.html + /// [`OpenOptions`]: super::OpenOptions /// /// # Errors /// /// Results in an error if called from outside of the Tokio runtime or if /// the underlying [`create`] call results in an error. /// - /// [`create`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.create + /// [`create`]: std::fs::File::create /// /// # Examples /// @@ -155,10 +155,10 @@ impl File { Ok(File::from_std(std_file)) } - /// Convert a [`std::fs::File`][std] to a [`tokio_fs::File`][file]. + /// Convert a [`std::fs::File`][std] to a [`tokio::fs::File`][file]. /// - /// [std]: https://doc.rust-lang.org/std/fs/struct.File.html - /// [file]: struct.File.html + /// [std]: std::fs::File + /// [file]: File /// /// # Examples /// @@ -399,6 +399,8 @@ impl File { /// /// Use `File::try_into_std` to attempt conversion immediately. /// + /// [std]: std::fs::File + /// /// # Examples /// /// ```no_run @@ -417,6 +419,8 @@ impl File { /// Tries to immediately destructure `File` into a [`std::fs::File`][std]. /// + /// [std]: std::fs::File + /// /// # Errors /// /// This function will return an error containing the file if some diff --git a/tokio/src/fs/hard_link.rs b/tokio/src/fs/hard_link.rs index e3a32afc..50cc17d2 100644 --- a/tokio/src/fs/hard_link.rs +++ b/tokio/src/fs/hard_link.rs @@ -5,12 +5,39 @@ use std::path::Path; /// Creates a new hard link on the filesystem. /// +/// This is an async version of [`std::fs::hard_link`][std] +/// +/// [std]: std::fs::hard_link +/// /// The `dst` path will be a link pointing to the `src` path. Note that systems /// often require these two paths to both be located on the same filesystem. /// -/// This is an async version of [`std::fs::hard_link`][std] +/// # Platform-specific behavior +/// +/// This function currently corresponds to the `link` function on Unix +/// and the `CreateHardLink` function on Windows. +/// Note that, this [may change in the future][changes]. +/// +/// [changes]: https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// * The `src` path is not a file or doesn't exist. +/// +/// # Examples +/// +/// ```no_run +/// use tokio::fs; /// -/// [std]: https://doc.rust-lang.org/std/fs/fn.hard_link.html +/// #[tokio::main] +/// async fn main() -> std::io::Result<()> { +/// fs::hard_link("a.txt", "b.txt").await?; // Hard link a.txt to b.txt +/// Ok(()) +/// } +/// ``` pub async fn hard_link(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { let src = src.as_ref().to_owned(); let dst = dst.as_ref().to_owned(); diff --git a/tokio/src/fs/metadata.rs b/tokio/src/fs/metadata.rs index 3a830db3..6bbb44ad 100644 --- a/tokio/src/fs/metadata.rs +++ b/tokio/src/fs/metadata.rs @@ -4,7 +4,43 @@ use std::fs::Metadata; use std::io; use std::path::Path; -/// Queries the file system metadata for a path. +/// Given a path, query the file system to get information about a file, +/// directory, etc. +/// +/// This is an async version of [`std::fs::metadata`][std] +/// +/// This function will traverse symbolic links to query information about the +/// destination file. +/// +/// # Platform-specific behavior +/// +/// This function currently corresponds to the `stat` function on Unix and the +/// `GetFileAttributesEx` function on Windows. Note that, this [may change in +/// the future][changes]. +/// +/// [std]: std::fs::metadata +/// [changes]: https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// * The user lacks permissions to perform `metadata` call on `path`. +/// * `path` does not exist. +/// +/// # Examples +/// +/// ```rust,no_run +/// use tokio::fs; +/// +/// #[tokio::main] +/// async fn main() -> std::io::Result<()> { +/// let attr = fs::metadata("/some/file/path.txt").await?; +/// // inspect attr ... +/// Ok(()) +/// } +/// ``` pub async fn metadata(path: impl AsRef) -> io::Result { let path = path.as_ref().to_owned(); asyncify(|| std::fs::metadata(path)).await diff --git a/tokio/src/fs/mod.rs b/tokio/src/fs/mod.rs index c462bf4b..266364b9 100644 --- a/tokio/src/fs/mod.rs +++ b/tokio/src/fs/mod.rs @@ -24,6 +24,9 @@ //! //! [`AsyncRead`]: https://docs.rs/tokio-io/0.1/tokio_io/trait.AsyncRead.html +mod canonicalize; +pub use self::canonicalize::canonicalize; + mod create_dir; pub use self::create_dir::create_dir; diff --git a/tokio/src/fs/open_options.rs b/tokio/src/fs/open_options.rs index 8931247f..3210f4b7 100644 --- a/tokio/src/fs/open_options.rs +++ b/tokio/src/fs/open_options.rs @@ -5,13 +5,69 @@ use std::path::Path; /// Options and flags which can be used to configure how a file is opened. /// +/// This builder exposes the ability to configure how a [`File`] is opened and +/// what operations are permitted on the open file. The [`File::open`] and +/// [`File::create`] methods are aliases for commonly used options using this +/// builder. +/// +/// Generally speaking, when using `OpenOptions`, you'll first call [`new`], +/// then chain calls to methods to set each option, then call [`open`], passing +/// the path of the file you're trying to open. This will give you a +/// [`io::Result`][result] with a [`File`] inside that you can further operate +/// on. +/// /// This is a specialized version of [`std::fs::OpenOptions`] for usage from /// the Tokio runtime. /// /// `From` is implemented for more advanced configuration /// than the methods provided here. /// -/// [`std::fs::OpenOptions`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html +/// [`new`]: OpenOptions::new +/// [`open`]: OpenOptions::open +/// [result]: std::io::Result +/// [`File`]: File +/// [`File::open`]: File::open +/// [`File::create`]: File::create +/// [`std::fs::OpenOptions`]: std::fs::OpenOptions +/// +/// # Examples +/// +/// Opening a file to read: +/// +/// ```no_run +/// use tokio::fs::OpenOptions; +/// use std::io; +/// +/// #[tokio::main] +/// async fn main() -> io::Result<()> { +/// let file = OpenOptions::new() +/// .read(true) +/// .open("foo.txt") +/// .await?; +/// +/// Ok(()) +/// } +/// ``` +/// +/// Opening a file for both reading and writing, as well as creating it if it +/// doesn't exist: +/// +/// ```no_run +/// use tokio::fs::OpenOptions; +/// use std::io; +/// +/// #[tokio::main] +/// async fn main() -> io::Result<()> { +/// let file = OpenOptions::new() +/// .read(true) +/// .write(true) +/// .create(true) +/// .open("foo.txt") +/// .await?; +/// +/// Ok(()) +/// } +/// ``` #[derive(Clone, Debug)] pub struct OpenOptions(std::fs::OpenOptions); @@ -20,9 +76,13 @@ impl OpenOptions { /// /// All options are initially set to `false`. /// + /// This is an async version of [`std::fs::OpenOptions::new`][std] + /// + /// [std]: std::fs::OpenOptions::new + /// /// # Examples /// - /// ```ignore + /// ```no_run /// use tokio::fs::OpenOptions; /// /// let mut options = OpenOptions::new(); @@ -32,49 +92,232 @@ impl OpenOptions { OpenOptions(std::fs::OpenOptions::new()) } - /// See the underlying [`read`] call for details. + /// Sets the option for read access. + /// + /// This option, when true, will indicate that the file should be + /// `read`-able if opened. /// - /// [`read`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.read + /// This is an async version of [`std::fs::OpenOptions::read`][std] + /// + /// [std]: std::fs::OpenOptions::read + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; + /// + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new() + /// .read(true) + /// .open("foo.txt") + /// .await?; + /// + /// Ok(()) + /// } + /// ``` pub fn read(&mut self, read: bool) -> &mut OpenOptions { self.0.read(read); self } - /// See the underlying [`write`] call for details. + /// Sets the option for write access. /// - /// [`write`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.write + /// This option, when true, will indicate that the file should be + /// `write`-able if opened. + /// + /// This is an async version of [`std::fs::OpenOptions::write`][std] + /// + /// [std]: std::fs::OpenOptions::write + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; + /// + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new() + /// .write(true) + /// .open("foo.txt") + /// .await?; + /// + /// Ok(()) + /// } + /// ``` pub fn write(&mut self, write: bool) -> &mut OpenOptions { self.0.write(write); self } - /// See the underlying [`append`] call for details. + /// Sets the option for the append mode. + /// + /// This option, when true, means that writes will append to a file instead + /// of overwriting previous contents. Note that setting + /// `.write(true).append(true)` has the same effect as setting only + /// `.append(true)`. + /// + /// For most filesystems, the operating system guarantees that all writes are + /// atomic: no writes get mangled because another process writes at the same + /// time. + /// + /// One maybe obvious note when using append-mode: make sure that all data + /// that belongs together is written to the file in one operation. This + /// can be done by concatenating strings before passing them to [`write()`], + /// or using a buffered writer (with a buffer of adequate size), + /// and calling [`flush()`] when the message is complete. + /// + /// If a file is opened with both read and append access, beware that after + /// opening, and after every write, the position for reading may be set at the + /// end of the file. So, before writing, save the current position (using + /// [`seek`]`(`[`SeekFrom`]`::`[`Current`]`(0))`), and restore it before the next read. + /// + /// This is an async version of [`std::fs::OpenOptions::append`][std] + /// + /// [std]: std::fs::OpenOptions::append + /// + /// ## Note + /// + /// This function doesn't create the file if it doesn't exist. Use the [`create`] + /// method to do so. + /// + /// [`write()`]: crate::io::AsyncWriteExt::write + /// [`flush()`]: crate::io::AsyncWriteExt::flush + /// [`seek`]: crate::io::AsyncSeekExt::seek + /// [`SeekFrom`]: std::io::SeekFrom + /// [`Current`]: std::io::SeekFrom::Current + /// [`create`]: OpenOptions::create + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; /// - /// [`append`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.append + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new() + /// .append(true) + /// .open("foo.txt") + /// .await?; + /// + /// Ok(()) + /// } + /// ``` pub fn append(&mut self, append: bool) -> &mut OpenOptions { self.0.append(append); self } - /// See the underlying [`truncate`] call for details. + /// Sets the option for truncating a previous file. + /// + /// If a file is successfully opened with this option set it will truncate + /// the file to 0 length if it already exists. + /// + /// The file must be opened with write access for truncate to work. + /// + /// This is an async version of [`std::fs::OpenOptions::truncate`][std] + /// + /// [std]: std::fs::OpenOptions::truncate + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; + /// + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new() + /// .write(true) + /// .truncate(true) + /// .open("foo.txt") + /// .await?; /// - /// [`truncate`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.truncate + /// Ok(()) + /// } + /// ``` pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions { self.0.truncate(truncate); self } - /// See the underlying [`create`] call for details. + /// Sets the option for creating a new file. + /// + /// This option indicates whether a new file will be created if the file + /// does not yet already exist. + /// + /// In order for the file to be created, [`write`] or [`append`] access must + /// be used. /// - /// [`create`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create + /// This is an async version of [`std::fs::OpenOptions::create`][std] + /// + /// [std]: std::fs::OpenOptions::create + /// [`write`]: OpenOptions::write + /// [`append`]: OpenOptions::append + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; + /// + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new() + /// .write(true) + /// .create(true) + /// .open("foo.txt") + /// .await?; + /// + /// Ok(()) + /// } + /// ``` pub fn create(&mut self, create: bool) -> &mut OpenOptions { self.0.create(create); self } - /// See the underlying [`create_new`] call for details. + /// Sets the option to always create a new file. /// - /// [`create_new`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new + /// This option indicates whether a new file will be created. No file is + /// allowed to exist at the target location, also no (dangling) symlink. + /// + /// This option is useful because it is atomic. Otherwise between checking + /// whether a file exists and creating a new one, the file may have been + /// created by another process (a TOCTOU race condition / attack). + /// + /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are + /// ignored. + /// + /// The file must be opened with write or append access in order to create a + /// new file. + /// + /// This is an async version of [`std::fs::OpenOptions::create_new`][std] + /// + /// [std]: std::fs::OpenOptions::create_new + /// [`.create()`]: OpenOptions::create + /// [`.truncate()`]: OpenOptions::truncate + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; + /// + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new() + /// .write(true) + /// .create_new(true) + /// .open("foo.txt") + /// .await?; + /// + /// Ok(()) + /// } + /// ``` pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions { self.0.create_new(create_new); self @@ -82,12 +325,56 @@ impl OpenOptions { /// Opens a file at `path` with the options specified by `self`. /// + /// This is an async version of [`std::fs::OpenOptions::open`][std] + /// + /// [std]: std::fs::OpenOptions::open + /// /// # Errors /// - /// `OpenOptionsFuture` results in an error if called from outside of the - /// Tokio runtime or if the underlying [`open`] call results in an error. + /// This function will return an error under a number of different + /// circumstances. Some of these error conditions are listed here, together + /// with their [`ErrorKind`]. The mapping to [`ErrorKind`]s is not part of + /// the compatibility contract of the function, especially the `Other` kind + /// might change to more specific kinds in the future. + /// + /// * [`NotFound`]: The specified file does not exist and neither `create` + /// or `create_new` is set. + /// * [`NotFound`]: One of the directory components of the file path does + /// not exist. + /// * [`PermissionDenied`]: The user lacks permission to get the specified + /// access rights for the file. + /// * [`PermissionDenied`]: The user lacks permission to open one of the + /// directory components of the specified path. + /// * [`AlreadyExists`]: `create_new` was specified and the file already + /// exists. + /// * [`InvalidInput`]: Invalid combinations of open options (truncate + /// without write access, no access mode set, etc.). + /// * [`Other`]: One of the directory components of the specified file path + /// was not, in fact, a directory. + /// * [`Other`]: Filesystem-level errors: full disk, write permission + /// requested on a read-only file system, exceeded disk quota, too many + /// open files, too long filename, too many symbolic links in the + /// specified path (Unix-like systems only), etc. + /// + /// # Examples + /// + /// ```no_run + /// use tokio::fs::OpenOptions; + /// use std::io; + /// + /// #[tokio::main] + /// async fn main() -> io::Result<()> { + /// let file = OpenOptions::new().open("foo.txt").await?; + /// Ok(()) + /// } + /// ``` /// - /// [`open`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open + /// [`ErrorKind`]: std::io::ErrorKind + /// [`AlreadyExists`]: std::io::ErrorKind::AlreadyExists + /// [`InvalidInput`]: std::io::ErrorKind::InvalidInput + /// [`NotFound`]: std::io::ErrorKind::NotFound + /// [`Other`]: std::io::ErrorKind::Other + /// [`PermissionDenied`]: std::io::ErrorKind::PermissionDenied pub async fn open(&self, path: impl AsRef) -> io::Result { let path = path.as_ref().to_owned(); let opts = self.0.clone(); diff --git a/tokio/src/fs/os/unix/symlink.rs b/tokio/src/fs/os/unix/symlink.rs index 3d539446..22ece725 100644 --- a/tokio/src/fs/os/unix/symlink.rs +++ b/tokio/src/fs/os/unix/symlink.rs @@ -9,7 +9,7 @@ use std::path::Path; /// /// This is an async version of [`std::os::unix::fs::symlink`][std] /// -/// [std]: https://doc.rust-lang.org/std/os/unix/fs/fn.symlink.html +/// [std]: std::os::unix::fs::symlink pub async fn symlink(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { let src = src.as_ref().to_owned(); let dst = dst.as_ref().to_owned(); diff --git a/tokio/src/fs/os/windows/symlink_dir.rs b/tokio/src/fs/os/windows/symlink_dir.rs index 6753c25e..736e762b 100644 --- a/tokio/src/fs/os/windows/symlink_dir.rs +++ b/tokio/src/fs/os/windows/symlink_dir.rs @@ -10,7 +10,7 @@ use std::path::Path; /// /// This is an async version of [`std::os::windows::fs::symlink_dir`][std] /// -/// [std]: https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_dir.html +/// [std]: std::os::windows::fs::symlink_dir pub async fn symlink_dir(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { let src = src.as_ref().to_owned(); let dst = dst.as_ref().to_owned(); diff --git a/tokio/src/fs/os/windows/symlink_file.rs b/tokio/src/fs/os/windows/symlink_file.rs index 623352a1..07d8e604 100644 --- a/tokio/src/fs/os/windows/symlink_file.rs +++ b/tokio/src/fs/os/windows/symlink_file.rs @@ -10,7 +10,7 @@ use std::path::Path; /// /// This is an async version of [`std::os::windows::fs::symlink_file`][std] /// -/// [std]: https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_file.html +/// [std]: std::os::windows::fs::symlink_file pub async fn symlink_file(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { let src = src.as_ref().to_owned(); let dst = dst.as_ref().to_owned(); diff --git a/tokio/src/fs/read.rs b/tokio/src/fs/read.rs index 796acbf8..f61275d0 100644 --- a/tokio/src/fs/read.rs +++ b/tokio/src/fs/read.rs @@ -2,21 +2,44 @@ use crate::fs::asyncify; use std::{io, path::Path}; -/// Creates a future which will open a file for reading and read the entire -/// contents into a buffer and return said buffer. +/// Read the entire contents of a file into a bytes vector. /// -/// This is the async equivalent of `std::fs::read`. +/// This is an async version of [`std::fs::read`][std] +/// +/// [std]: std::fs::read +/// +/// This is a convenience function for using [`File::open`] and [`read_to_end`] +/// with fewer imports and without an intermediate variable. It pre-allocates a +/// buffer based on the file size when available, so it is generally faster than +/// reading into a vector created with `Vec::new()`. +/// +/// [`File::open`]: super::File::open +/// [`read_to_end`]: crate::io::AsyncReadExt::read_to_end +/// +/// # Errors +/// +/// This function will return an error if `path` does not already exist. +/// Other errors may also be returned according to [`OpenOptions::open`]. +/// +/// [`OpenOptions::open`]: super::OpenOptions::open +/// +/// It will also return an error if it encounters while reading an error +/// of a kind other than [`ErrorKind::Interrupted`]. +/// +/// [`ErrorKind::Interrupted`]: std::io::ErrorKind::Interrupted /// /// # Examples /// /// ```no_run /// use tokio::fs; +/// use std::net::SocketAddr; /// -/// # async fn dox() -> std::io::Result<()> { -/// let contents = fs::read("foo.txt").await?; -/// println!("foo.txt contains {} bytes", contents.len()); -/// # Ok(()) -/// # } +/// #[tokio::main] +/// async fn main() -> Result<(), Box> { +/// let contents = fs::read("address.txt").await?; +/// let foo: SocketAddr = String::from_utf8_lossy(&contents).parse()?; +/// Ok(()) +/// } /// ``` pub async fn read(path: impl AsRef) -> io::Result> { let path = path.as_ref().to_owned(); diff --git a/tokio/src/fs/remove_file.rs b/tokio/src/fs/remove_file.rs index 8ab162ca..d22a5bfc 100644 --- a/tokio/src/fs/remove_file.rs +++ b/tokio/src/fs/remove_file.rs @@ -5,13 +5,13 @@ use std::path::Path; /// Removes a file from the filesystem. /// -/// Note that there is no -/// guarantee that the file is immediately deleted (e.g. depending on -/// platform, other open file descriptors may prevent immediate removal). +/// Note that there is no guarantee that the file is immediately deleted (e.g. +/// depending on platform, other open file descriptors may prevent immediate +/// removal). /// /// This is an async version of [`std::fs::remove_file`][std] /// -/// [std]: https://doc.rust-lang.org/std/fs/fn.remove_file.html +/// [std]: std::fs::remove_file pub async fn remove_file(path: impl AsRef) -> io::Result<()> { let path = path.as_ref().to_owned(); asyncify(move || std::fs::remove_file(path)).await diff --git a/tokio/src/io/stderr.rs b/tokio/src/io/stderr.rs index 231941f2..d91dd481 100644 --- a/tokio/src/io/stderr.rs +++ b/tokio/src/io/stderr.rs @@ -14,8 +14,8 @@ cfg_io_std! { /// /// Created by the [`stderr`] function. /// - /// [`stderr`]: fn.stderr.html - /// [`AsyncWrite`]: trait.AsyncWrite.html + /// [`stderr`]: stderr() + /// [`AsyncWrite`]: AsyncWrite #[derive(Debug)] pub struct Stderr { std: Blocking, diff --git a/tokio/src/io/util/copy.rs b/tokio/src/io/util/copy.rs index 312ff360..0a2aea73 100644 --- a/tokio/src/io/util/copy.rs +++ b/tokio/src/io/util/copy.rs @@ -12,7 +12,7 @@ cfg_io_util! { /// This struct is generally created by calling [`copy`][copy]. Please /// see the documentation of `copy()` for more details. /// - /// [copy]: fn.copy.html + /// [copy]: copy() #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Copy<'a, R: ?Sized, W: ?Sized> { @@ -57,7 +57,7 @@ cfg_io_util! { /// # } /// ``` /// - /// [std]: https://doc.rust-lang.org/std/io/fn.copy.html + /// [std]: std::io::copy pub fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W> where R: AsyncRead + Unpin + ?Sized, diff --git a/tokio/src/net/mod.rs b/tokio/src/net/mod.rs index 83b12fd2..eb24ac0b 100644 --- a/tokio/src/net/mod.rs +++ b/tokio/src/net/mod.rs @@ -15,12 +15,12 @@ //! over Unix Domain Datagram Socket **(available on Unix only)** //! -//! [`TcpListener`]: struct.TcpListener.html -//! [`TcpStream`]: struct.TcpStream.html -//! [`UdpSocket`]: struct.UdpSocket.html -//! [`UnixListener`]: struct.UnixListener.html -//! [`UnixStream`]: struct.UnixStream.html -//! [`UnixDatagram`]: struct.UnixDatagram.html +//! [`TcpListener`]: TcpListener +//! [`TcpStream`]: TcpStream +//! [`UdpSocket`]: UdpSocket +//! [`UnixListener`]: UnixListener +//! [`UnixStream`]: UnixStream +//! [`UnixDatagram`]: UnixDatagram mod addr; pub use addr::ToSocketAddrs; diff --git a/tokio/src/park/mod.rs b/tokio/src/park/mod.rs index e6b0c72b..9c1958c3 100644 --- a/tokio/src/park/mod.rs +++ b/tokio/src/park/mod.rs @@ -1,48 +1,38 @@ //! Abstraction over blocking and unblocking the current thread. //! //! Provides an abstraction over blocking the current thread. This is similar to -//! the park / unpark constructs provided by [`std`] but made generic. This -//! allows embedding custom functionality to perform when the thread is blocked. +//! the park / unpark constructs provided by `std` but made generic. This allows +//! embedding custom functionality to perform when the thread is blocked. //! -//! A blocked [`Park`][p] instance is unblocked by calling [`unpark`] on its -//! [`Unpark`][up] handle. +//! A blocked `Park` instance is unblocked by calling `unpark` on its +//! `Unpark` handle. //! -//! The [`ParkThread`] struct implements [`Park`][p] using -//! [`thread::park`][`std`] to put the thread to sleep. The Tokio reactor also -//! implements park, but uses [`mio::Poll`][mio] to block the thread instead. +//! The `ParkThread` struct implements `Park` using `thread::park` to put the +//! thread to sleep. The Tokio reactor also implements park, but uses +//! `mio::Poll` to block the thread instead. //! -//! The [`Park`][p] trait is composable. A timer implementation might decorate a -//! [`Park`][p] implementation by checking if any timeouts have elapsed after -//! the inner [`Park`][p] implementation unblocks. +//! The `Park` trait is composable. A timer implementation might decorate a +//! `Park` implementation by checking if any timeouts have elapsed after the +//! inner `Park` implementation unblocks. //! //! # Model //! -//! Conceptually, each [`Park`][p] instance has an associated token, which is +//! Conceptually, each `Park` instance has an associated token, which is //! initially not present: //! -//! * The [`park`] method blocks the current thread unless or until the token -//! is available, at which point it atomically consumes the token. -//! * The [`unpark`] method atomically makes the token available if it wasn't +//! * The `park` method blocks the current thread unless or until the token is +//! available, at which point it atomically consumes the token. +//! * The `unpark` method atomically makes the token available if it wasn't //! already. //! //! Some things to note: //! -//! * If [`unpark`] is called before [`park`], the next call to [`park`] will +//! * If `unpark` is called before `park`, the next call to `park` will //! **not** block the thread. -//! * **Spurious** wakeups are permitted, i.e., the [`park`] method may unblock -//! even if [`unpark`] was not called. -//! * [`park_timeout`] does the same as [`park`] but allows specifying a maximum +//! * **Spurious** wakeups are permitted, i.e., the `park` method may unblock +//! even if `unpark` was not called. +//! * `park_timeout` does the same as `park` but allows specifying a maximum //! time to block the thread for. -//! -//! [`std`]: https://doc.rust-lang.org/std/thread/fn.park.html -//! [`thread::park`]: https://doc.rust-lang.org/std/thread/fn.park.html -//! [`ParkThread`]: struct.ParkThread.html -//! [p]: trait.Park.html -//! [`park`]: trait.Park.html#tymethod.park -//! [`park_timeout`]: trait.Park.html#tymethod.park_timeout -//! [`unpark`]: trait.Unpark.html#tymethod.unpark -//! [up]: trait.Unpark.html -//! [mio]: https://docs.rs/mio/0.6/mio/struct.Poll.html cfg_resource_drivers! { mod either; @@ -60,10 +50,6 @@ use std::sync::Arc; use std::time::Duration; /// Block the current thread. -/// -/// See [module documentation][mod] for more details. -/// -/// [mod]: ../index.html pub(crate) trait Park { /// Unpark handle type for the `Park` implementation. type Unpark: Unpark; @@ -80,15 +66,11 @@ pub(crate) trait Park { /// forever, and callers should be prepared for this possibility. This /// function may wakeup spuriously for any reason. /// - /// See [module documentation][mod] for more details. - /// /// # Panics /// /// This function **should** not panic, but ultimately, panics are left as /// an implementation detail. Refer to the documentation for the specific /// `Park` implementation - /// - /// [mod]: ../index.html fn park(&mut self) -> Result<(), Self::Error>; /// Park the current thread for at most `duration`. @@ -100,39 +82,26 @@ pub(crate) trait Park { /// blocked for any amount of time. Spurious wakeups are permitted for any /// reason. /// - /// See [module documentation][mod] for more details. - /// /// # Panics /// /// This function **should** not panic, but ultimately, panics are left as /// an implementation detail. Refer to the documentation for the specific /// `Park` implementation - /// - /// [mod]: ../index.html fn park_timeout(&mut self, duration: Duration) -> Result<(), Self::Error>; } -/// Unblock a thread blocked by the associated [`Park`] instance. -/// -/// See [module documentation][mod] for more details. -/// -/// [mod]: ../index.html -/// [`Park`]: trait.Park.html +/// Unblock a thread blocked by the associated `Park` instance. pub(crate) trait Unpark: Sync + Send + 'static { /// Unblock a thread that is blocked by the associated `Park` handle. /// /// Calling `unpark` atomically makes available the unpark token, if it is /// not already available. /// - /// See [module documentation][mod] for more details. - /// /// # Panics /// /// This function **should** not panic, but ultimately, panics are left as /// an implementation detail. Refer to the documentation for the specific /// `Unpark` implementation - /// - /// [mod]: ../index.html fn unpark(&self); } diff --git a/tokio/src/park/thread.rs b/tokio/src/park/thread.rs index 894e5301..59513e1d 100644 --- a/tokio/src/park/thread.rs +++ b/tokio/src/park/thread.rs @@ -10,11 +10,9 @@ pub(crate) struct ParkThread { inner: Arc, } -/// Error returned by [`ParkThread`] +/// Error returned by `ParkThread` /// /// This currently is never returned, but might at some point in the future. -/// -/// [`ParkThread`]: struct.ParkThread.html #[derive(Debug)] pub(crate) struct ParkError { _p: (), diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index 8dc2133c..17ae0539 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -348,6 +348,8 @@ impl Command { /// platform specific and unstable, and it's recommended to use /// [`canonicalize`] to get an absolute program path instead. /// + /// [`canonicalize`]: crate::fs::canonicalize() + /// /// # Examples /// /// Basic usage: @@ -358,8 +360,6 @@ impl Command { /// let command = Command::new("ls") /// .current_dir("/bin"); /// ``` - /// - /// [`canonicalize`]: ../fs/fn.canonicalize.html pub fn current_dir>(&mut self, dir: P) -> &mut Command { self.std.current_dir(dir); self diff --git a/tokio/src/runtime/enter.rs b/tokio/src/runtime/enter.rs index 1995da63..b716c2a9 100644 --- a/tokio/src/runtime/enter.rs +++ b/tokio/src/runtime/enter.rs @@ -5,8 +5,6 @@ use std::marker::PhantomData; thread_local!(static ENTERED: Cell = Cell::new(false)); /// Represents an executor context. -/// -/// For more details, see [`enter` documentation](fn.enter.html) pub(crate) struct Enter { _p: PhantomData>, } diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index 11c8d6b7..800df861 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -4,7 +4,7 @@ //! runtime support. In particular, the following runtime services are //! necessary: //! -//! * An **I/O event loop**, called the [driver], which drives I/O resources and +//! * An **I/O event loop**, called the driver, which drives I/O resources and //! dispatches I/O events to tasks that depend on them. //! * A **scheduler** to execute [tasks] that use these I/O resources. //! * A **timer** for scheduling work to run after a set period of time. @@ -172,13 +172,9 @@ //! Any tasks that have not yet completed will be dropped. //! //! [tasks]: crate::task -//! [driver]: crate::io::driver -//! [executor]: https://tokio.rs/docs/internals/runtime-model/#executors -//! [`Runtime`]: struct.Runtime.html -//! [`Reactor`]: ../reactor/struct.Reactor.html -//! [`run`]: fn.run.html -//! [`tokio::spawn`]: ../executor/fn.spawn.html -//! [`tokio::main`]: ../../tokio_macros/attr.main.html +//! [`Runtime`]: Runtime +//! [`tokio::spawn`]: crate::spawn +//! [`tokio::main`]: ../attr.main.html //! [runtime builder]: crate::runtime::Builder //! [`Runtime::new`]: crate::runtime::Runtime::new //! [`Builder::basic_scheduler`]: crate::runtime::Builder::basic_scheduler diff --git a/tokio/src/sync/mpsc/bounded.rs b/tokio/src/sync/mpsc/bounded.rs index 7c7a5abb..da3bd638 100644 --- a/tokio/src/sync/mpsc/bounded.rs +++ b/tokio/src/sync/mpsc/bounded.rs @@ -7,7 +7,7 @@ use std::task::{Context, Poll}; /// Send values to the associated `Receiver`. /// -/// Instances are created by the [`channel`](fn.channel.html) function. +/// Instances are created by the [`channel`](channel) function. pub struct Sender { chan: chan::Tx, } @@ -30,7 +30,7 @@ impl fmt::Debug for Sender { /// Receive values from the associated `Sender`. /// -/// Instances are created by the [`channel`](fn.channel.html) function. +/// Instances are created by the [`channel`](channel) function. pub struct Receiver { /// The channel receiver chan: chan::Rx, diff --git a/tokio/src/sync/mpsc/mod.rs b/tokio/src/sync/mpsc/mod.rs index 60ae60cd..4cfd6150 100644 --- a/tokio/src/sync/mpsc/mod.rs +++ b/tokio/src/sync/mpsc/mod.rs @@ -33,8 +33,8 @@ //! consumes the channel to completion, at which point the receiver can be //! dropped. //! -//! [`Sender`]: struct.Sender.html -//! [`Receiver`]: struct.Receiver.html +//! [`Sender`]: crate::sync::mpsc::Sender +//! [`Receiver`]: crate::sync::mpsc::Receiver pub(super) mod block; diff --git a/tokio/src/sync/mpsc/unbounded.rs b/tokio/src/sync/mpsc/unbounded.rs index 63d04370..d1222f28 100644 --- a/tokio/src/sync/mpsc/unbounded.rs +++ b/tokio/src/sync/mpsc/unbounded.rs @@ -8,7 +8,7 @@ use std::task::{Context, Poll}; /// Send values to the associated `UnboundedReceiver`. /// /// Instances are created by the -/// [`unbounded_channel`](fn.unbounded_channel.html) function. +/// [`unbounded_channel`](unbounded_channel) function. pub struct UnboundedSender { chan: chan::Tx, } @@ -32,7 +32,7 @@ impl fmt::Debug for UnboundedSender { /// Receive values from the associated `UnboundedSender`. /// /// Instances are created by the -/// [`unbounded_channel`](fn.unbounded_channel.html) function. +/// [`unbounded_channel`](unbounded_channel) function. pub struct UnboundedReceiver { /// The channel receiver chan: chan::Rx, diff --git a/tokio/src/time/driver/mod.rs b/tokio/src/time/driver/mod.rs index 4a1ba4fe..5d487423 100644 --- a/tokio/src/time/driver/mod.rs +++ b/tokio/src/time/driver/mod.rs @@ -70,19 +70,11 @@ use std::{cmp, fmt}; /// * Level 5: 64 x ~12 day slots. /// /// When the timer processes entries at level zero, it will notify all the -/// [`Delay`] instances as their deadlines have been reached. For all higher +/// `Delay` instances as their deadlines have been reached. For all higher /// levels, all entries will be redistributed across the wheel at the next level /// down. Eventually, as time progresses, entries will [`Delay`] instances will /// either be canceled (dropped) or their associated entries will reach level /// zero and be notified. -/// -/// [`Delay`]: struct.Delay.html -/// [`Interval`]: struct.Interval.html -/// [`Timeout`]: struct.Timeout.html -/// [paper]: http://www.cs.columbia.edu/~nahum/w6998/papers/ton97-timing-wheels.pdf -/// [`handle`]: #method.handle -/// [`turn`]: #method.turn -/// [Handle.struct]: struct.Handle.html #[derive(Debug)] pub(crate) struct Driver { /// Shared state diff --git a/tokio/src/time/mod.rs b/tokio/src/time/mod.rs index 4193dc15..24aae11e 100644 --- a/tokio/src/time/mod.rs +++ b/tokio/src/time/mod.rs @@ -5,25 +5,24 @@ //! This module provides a number of types for executing code after a set period //! of time. //! -//! * [`Delay`][Delay] is a future that does no work and completes at a specific `Instant` +//! * `Delay` is a future that does no work and completes at a specific `Instant` //! in time. //! -//! * [`Interval`][Interval] is a stream yielding a value at a fixed period. It -//! is initialized with a `Duration` and repeatedly yields each time the -//! duration elapses. +//! * `Interval` is a stream yielding a value at a fixed period. It is +//! initialized with a `Duration` and repeatedly yields each time the duration +//! elapses. //! -//! * [`Timeout`][Timeout]: Wraps a future or stream, setting an upper bound to the -//! amount of time it is allowed to execute. If the future or stream does not +//! * `Timeout`: Wraps a future or stream, setting an upper bound to the amount +//! of time it is allowed to execute. If the future or stream does not //! complete in time, then it is canceled and an error is returned. //! -//! * [`DelayQueue`]: A queue where items are returned once the requested delay +//! * `DelayQueue`: A queue where items are returned once the requested delay //! has expired. //! //! These types are sufficient for handling a large number of scenarios //! involving time. //! -//! These types must be used from within the context of the -//! [`Runtime`][runtime]. +//! These types must be used from within the context of the `Runtime`. //! //! # Examples //! @@ -43,8 +42,8 @@ //! ``` //! //! Require that an operation takes no more than 300ms. Note that this uses the -//! [`timeout`][ext] function on the [`FutureExt`][ext] trait. This trait is -//! included in the prelude. +//! `timeout` function on the `FutureExt` trait. This trait is included in the +//! prelude. //! //! ``` //! use tokio::time::{timeout, Duration}; @@ -61,13 +60,6 @@ //! } //! # } //! ``` -//! -//! [runtime]: ../runtime/struct.Runtime.html -//! [ext]: ../util/trait.FutureExt.html#method.timeout -//! [Timeout]: struct.Timeout.html -//! [Delay]: struct.Delay.html -//! [Interval]: struct.Interval.html -//! [`DelayQueue`]: struct.DelayQueue.html mod clock; pub(crate) use self::clock::Clock; -- cgit v1.2.3