Skip to content

Commit 1f67dba

Browse files
committed
NixPath -> NixString and Error -> Errno
1 parent fb42dc9 commit 1f67dba

32 files changed

+428
-787
lines changed

src/errno.rs

+60-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use libc::c_int;
2+
use std::{fmt, io, error};
23

34
pub use self::consts::*;
45
pub use self::consts::Errno::*;
@@ -52,28 +53,72 @@ pub fn errno() -> i32 {
5253
}
5354
}
5455

55-
macro_rules! impl_errno {
56-
($errno:ty) => {
57-
impl $errno {
58-
pub fn last() -> Errno {
59-
super::last()
60-
}
56+
impl Errno {
57+
pub fn last() -> Self {
58+
last()
59+
}
60+
61+
pub fn desc(self) -> &'static str {
62+
desc(self)
63+
}
6164

62-
pub fn desc(self) -> &'static str {
63-
super::desc(self)
64-
}
65+
pub fn from_i32(err: i32) -> Errno {
66+
from_i32(err)
67+
}
6568

66-
pub fn from_i32(err: i32) -> Errno {
67-
from_i32(err)
68-
}
69+
pub unsafe fn clear() -> () {
70+
clear()
71+
}
6972

70-
pub unsafe fn clear() -> () {
71-
super::clear()
72-
}
73+
/// Returns `Ok(value)` if it does not contain the sentinel value. This
74+
/// should not be used when `-1` is not the errno sentinel value.
75+
pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
76+
if value == S::sentinel() {
77+
Err(Self::last())
78+
} else {
79+
Ok(value)
7380
}
7481
}
7582
}
7683

84+
/// The sentinel value indicates that a function failed and more detailed
85+
/// information about the error can be found in `errno`
86+
pub trait ErrnoSentinel: Sized {
87+
fn sentinel() -> Self;
88+
}
89+
90+
impl ErrnoSentinel for isize {
91+
fn sentinel() -> Self { -1 }
92+
}
93+
94+
impl ErrnoSentinel for i32 {
95+
fn sentinel() -> Self { -1 }
96+
}
97+
98+
impl ErrnoSentinel for i64 {
99+
fn sentinel() -> Self { -1 }
100+
}
101+
102+
impl error::Error for Errno {
103+
fn description(&self) -> &str {
104+
self.desc()
105+
}
106+
}
107+
108+
impl fmt::Display for Errno {
109+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110+
write!(f, "{:?}: {}", self, self.desc())
111+
}
112+
}
113+
114+
impl From<Errno> for io::Error {
115+
fn from(err: Errno) -> Self {
116+
io::Error::from_raw_os_error(err as i32)
117+
}
118+
}
119+
120+
pub type Result<T> = ::std::result::Result<T, Errno>;
121+
77122
fn last() -> Errno {
78123
Errno::from_i32(errno())
79124
}
@@ -618,8 +663,6 @@ mod consts {
618663
EHWPOISON = 133,
619664
}
620665

621-
impl_errno!(Errno);
622-
623666
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
624667
pub const EDEADLOCK: Errno = Errno::EDEADLK;
625668

@@ -880,8 +923,6 @@ mod consts {
880923
EQFULL = 106,
881924
}
882925

883-
impl_errno!(Errno);
884-
885926
pub const ELAST: Errno = Errno::EQFULL;
886927
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
887928
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1108,8 +1149,6 @@ mod consts {
11081149

11091150
}
11101151

1111-
impl_errno!(Errno);
1112-
11131152
pub const ELAST: Errno = Errno::EOWNERDEAD;
11141153
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11151154
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1330,8 +1369,6 @@ mod consts {
13301369
EASYNC = 99,
13311370
}
13321371

1333-
impl_errno!(Errno);
1334-
13351372
pub const ELAST: Errno = Errno::EASYNC;
13361373
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
13371374
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1547,8 +1584,6 @@ mod consts {
15471584
ENOTSUP = 91,
15481585
}
15491586

1550-
impl_errno!(Errno);
1551-
15521587
pub const ELAST: Errno = Errno::ENOTSUP;
15531588
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
15541589

@@ -1758,8 +1793,6 @@ mod consts {
17581793
EPROTO = 96,
17591794
}
17601795

1761-
impl_errno!(Errno);
1762-
17631796
pub const ELAST: Errno = Errno::ENOTSUP;
17641797
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
17651798

src/fcntl.rs

+9-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use {Error, Result, NixPath};
2-
use errno::Errno;
1+
use NixString;
2+
use errno::{Errno, Result};
33
use libc::{c_int, c_uint};
44
use sys::stat::Mode;
55
use std::os::unix::io::RawFd;
@@ -97,16 +97,12 @@ mod ffi {
9797
}
9898
}
9999

100-
pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
101-
let fd = try!(path.with_nix_path(|cstr| {
102-
unsafe { ffi::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
103-
}));
104-
105-
if fd < 0 {
106-
return Err(Error::Sys(Errno::last()));
107-
}
100+
pub fn open<P: NixString>(path: P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
101+
let fd = unsafe {
102+
ffi::open(path.as_ref().as_ptr(), oflag.bits(), mode.bits() as c_uint)
103+
};
108104

109-
Ok(fd)
105+
Errno::result(fd)
110106
}
111107

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

160-
if res < 0 {
161-
return Err(Error::Sys(Errno::last()));
162-
}
163-
164-
Ok(res)
156+
Errno::result(res)
165157
}
166158

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

