Skip to content

Commit 0a16991

Browse files
committed
NixPath -> NixString and Error -> Errno
1 parent 3154b7d commit 0a16991

28 files changed

+669
-1062
lines changed

src/errno.rs

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

34
pub use self::consts::*;
45
pub use self::consts::Errno::*;
@@ -52,28 +53,64 @@ 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+
}
6160

62-
pub fn desc(self) -> &'static str {
63-
super::desc(self)
64-
}
61+
pub fn desc(self) -> &'static str {
62+
desc(self)
63+
}
6564

66-
pub fn from_i32(err: i32) -> Errno {
67-
from_i32(err)
68-
}
65+
pub fn from_i32(err: i32) -> Errno {
66+
from_i32(err)
67+
}
6968

70-
pub unsafe fn clear() -> () {
71-
super::clear()
72-
}
69+
pub unsafe fn clear() -> () {
70+
clear()
71+
}
72+
73+
pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
74+
if value == S::sentinel() {
75+
Err(Self::last())
76+
} else {
77+
Ok(value)
7378
}
7479
}
7580
}
7681

82+
pub trait ErrnoSentinel: Sized {
83+
fn sentinel() -> Self;
84+
}
85+
86+
impl ErrnoSentinel for c_int {
87+
fn sentinel() -> Self { -1 }
88+
}
89+
90+
impl ErrnoSentinel for c_long {
91+
fn sentinel() -> Self { -1 }
92+
}
93+
94+
impl error::Error for Errno {
95+
fn description(&self) -> &str {
96+
self.desc()
97+
}
98+
}
99+
100+
impl fmt::Display for Errno {
101+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102+
write!(f, "{:?}: {}", self, self.desc())
103+
}
104+
}
105+
106+
impl From<Errno> for io::Error {
107+
fn from(err: Errno) -> Self {
108+
io::Error::from_raw_os_error(err as i32)
109+
}
110+
}
111+
112+
pub type Result<T> = ::std::result::Result<T, Errno>;
113+
77114
fn last() -> Errno {
78115
Errno::from_i32(errno())
79116
}
@@ -618,8 +655,6 @@ mod consts {
618655
EHWPOISON = 133,
619656
}
620657

621-
impl_errno!(Errno);
622-
623658
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
624659
pub const EDEADLOCK: Errno = Errno::EDEADLK;
625660

@@ -880,8 +915,6 @@ mod consts {
880915
EQFULL = 106,
881916
}
882917

883-
impl_errno!(Errno);
884-
885918
pub const ELAST: Errno = Errno::EQFULL;
886919
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
887920
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1108,8 +1141,6 @@ mod consts {
11081141

11091142
}
11101143

1111-
impl_errno!(Errno);
1112-
11131144
pub const ELAST: Errno = Errno::EOWNERDEAD;
11141145
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11151146
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1330,8 +1361,6 @@ mod consts {
13301361
EASYNC = 99,
13311362
}
13321363

1333-
impl_errno!(Errno);
1334-
13351364
pub const ELAST: Errno = Errno::EASYNC;
13361365
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
13371366
pub const EDEADLOCK: Errno = Errno::EDEADLK;
@@ -1547,8 +1576,6 @@ mod consts {
15471576
ENOTSUP = 91,
15481577
}
15491578

1550-
impl_errno!(Errno);
1551-
15521579
pub const ELAST: Errno = Errno::ENOTSUP;
15531580
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
15541581

@@ -1758,8 +1785,6 @@ mod consts {
17581785
EPROTO = 96,
17591786
}
17601787

1761-
impl_errno!(Errno);
1762-
17631788
pub const ELAST: Errno = Errno::ENOTSUP;
17641789
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
17651790

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::{mode_t, c_int};
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 mode_t) }
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 mode_t)
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

+4-138
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ 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;
2325

2426
pub mod errno;
2527
pub mod features;
@@ -37,140 +39,4 @@ pub mod sched;
3739
pub mod sys;
3840
pub mod unistd;
3941

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

0 commit comments

Comments
 (0)