xref: /third_party/rust/crates/rustix/src/io/errno.rs (revision b8a62b91)
1//! The `Errno` type, which is a minimal wrapper around an error code.
2//!
3//! We define the error constants as individual `const`s instead of an
4//! enum because we may not know about all of the host's error values
5//! and we don't want unrecognized values to create UB.
6
7use crate::backend;
8use core::{fmt, result};
9#[cfg(feature = "std")]
10use std::error;
11
12/// A specialized [`Result`] type for `rustix` APIs.
13///
14/// [`Result`]: core::result::Result
15pub type Result<T> = result::Result<T, Errno>;
16
17/// `errno`—An error code.
18///
19/// The error type for `rustix` APIs. This is similar to `std::io::Error`, but
20/// only holds an OS error code, and no extra error value.
21///
22/// # References
23///  - [POSIX]
24///  - [Linux]
25///
26/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html
27/// [Linux]: https://man7.org/linux/man-pages/man3/errno.3.html
28pub use backend::io::errno::Errno;
29
30impl Errno {
31    /// Shorthand for `std::io::Error::from(self).kind()`.
32    #[cfg(feature = "std")]
33    #[inline]
34    pub fn kind(self) -> std::io::ErrorKind {
35        std::io::Error::from(self).kind()
36    }
37}
38
39impl fmt::Display for Errno {
40    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
41        #[cfg(feature = "std")]
42        {
43            std::io::Error::from(*self).fmt(fmt)
44        }
45        #[cfg(not(feature = "std"))]
46        {
47            write!(fmt, "os error {}", self.raw_os_error())
48        }
49    }
50}
51
52impl fmt::Debug for Errno {
53    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54        #[cfg(feature = "std")]
55        {
56            std::io::Error::from(*self).fmt(fmt)
57        }
58        #[cfg(not(feature = "std"))]
59        {
60            write!(fmt, "os error {}", self.raw_os_error())
61        }
62    }
63}
64
65#[cfg(feature = "std")]
66impl error::Error for Errno {}
67
68#[cfg(feature = "std")]
69impl From<Errno> for std::io::Error {
70    #[inline]
71    fn from(err: Errno) -> Self {
72        Self::from_raw_os_error(err.raw_os_error() as _)
73    }
74}
75
76/// Call `f` until it either succeeds or fails other than [`Errno::INTR`].
77#[inline]
78pub fn retry_on_intr<T, F: FnMut() -> Result<T>>(mut f: F) -> Result<T> {
79    loop {
80        match f() {
81            Err(Errno::INTR) => (),
82            result => return result,
83        }
84    }
85}
86