diff --git a/library/std/src/io/buffered/mod.rs b/library/std/src/io/buffered/mod.rs index f9caeaf98e2fb..6cd24fe0dc66e 100644 --- a/library/std/src/io/buffered/mod.rs +++ b/library/std/src/io/buffered/mod.rs @@ -126,6 +126,29 @@ impl IntoInnerError { pub fn into_inner(self) -> W { self.0 } + + #[doc(test(attr(cfg(os = "linux"))))] + /// Consumes the [`IntoInnerError`] and returns the error which caused the call to + /// [`BufWriter::into_inner()`] to fail, and the underlying writer. + /// + /// This can be used to simply obtain ownership of the underlying error; it can also be used for + /// advanced error recovery. + /// + /// # Example (requires `/dev/full`, which is available on Linux) + /// ``` + /// use std::io::{BufWriter, ErrorKind, Write}; + /// use std::fs::File; + /// + /// let mut stream = BufWriter::new(File::create("/dev/full").unwrap()); + /// write!(stream, "this cannot be actually written").unwrap(); + /// let into_inner_err = stream.into_inner().expect_err("now we discover the ENOSPC"); + /// let (err, _writer) = into_inner_err.into_parts(); + /// assert_eq!(err.kind(), ErrorKind::NoStorageSpace); + /// ``` + #[stable(feature = "std_io_into_inner_error_into_inner_parts", since = "1.51.0")] + pub fn into_parts(self) -> (Error, W) { + (self.1, self.0) + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index ba0f0a0cd714a..c83407a426597 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -156,6 +156,11 @@ pub enum ErrorKind { /// [`Ok(0)`]: Ok #[stable(feature = "rust1", since = "1.0.0")] WriteZero, + /// The underlying storage (typically, a filesystem) is full. + /// + /// This does not include out of quota errors. + #[stable(feature = "io_error_no_storage_space", since = "1.51.0")] + NoStorageSpace, /// This operation was interrupted. /// /// Interrupted operations can typically be retried. @@ -199,6 +204,7 @@ impl ErrorKind { ErrorKind::TimedOut => "timed out", ErrorKind::WriteZero => "write zero", ErrorKind::Interrupted => "operation interrupted", + ErrorKind::NoStorageSpace => "no storage space", ErrorKind::Other => "other os error", ErrorKind::UnexpectedEof => "unexpected end of file", } diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index b28c6d85b7c72..fd7a1591624f4 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -174,6 +174,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, libc::EADDRINUSE => ErrorKind::AddrInUse, libc::ENOENT => ErrorKind::NotFound, + libc::ENOSPC => ErrorKind::NoStorageSpace, libc::EINTR => ErrorKind::Interrupted, libc::EINVAL => ErrorKind::InvalidInput, libc::ETIMEDOUT => ErrorKind::TimedOut,