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.
13pub type Result<T> = result::Result<T, Errno>;
14
15/// `errno`—An error code.
16///
17/// The error type for `rustix` APIs. This is similar to `std::io::Error`, but
18/// only holds an OS error code, and no extra error value.
19///
20/// # References
21/// - [POSIX]
22/// - [Linux]
23/// - [Winsock2]
24/// - [FreeBSD]
25/// - [NetBSD]
26/// - [OpenBSD]
27/// - [DragonFly BSD]
28/// - [illumos]
29/// - [glibc]
30///
31/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html
32/// [Linux]: https://man7.org/linux/man-pages/man3/errno.3.html
33/// [Winsock2]: https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
34/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?errno
35/// [NetBSD]: https://man.netbsd.org/errno.2
36/// [OpenBSD]: https://man.openbsd.org/errno.2
37/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=errno&section=2
38/// [illumos]: https://illumos.org/man/3C/errno
39/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html
40pub use backend::io::errno::Errno;
41
42impl Errno {
43 /// Shorthand for `std::io::Error::from(self).kind()`.
44 #[cfg(feature = "std")]
45 #[inline]
46 pub fn kind(self) -> std::io::ErrorKind {
47 std::io::Error::from(self).kind()
48 }
49}
50
51impl fmt::Display for Errno {
52 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
53 #[cfg(feature = "std")]
54 {
55 std::io::Error::from(*self).fmt(fmt)
56 }
57 #[cfg(not(feature = "std"))]
58 {
59 write!(fmt, "os error {}", self.raw_os_error())
60 }
61 }
62}
63
64impl fmt::Debug for Errno {
65 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
66 #[cfg(feature = "std")]
67 {
68 std::io::Error::from(*self).fmt(fmt)
69 }
70 #[cfg(not(feature = "std"))]
71 {
72 write!(fmt, "os error {}", self.raw_os_error())
73 }
74 }
75}
76
77#[cfg(feature = "std")]
78impl error::Error for Errno {}
79
80#[cfg(feature = "std")]
81impl From<Errno> for std::io::Error {
82 #[inline]
83 fn from(err: Errno) -> Self {
84 Self::from_raw_os_error(code:err.raw_os_error() as _)
85 }
86}
87
88/// Call `f` until it either succeeds or fails other than [`Errno::INTR`].
89#[inline]
90pub fn retry_on_intr<T, F: FnMut() -> Result<T>>(mut f: F) -> Result<T> {
91 loop {
92 match f() {
93 Err(Errno::INTR) => (),
94 result: Result => return result,
95 }
96 }
97}
98