Skip to main content

std/io/
error.rs

1#[cfg(test)]
2mod tests;
3
4#[cfg_attr(
5    test,
6    expect(unused, reason = "only used in implementation for non-test compilation")
7)]
8use crate::{
9    io::{Error, OsFunctions, RawOsError},
10    sys::io::{decode_error_kind, errno, error_string, is_interrupted},
11};
12
13// Because std is linked in during testing, these incoherent implementations would
14// be duplicated if this was unconditionally included.
15// See #2912 for details.
16#[cfg(not(test))]
17impl Error {
18    /// Returns an error representing the last OS error which occurred.
19    ///
20    /// This function reads the value of `errno` for the target platform (e.g.
21    /// `GetLastError` on Windows) and will return a corresponding instance of
22    /// [`Error`] for the error code.
23    ///
24    /// This should be called immediately after a call to a platform function,
25    /// otherwise the state of the error value is indeterminate. In particular,
26    /// other standard library functions may call platform functions that may
27    /// (or may not) reset the error value even if they succeed.
28    ///
29    /// # Examples
30    ///
31    /// ```
32    /// use std::io::Error;
33    ///
34    /// let os_error = Error::last_os_error();
35    /// println!("last OS error: {os_error:?}");
36    /// ```
37    #[rustc_allow_incoherent_impl]
38    #[stable(feature = "rust1", since = "1.0.0")]
39    #[doc(alias = "GetLastError")]
40    #[doc(alias = "errno")]
41    #[must_use]
42    #[inline]
43    pub fn last_os_error() -> Error {
44        Error::from_raw_os_error(errno())
45    }
46
47    /// Creates a new instance of an [`Error`] from a particular OS error code.
48    ///
49    /// # Examples
50    ///
51    /// On Linux:
52    ///
53    /// ```
54    /// # if cfg!(target_os = "linux") {
55    /// use std::io;
56    ///
57    /// let error = io::Error::from_raw_os_error(22);
58    /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
59    /// # }
60    /// ```
61    ///
62    /// On Windows:
63    ///
64    /// ```
65    /// # if cfg!(windows) {
66    /// use std::io;
67    ///
68    /// let error = io::Error::from_raw_os_error(10022);
69    /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
70    /// # }
71    /// ```
72    #[rustc_allow_incoherent_impl]
73    #[stable(feature = "rust1", since = "1.0.0")]
74    #[must_use]
75    #[inline]
76    pub fn from_raw_os_error(code: RawOsError) -> Error {
77        const FUNCTIONS: &'static OsFunctions = &OsFunctions {
78            format_os_error: |code, fmt| fmt.write_str(&error_string(code)),
79            decode_error_kind,
80            is_interrupted,
81        };
82
83        // SAFETY: `FUNCTIONS` is a constant and not created at runtime.
84        unsafe { Error::from_raw_os_error_with_functions(code, FUNCTIONS) }
85    }
86}