]> git.proxmox.com Git - rustc.git/blob - vendor/errno-0.2.8/src/lib.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / errno-0.2.8 / src / lib.rs
1 //! Cross-platform interface to the `errno` variable.
2 //!
3 //! # Examples
4 //! ```
5 //! use errno::{Errno, errno, set_errno};
6 //!
7 //! // Get the current value of errno
8 //! let e = errno();
9 //!
10 //! // Set the current value of errno
11 //! set_errno(e);
12 //!
13 //! // Extract the error code as an i32
14 //! let code = e.0;
15 //!
16 //! // Display a human-friendly error message
17 //! println!("Error {}: {}", code, e);
18 //! ```
19
20 #![cfg_attr(target_os = "wasi", feature(thread_local))]
21 #![cfg_attr(not(feature = "std"), no_std)]
22
23 #[cfg(unix)] extern crate libc;
24 #[cfg(windows)] extern crate winapi;
25 #[cfg(target_os = "dragonfly")] extern crate errno_dragonfly;
26 #[cfg(target_os = "wasi")] extern crate libc;
27 #[cfg(target_os = "hermit")] extern crate libc;
28
29 #[cfg_attr(unix, path = "unix.rs")]
30 #[cfg_attr(windows, path = "windows.rs")]
31 #[cfg_attr(target_os = "wasi", path = "wasi.rs")]
32 #[cfg_attr(target_os = "hermit", path = "hermit.rs")]
33 mod sys;
34
35 #[cfg(feature = "std")]
36 use std::fmt;
37 #[cfg(feature = "std")]
38 use std::io;
39 #[cfg(feature = "std")]
40 use std::error::Error;
41
42 /// Wraps a platform-specific error code.
43 ///
44 /// The `Display` instance maps the code to a human-readable string. It
45 /// calls [`strerror_r`][1] under POSIX, and [`FormatMessageW`][2] on
46 /// Windows.
47 ///
48 /// [1]: http://pubs.opengroup.org/onlinepubs/009695399/functions/strerror.html
49 /// [2]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351%28v=vs.85%29.aspx
50 #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd, Hash)]
51 pub struct Errno(pub i32);
52
53 #[cfg(feature = "std")]
54 impl fmt::Debug for Errno {
55 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
56 sys::with_description(*self, |desc| {
57 fmt.debug_struct("Errno")
58 .field("code", &self.0)
59 .field("description", &desc.ok())
60 .finish()
61 })
62 }
63 }
64
65 #[cfg(feature = "std")]
66 impl fmt::Display for Errno {
67 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
68 sys::with_description(*self, |desc| match desc {
69 Ok(desc) => fmt.write_str(&desc),
70 Err(fm_err) => write!(
71 fmt, "OS error {} ({} returned error {})",
72 self.0, sys::STRERROR_NAME, fm_err.0),
73 })
74 }
75 }
76
77 impl Into<i32> for Errno {
78 fn into(self) -> i32 {
79 self.0
80 }
81 }
82
83 #[cfg(feature = "std")]
84 impl Error for Errno {
85 // TODO: Remove when MSRV >= 1.27
86 #[allow(deprecated)]
87 fn description(&self) -> &str {
88 "system error"
89 }
90 }
91
92 #[cfg(feature = "std")]
93 impl From<Errno> for io::Error {
94 fn from(errno: Errno) -> Self {
95 io::Error::from_raw_os_error(errno.0)
96 }
97 }
98
99 /// Returns the platform-specific value of `errno`.
100 pub fn errno() -> Errno {
101 sys::errno()
102 }
103
104 /// Sets the platform-specific value of `errno`.
105 pub fn set_errno(err: Errno) {
106 sys::set_errno(err)
107 }
108
109 #[test]
110 fn it_works() {
111 let x = errno();
112 set_errno(x);
113 }
114
115 #[cfg(feature = "std")]
116 #[test]
117 fn it_works_with_to_string() {
118 let x = errno();
119 let _ = x.to_string();
120 }
121
122 #[cfg(feature = "std")]
123 #[test]
124 fn check_description() {
125 let expect = if cfg!(windows) {
126 "Incorrect function."
127 } else if cfg!(target_os = "illumos") {
128 "Not owner"
129 } else if cfg!(target_os = "wasi") {
130 "Argument list too long"
131 } else {
132 "Operation not permitted"
133 };
134
135 set_errno(Errno(1));
136
137 assert_eq!(errno().to_string(), expect);
138 assert_eq!(
139 format!("{:?}", errno()),
140 format!("Errno {{ code: 1, description: Some({:?}) }}", expect));
141 }
142
143 #[cfg(feature = "std")]
144 #[test]
145 fn check_error_into_errno() {
146 const ERROR_CODE: i32 = 1;
147
148 let error = io::Error::from_raw_os_error(ERROR_CODE);
149 let new_error: io::Error = Errno(ERROR_CODE).into();
150 assert_eq!(error.kind(), new_error.kind());
151 }