summaryrefslogtreecommitdiff
path: root/src/errno.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/errno.rs')
-rw-r--r--src/errno.rs89
1 files changed, 61 insertions, 28 deletions
diff --git a/src/errno.rs b/src/errno.rs
index 5ca8ef08..8de55b80 100644
--- a/src/errno.rs
+++ b/src/errno.rs
@@ -1,9 +1,10 @@
use libc::c_int;
+use std::{fmt, io, error, result};
+use Error;
pub use self::consts::*;
pub use self::consts::Errno::*;
-
#[cfg(any(target_os = "macos",
target_os = "ios",
target_os = "freebsd"))]
@@ -52,28 +53,72 @@ pub fn errno() -> i32 {
}
}
-macro_rules! impl_errno {
- ($errno:ty) => {
- impl $errno {
- pub fn last() -> Errno {
- super::last()
- }
+impl Errno {
+ pub fn last() -> Self {
+ last()
+ }
+
+ pub fn desc(self) -> &'static str {
+ desc(self)
+ }
- pub fn desc(self) -> &'static str {
- super::desc(self)
- }
+ pub fn from_i32(err: i32) -> Errno {
+ from_i32(err)
+ }
- pub fn from_i32(err: i32) -> Errno {
- from_i32(err)
- }
+ pub unsafe fn clear() -> () {
+ clear()
+ }
- pub unsafe fn clear() -> () {
- super::clear()
- }
+ /// Returns `Ok(value)` if it does not contain the sentinel value. This
+ /// should not be used when `-1` is not the errno sentinel value.
+ pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
+ if value == S::sentinel() {
+ Err(Error::Sys(Self::last()))
+ } else {
+ Ok(value)
}
}
}
+/// The sentinel value indicates that a function failed and more detailed
+/// information about the error can be found in `errno`
+pub trait ErrnoSentinel: Sized {
+ fn sentinel() -> Self;
+}
+
+impl ErrnoSentinel for isize {
+ fn sentinel() -> Self { -1 }
+}
+
+impl ErrnoSentinel for i32 {
+ fn sentinel() -> Self { -1 }
+}
+
+impl ErrnoSentinel for i64 {
+ fn sentinel() -> Self { -1 }
+}
+
+impl error::Error for Errno {
+ fn description(&self) -> &str {
+ self.desc()
+ }
+}
+
+impl fmt::Display for Errno {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}: {}", self, self.desc())
+ }
+}
+
+impl From<Errno> for io::Error {
+ fn from(err: Errno) -> Self {
+ io::Error::from_raw_os_error(err as i32)
+ }
+}
+
+pub type Result<T> = result::Result<T, Error>;
+
fn last() -> Errno {
Errno::from_i32(errno())
}
@@ -618,8 +663,6 @@ mod consts {
EHWPOISON = 133,
}
- impl_errno!(Errno);
-
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -880,8 +923,6 @@ mod consts {
EQFULL = 106,
}
- impl_errno!(Errno);
-
pub const ELAST: Errno = Errno::EQFULL;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1108,8 +1149,6 @@ mod consts {
}
- impl_errno!(Errno);
-
pub const ELAST: Errno = Errno::EOWNERDEAD;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1330,8 +1369,6 @@ mod consts {
EASYNC = 99,
}
- impl_errno!(Errno);
-
pub const ELAST: Errno = Errno::EASYNC;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1547,8 +1584,6 @@ mod consts {
ENOTSUP = 91,
}
- impl_errno!(Errno);
-
pub const ELAST: Errno = Errno::ENOTSUP;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
@@ -1758,8 +1793,6 @@ mod consts {
EPROTO = 96,
}
- impl_errno!(Errno);
-
pub const ELAST: Errno = Errno::ENOTSUP;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;