Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errno::result() #247

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 59 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};
use {Error, Result};

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,70 @@ 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)
}
}

fn last() -> Errno {
Errno::from_i32(errno())
}
Expand Down Expand Up @@ -618,8 +661,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 +921,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 +1147,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 +1367,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 +1582,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 +1791,6 @@ mod consts {
EPROTO = 96,
}

impl_errno!(Errno);

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

Expand Down
21 changes: 4 additions & 17 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use {Error, Result, NixPath};
use errno::Errno;
use {Errno, Result, NixPath};
use libc::{c_int, c_uint};
use sys::stat::Mode;
use std::os::unix::io::RawFd;
Expand Down Expand Up @@ -102,11 +101,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 +152,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 +178,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
12 changes: 2 additions & 10 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;

pub mod errno;
pub mod features;
Expand Down Expand Up @@ -185,12 +186,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(())
}
6 changes: 3 additions & 3 deletions src/mount.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use libc::{c_ulong, c_int};
use {Result, NixPath, from_ffi};
use {Errno, Result, NixPath};

bitflags!(
flags MsFlags: c_ulong {
Expand Down Expand Up @@ -105,13 +105,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, 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
9 changes: 2 additions & 7 deletions src/poll.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use libc::c_int;
use {Error, Result};
use errno::Errno;
use {Errno, Result};

pub use self::ffi::PollFd;
pub use self::ffi::consts::*;
Expand Down Expand Up @@ -72,9 +71,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)
}
27 changes: 5 additions & 22 deletions src/sched.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::mem;
use std::os::unix::io::RawFd;
use libc::{c_int, c_uint, c_void, c_ulong, pid_t};
use errno::Errno;
use {Result, Error};
use {Errno, Result};

pub type CloneFlags = c_uint;

Expand Down Expand Up @@ -172,11 +171,7 @@ pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> Result<()> {
ffi::sched_setaffinity(pid as pid_t, mem::size_of::<CpuSet>() as size_t, mem::transmute(cpuset))
};

if res != 0 {
Err(Error::Sys(Errno::last()))
} else {
Ok(())
}
Errno::result(res).map(drop)
}

pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> Result<pid_t> {
Expand All @@ -190,29 +185,17 @@ pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> Result<pid
ffi::clone(mem::transmute(callback), ptr as *mut c_void, flags, &mut cb)
};

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

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

pub fn unshare(flags: CloneFlags) -> Result<()> {
let res = unsafe { ffi::unshare(flags) };

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

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

pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
let res = unsafe { ffi::setns(fd, nstype) };

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

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