Skip to content

Commit 12ef980

Browse files
committed
NixPath -> NixString and Error -> Errno
1 parent cca8a04 commit 12ef980

19 files changed

+201
-333
lines changed

src/errno.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use libc::c_int;
22
use std::{fmt, io, error, result};
3-
use Error;
43

54
pub use self::consts::*;
65
pub use self::consts::Errno::*;
@@ -74,7 +73,7 @@ impl Errno {
7473
/// should not be used when `-1` is not the errno sentinel value.
7574
pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
7675
if value == S::sentinel() {
77-
Err(Error::Sys(Self::last()))
76+
Err(Self::last())
7877
} else {
7978
Ok(value)
8079
}
@@ -117,7 +116,7 @@ impl From<Errno> for io::Error {
117116
}
118117
}
119118

120-
pub type Result<T> = result::Result<T, Error>;
119+
pub type Result<T> = result::Result<T, Errno>;
121120

122121
fn last() -> Errno {
123122
Errno::from_i32(errno())

src/fcntl.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use NixPath;
1+
use NixString;
22
use errno::{Errno, Result};
33
use libc::{c_int, c_uint};
44
use sys::stat::Mode;
@@ -97,10 +97,10 @@ 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-
}));
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+
};
104104

105105
Errno::result(fd)
106106
}

src/lib.rs

+4-144
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ extern crate nix_test as nixtest;
2121
// Re-exports
2222
pub use libc::{c_int, c_void};
2323
pub use errno::{Errno, Result};
24+
pub use nix_string::NixString;
25+
26+
#[macro_use]
27+
mod nix_string;
2428

2529
pub mod errno;
2630
pub mod features;
@@ -40,147 +44,3 @@ pub mod sched;
4044

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

src/mount.rs

+28-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use libc::{c_ulong, c_int};
2-
use NixPath;
2+
use NixString;
33
use errno::{Errno, Result};
44

