diff options
Diffstat (limited to 'src/errno.rs')
-rw-r--r-- | src/errno.rs | 89 |
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; |