190-
if res < 0 {
191-
return Err(Error::Sys(Errno::last()));
192-
}
193-
194-
Ok(())
182+
Errno::result(res).map(drop)
195183
}
196184

197185
#[cfg(any(target_os = "linux", target_os = "android"))]

src/lib.rs

+6-140
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ extern crate libc;
1818
#[cfg(test)]
1919
extern crate nix_test as nixtest;
2020

21-
// Re-export some libc constants
21+
// Re-exports
2222
pub use libc::{c_int, c_void};
23+
pub use errno::{Errno, Result};
24+
pub use nix_string::NixString;
25+
26+
#[macro_use]
27+
mod nix_string;
2328

2429
pub mod errno;
2530
pub mod features;
@@ -36,142 +41,3 @@ pub mod sched;
3641

3742
pub mod sys;
3843
pub mod unistd;
39-
40-
/*
41-
*
42-
* ===== Result / Error =====
43-
*
44-
*/
45-
46-
use libc::c_char;
47-
use std::{ptr, result};
48-
use std::ffi::CStr;
49-
use std::path::{Path, PathBuf};
50-
use std::os::unix::ffi::OsStrExt;
51-
use std::io;
52-
use std::fmt;
53-
use std::error;
54-
use libc::PATH_MAX;
55-
56-
pub type Result<T> = result::Result<T, Error>;
57-
58-
#[derive(Clone, Copy, Debug, PartialEq)]
59-
pub enum Error {
60-
Sys(errno::Errno),
61-
InvalidPath,
62-
}
63-
64-
impl Error {
65-
pub fn from_errno(errno: errno::Errno) -> Error {
66-
Error::Sys(errno)
67-
}
68-
69-
pub fn last() -> Error {
70-
Error::Sys(errno::Errno::last())
71-
}
72-
73-
pub fn invalid_argument() -> Error {
74-
Error::Sys(errno::EINVAL)
75-
}
76-
77-
pub fn errno(&self) -> errno::Errno {
78-
match *self {
79-
Error::Sys(errno) => errno,
80-
Error::InvalidPath => errno::Errno::EINVAL,
81-
}
82-
}
83-
}
84-
85-
impl From<errno::Errno> for Error {
86-
fn from(errno: errno::Errno) -> Error { Error::from_errno(errno) }
87-
}
88-
89-
impl error::Error for Error {
90-
fn description(&self) -> &str {
91-
match self {
92-
&Error::InvalidPath => "Invalid path",
93-
&Error::Sys(ref errno) => errno.desc(),
94-
}
95-
}
96-
}
97-
98-
impl fmt::Display for Error {
99-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100-
match self {
101-
&Error::InvalidPath => write!(f, "Invalid path"),
102-
&Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()),
103-
}
104-
}
105-
}
106-
107-
impl From<Error> for io::Error {
108-
fn from(err: Error) -> Self {
109-
match err {
110-
Error::InvalidPath => io::Error::new(io::ErrorKind::InvalidInput, err),
111-
Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
112-
}
113-
}
114-
}
115-
116-
pub trait NixPath {
117-
fn len(&self) -> usize;
118-
119-
fn with_nix_path<T, F>(&self, f: F) -> Result<T>
120-
where F: FnOnce(&CStr) -> T;
121-
}
122-
123-
impl NixPath for [u8] {
124-
fn len(&self) -> usize {
125-
self.len()
126-
}
127-
128-
fn with_nix_path<T, F>(&self, f: F) -> Result<T>
129-
where F: FnOnce(&CStr) -> T {
130-
let mut buf = [0u8; PATH_MAX as usize];
131-
132-
if self.len() >= PATH_MAX as usize {
133-
return Err(Error::InvalidPath);
134-
}
135-
136-
match self.iter().position(|b| *b == 0) {
137-
Some(_) => Err(Error::InvalidPath),
138-
None => {
139-
unsafe {
140-
// TODO: Replace with bytes::copy_memory. rust-lang/rust#24028
141-
ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
142-
Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
143-
}
144-
145-
}
146-
}
147-
}
148-
}
149-
150-
impl NixPath for Path {
151-
fn len(&self) -> usize {
152-
self.as_os_str().as_bytes().len()
153-
}
154-
155-
fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
156-
self.as_os_str().as_bytes().with_nix_path(f)
157-
}
158-
}
159-
160-
impl NixPath for PathBuf {
161-
fn len(&self) -> usize {
162-
self.as_os_str().as_bytes().len()
163-
}
164-
165-
fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
166-
self.as_os_str().as_bytes().with_nix_path(f)
167-
}
168-
}
169-
170-
#[inline]
171-
pub fn from_ffi(res: libc::c_int) -> Result<()> {
172-
if res != 0 {
173-
return Err(Error::Sys(errno::Errno::last()));
174-
}
175-
176-
Ok(())
177-
}

0 commit comments

Comments
 (0)