55
bitflags!(
@@ -50,18 +50,15 @@ bitflags!(
5050
);
5151

5252
mod ffi {
53-
use libc::{c_char, c_int};
53+
use libc::{c_char, c_int, c_ulong, c_void};
5454

5555
extern {
56-
/*
57-
* TODO: Bring back
5856
pub fn mount(
5957
source: *const c_char,
6058
target: *const c_char,
6159
fstype: *const c_char,
6260
flags: c_ulong,
6361
data: *const c_void) -> c_int;
64-
*/
6562

6663
pub fn umount(target: *const c_char) -> c_int;
6764

@@ -72,47 +69,42 @@ mod ffi {
7269
/*
7370
* TODO: Bring this back with a test
7471
*
75-
pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P4: ?Sized + NixPath>(
76-
source: Option<&P1>,
72+
pub fn mount<P1: NixString, P2: NixString, P3: NixString, P4: NixString>(
73+
source: Option<P1>,
7774
target: P2,
78-
fstype: Option<&P3>,
75+
fstype: Option<P3>,
7976
flags: MsFlags,
80-
data: Option<&P4>) -> Result<()> {
77+
data: Option<P4>) -> Result<()> {
78+
use std::ffi::CStr;
79+
use std::ptr;
8180
use libc;
8281
83-
let res = try!(try!(try!(try!(
84-
source.with_nix_path(|source| {
85-
target.with_nix_path(|target| {
86-
fstype.with_nix_path(|fstype| {
87-
data.with_nix_path(|data| {
88-
unsafe {
89-
ffi::mount(source.as_ext_str(),
90-
target.as_ext_str(),
91-
fstype,
92-
flags.bits,
93-
data as *const libc::c_void)
94-
}
95-
})
96-
})
97-
})
98-
})))));
82+
let source = source.as_ref().map(NixString::as_ref);
83+
let fstype = fstype.as_ref().map(NixString::as_ref);
84+
let data = data.as_ref().map(NixString::as_ref);
85+
let res = unsafe {
86+
ffi::mount(source.map(CStr::as_ptr).unwrap_or(ptr::null()),
87+
target.as_ref().as_ptr(),
88+
fstype.map(CStr::as_ptr).unwrap_or(ptr::null()),
89+
flags.bits,
90+
data.map(CStr::as_ptr).unwrap_or(ptr::null()) as *const libc::c_void)
91+
};
9992
100-
return from_ffi(res);
101-
}
102-
*/
93+
Errno::result(res).map(drop)
94+
}*/
10395

104-
pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
105-
let res = try!(target.with_nix_path(|cstr| {
106-
unsafe { ffi::umount(cstr.as_ptr()) }
107-
}));
96+
pub fn umount<P: NixString>(target: P) -> Result<()> {
97+
let res = unsafe {
98+
ffi::umount(target.as_ref().as_ptr())
99+
};
108100

109101
Errno::result(res).map(drop)
110102
}
111103

112-
pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
113-
let res = try!(target.with_nix_path(|cstr| {
114-
unsafe { ffi::umount2(cstr.as_ptr(), flags.bits) }
115-
}));
104+
pub fn umount2<P: NixString>(target: P, flags: MntFlags) -> Result<()> {
105+
let res = unsafe {
106+
ffi::umount2(target.as_ref().as_ptr(), flags.bits)
107+
};
116108

117109
Errno::result(res).map(drop)
118110
}

src/nix_string.rs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::ffi::{CStr, CString};
2+
use std::borrow::Cow;
3+
4+
/// Represents a type that can be converted to a `&CStr` without fail.
5+
///
6+
/// Note: this trait exists in place of `AsRef<CStr>` because is not
7+
/// implemented until Rust 1.7.0
8+
pub trait NixString {
9+
fn as_ref(&self) -> &CStr;
10+
}
11+
12+
impl<'a> NixString for Cow<'a, CStr> {
13+
fn as_ref(&self) -> &CStr {
14+
self
15+
}
16+
}
17+
18+
impl NixString for CStr {
19+
fn as_ref(&self) -> &CStr {
20+
self
21+
}
22+
}
23+
24+
impl NixString for CString {
25+
fn as_ref(&self) -> &CStr {
26+
self
27+
}
28+
}
29+
30+
impl<'a, T: ?Sized + NixString> NixString for &'a T {
31+
fn as_ref(&self) -> &CStr {
32+
NixString::as_ref(*self)
33+
}
34+
}
35+
36+
impl<'a, T: ?Sized + NixString> NixString for &'a mut T {
37+
fn as_ref(&self) -> &CStr {
38+
NixString::as_ref(*self)
39+
}
40+
}
41+
42+
#[macro_export]
43+
macro_rules! cstr {
44+
($s:expr) => {
45+
unsafe { ::std::ffi::CStr::from_ptr(concat!($s, "\0").as_ptr() as *const _) }
46+
}
47+
}

src/sys/mman.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use {NixPath, Error};
1+
use NixString;
22
use errno::{Errno, Result};
33
use fcntl::OFlag;
44
use libc::{c_void, size_t, off_t, mode_t};
@@ -204,7 +204,7 @@ pub fn mmap(addr: *mut c_void, length: size_t, prot: MmapProt, flags: MmapFlag,
204204
let ret = unsafe { ffi::mmap(addr, length, prot, flags, fd, offset) };
205205

206206
if ret as isize == MAP_FAILED {
207-
Err(Error::Sys(Errno::last()))
207+
Err(Errno::last())
208208
} else {
209209
Ok(ret)
210210
}
@@ -222,20 +222,14 @@ pub fn msync(addr: *const c_void, length: size_t, flags: MmapSync) -> Result<()>
222222
Errno::result(unsafe { ffi::msync(addr, length, flags) }).map(drop)
223223
}
224224

225-
pub fn shm_open<P: ?Sized + NixPath>(name: &P, flag: OFlag, mode: Mode) -> Result<RawFd> {
226-
let ret = try!(name.with_nix_path(|cstr| {
227-
unsafe {
228-
ffi::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as mode_t)
229-
}
230-
}));
231-
232-
Errno::result(ret)
225+
pub fn shm_open<P: NixString>(name: P, flag: OFlag, mode: Mode) -> Result<RawFd> {
226+
unsafe {
227+
Errno::result(ffi::shm_open(name.as_ref().as_ptr(), flag.bits(), mode.bits() as mode_t))
228+
}
233229
}
234230

235-
pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
236-
let ret = try!(name.with_nix_path(|cstr| {
237-
unsafe { ffi::shm_unlink(cstr.as_ptr()) }
238-
}));
239-
240-
Errno::result(ret).map(drop)
231+
pub fn shm_unlink<P: NixString>(name: P) -> Result<()> {
232+
unsafe {
233+
Errno::result(ffi::shm_unlink(name.as_ref().as_ptr())).map(drop)
234+
}
241235
}

0 commit comments

Comments
 (0)