Skip to content

Commit

Permalink
Errno::result()
Browse files Browse the repository at this point in the history
  • Loading branch information
arcnmx committed Jan 26, 2016
1 parent e8f014d commit 69483df
Show file tree
Hide file tree
Showing 28 changed files with 257 additions and 503 deletions.
89 changes: 61 additions & 28 deletions src/errno.rs
Original file line number Diff line number Diff line change
@@ -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"))]
Expand Down Expand Up @@ -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())
}
Expand Down Expand Up @@ -618,8 +663,6 @@ mod consts {
EHWPOISON = 133,
}

impl_errno!(Errno);

pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1547,8 +1584,6 @@ mod consts {
ENOTSUP = 91,
}

impl_errno!(Errno);

pub const ELAST: Errno = Errno::ENOTSUP;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;

Expand Down Expand Up @@ -1758,8 +1793,6 @@ mod consts {
EPROTO = 96,
}

impl_errno!(Errno);

pub const ELAST: Errno = Errno::ENOTSUP;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;

Expand Down
22 changes: 5 additions & 17 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {Error, Result, NixPath};
use errno::Errno;
use NixPath;
use errno::{Errno, Result};
use libc::{c_int, c_uint};
use sys::stat::Mode;
use std::os::unix::io::RawFd;
Expand Down Expand Up @@ -102,11 +102,7 @@ pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<R
unsafe { ffi::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
}));

if fd < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(fd)
Errno::result(fd)
}

pub enum FcntlArg<'a> {
Expand Down Expand Up @@ -157,11 +153,7 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
}
};

if res < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(res)
Errno::result(res)
}

pub enum FlockArg {
Expand All @@ -187,11 +179,7 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
}
};

if res < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(())
Errno::result(res).map(drop)
}

#[cfg(any(target_os = "linux", target_os = "android"))]
Expand Down
18 changes: 4 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ extern crate libc;
#[cfg(test)]
extern crate nix_test as nixtest;

// Re-export some libc constants
// Re-exports
pub use libc::{c_int, c_void};
pub use errno::{Errno, Result};

pub mod errno;
pub mod features;
Expand All @@ -42,12 +43,12 @@ pub mod unistd;

/*
*
* ===== Result / Error =====
* ===== Error =====
*
*/

use libc::c_char;
use std::{ptr, result};
use std::ptr;
use std::ffi::CStr;
use std::path::{Path, PathBuf};
use std::os::unix::ffi::OsStrExt;
Expand All @@ -56,8 +57,6 @@ use std::fmt;
use std::error;
use libc::PATH_MAX;

pub type Result<T> = result::Result<T, Error>;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Error {
Sys(errno::Errno),
Expand Down Expand Up @@ -185,12 +184,3 @@ impl NixPath for PathBuf {
self.as_os_str().as_bytes().with_nix_path(f)
}
}

#[inline]
pub fn from_ffi(res: libc::c_int) -> Result<()> {
if res != 0 {
return Err(Error::Sys(errno::Errno::last()));
}

Ok(())
}
7 changes: 4 additions & 3 deletions src/mount.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use libc::{c_ulong, c_int};
use {Result, NixPath, from_ffi};
use NixPath;
use errno::{Errno, Result};

bitflags!(
flags MsFlags: c_ulong {
Expand Down Expand Up @@ -105,13 +106,13 @@ pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
unsafe { ffi::umount(cstr.as_ptr()) }
}));

from_ffi(res)
Errno::result(res).map(drop)
}

pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
let res = try!(target.with_nix_path(|cstr| {
unsafe { ffi::umount2(cstr.as_ptr(), flags.bits) }
}));

from_ffi(res)
Errno::result(res).map(drop)
}
33 changes: 8 additions & 25 deletions src/mqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
//!
//! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html)

use {Error, Result, from_ffi};
use errno::Errno;
use errno::{Errno, Result};

use libc::{c_int, c_long, c_char, size_t, mode_t, strlen};
use std::ffi::CString;
Expand Down Expand Up @@ -80,52 +79,38 @@ impl MqAttr {
pub fn mq_open(name: &CString, oflag: MQ_OFlag, mode: Mode, attr: &MqAttr) -> Result<MQd> {
let res = unsafe { ffi::mq_open(name.as_ptr(), oflag.bits(), mode.bits() as mode_t, attr as *const MqAttr) };

if res < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(res)
Errno::result(res)
}

pub fn mq_unlink(name: &CString) -> Result<()> {
let res = unsafe { ffi::mq_unlink(name.as_ptr()) };
from_ffi(res)
Errno::result(res).map(drop)
}

pub fn mq_close(mqdes: MQd) -> Result<()> {
let res = unsafe { ffi::mq_close(mqdes) };
from_ffi(res)
Errno::result(res).map(drop)
}


pub fn mq_receive(mqdes: MQd, message: &mut [u8], msq_prio: u32) -> Result<usize> {
let len = message.len() as size_t;
let res = unsafe { ffi::mq_receive(mqdes, message.as_mut_ptr() as *mut c_char, len, &msq_prio) };

if res < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(res as usize)
Errno::result(res).map(|r| r as usize)
}

pub fn mq_send(mqdes: MQd, message: &CString, msq_prio: u32) -> Result<usize> {
let len = unsafe { strlen(message.as_ptr()) as size_t };
let res = unsafe { ffi::mq_send(mqdes, message.as_ptr(), len, msq_prio) };

if res < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(res as usize)
Errno::result(res).map(|r| r as usize)
}

pub fn mq_getattr(mqd: MQd) -> Result<MqAttr> {
let mut attr = MqAttr::new(0, 0, 0, 0);
let res = unsafe { ffi::mq_getattr(mqd, &mut attr) };
if res < 0 {
return Err(Error::Sys(Errno::last()));
}
try!(Errno::result(res));
Ok(attr)
}

Expand All @@ -137,9 +122,7 @@ pub fn mq_getattr(mqd: MQd) -> Result<MqAttr> {
pub fn mq_setattr(mqd: MQd, newattr: &MqAttr) -> Result<MqAttr> {
let mut attr = MqAttr::new(0, 0, 0, 0);
let res = unsafe { ffi::mq_setattr(mqd, newattr as *const MqAttr, &mut attr) };
if res < 0 {
return Err(Error::Sys(Errno::last()));
}
try!(Errno::result(res));
Ok(attr)
}

Expand Down
6 changes: 1 addition & 5 deletions src/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,5 @@ pub fn poll(fds: &mut [PollFd], timeout: c_int) -> Result<c_int> {
ffi::poll(fds.as_mut_ptr(), fds.len() as ffi::nfds_t, timeout)
};

if res < 0 {
return Err(Error::Sys(Errno::last()));
}

Ok(res)
Errno::result(res)
}
Loading

0 comments on commit 69483df

Please sign in to comment.