From 12ef980bd6044de28b0c82cb3a6c7bb9bb9953f4 Mon Sep 17 00:00:00 2001 From: arcnmx Date: Tue, 5 Jan 2016 14:12:12 -0500 Subject: [PATCH] NixPath -> NixString and Error -> Errno --- src/errno.rs | 5 +- src/fcntl.rs | 10 +-- src/lib.rs | 148 ++------------------------------------- src/mount.rs | 64 ++++++++--------- src/nix_string.rs | 47 +++++++++++++ src/sys/mman.rs | 26 +++---- src/sys/ptrace.rs | 3 +- src/sys/quota.rs | 31 ++++---- src/sys/signalfd.rs | 2 +- src/sys/socket/addr.rs | 39 +++++------ src/sys/socket/mod.rs | 3 +- src/sys/stat.rs | 32 ++++----- src/sys/statfs.rs | 10 +-- src/sys/statvfs.rs | 17 ++--- src/unistd.rs | 69 +++++++++--------- test/sys/test_socket.rs | 9 +-- test/sys/test_termios.rs | 6 +- test/test_mq.rs | 5 +- test/test_stat.rs | 8 ++- 19 files changed, 201 insertions(+), 333 deletions(-) create mode 100644 src/nix_string.rs diff --git a/src/errno.rs b/src/errno.rs index 8de55b8021..1e219f13cc 100644 --- a/src/errno.rs +++ b/src/errno.rs @@ -1,6 +1,5 @@ use libc::c_int; use std::{fmt, io, error, result}; -use Error; pub use self::consts::*; pub use self::consts::Errno::*; @@ -74,7 +73,7 @@ impl Errno { /// should not be used when `-1` is not the errno sentinel value. pub fn result>(value: S) -> Result { if value == S::sentinel() { - Err(Error::Sys(Self::last())) + Err(Self::last()) } else { Ok(value) } @@ -117,7 +116,7 @@ impl From for io::Error { } } -pub type Result = result::Result; +pub type Result = result::Result; fn last() -> Errno { Errno::from_i32(errno()) diff --git a/src/fcntl.rs b/src/fcntl.rs index 197f0059f9..b86d7d8135 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -1,4 +1,4 @@ -use NixPath; +use NixString; use errno::{Errno, Result}; use libc::{c_int, c_uint}; use sys::stat::Mode; @@ -97,10 +97,10 @@ mod ffi { } } -pub fn open(path: &P, oflag: OFlag, mode: Mode) -> Result { - let fd = try!(path.with_nix_path(|cstr| { - unsafe { ffi::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) } - })); +pub fn open(path: P, oflag: OFlag, mode: Mode) -> Result { + let fd = unsafe { + ffi::open(path.as_ref().as_ptr(), oflag.bits(), mode.bits() as c_uint) + }; Errno::result(fd) } diff --git a/src/lib.rs b/src/lib.rs index cc72f704e6..3e409aa110 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,10 @@ extern crate nix_test as nixtest; // Re-exports pub use libc::{c_int, c_void}; pub use errno::{Errno, Result}; +pub use nix_string::NixString; + +#[macro_use] +mod nix_string; pub mod errno; pub mod features; @@ -40,147 +44,3 @@ pub mod sched; pub mod sys; pub mod unistd; - -/* - * - * ===== Error ===== - * - */ - -use libc::c_char; -use std::ptr; -use std::ffi::CStr; -use std::path::{Path, PathBuf}; -use std::os::unix::ffi::OsStrExt; -use std::io; -use std::fmt; -use std::error; -use libc::PATH_MAX; - -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum Error { - Sys(errno::Errno), - InvalidPath, -} - -impl Error { - pub fn from_errno(errno: errno::Errno) -> Error { - Error::Sys(errno) - } - - pub fn last() -> Error { - Error::Sys(errno::Errno::last()) - } - - pub fn invalid_argument() -> Error { - Error::Sys(errno::EINVAL) - } - - pub fn errno(&self) -> errno::Errno { - match *self { - Error::Sys(errno) => errno, - Error::InvalidPath => errno::Errno::EINVAL, - } - } -} - -impl From for Error { - fn from(errno: errno::Errno) -> Error { Error::from_errno(errno) } -} - -impl error::Error for Error { - fn description(&self) -> &str { - match self { - &Error::InvalidPath => "Invalid path", - &Error::Sys(ref errno) => errno.desc(), - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &Error::InvalidPath => write!(f, "Invalid path"), - &Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()), - } - } -} - -impl From for io::Error { - fn from(err: Error) -> Self { - match err { - Error::InvalidPath => io::Error::new(io::ErrorKind::InvalidInput, err), - Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32), - } - } -} - -pub trait NixPath { - fn len(&self) -> usize; - - fn with_nix_path(&self, f: F) -> Result - where F: FnOnce(&CStr) -> T; -} - -impl NixPath for CStr { - fn len(&self) -> usize { - self.to_bytes().len() - } - - fn with_nix_path(&self, f: F) -> Result - where F: FnOnce(&CStr) -> T { - // Equivalence with the [u8] impl. - if self.len() >= PATH_MAX as usize { - return Err(Error::InvalidPath); - } - - Ok(f(self)) - } -} - -impl NixPath for [u8] { - fn len(&self) -> usize { - self.len() - } - - fn with_nix_path(&self, f: F) -> Result - where F: FnOnce(&CStr) -> T { - let mut buf = [0u8; PATH_MAX as usize]; - - if self.len() >= PATH_MAX as usize { - return Err(Error::InvalidPath); - } - - match self.iter().position(|b| *b == 0) { - Some(_) => Err(Error::InvalidPath), - None => { - unsafe { - // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028 - ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len()); - Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char))) - } - - } - } - } -} - -impl NixPath for Path { - fn len(&self) -> usize { - self.as_os_str().as_bytes().len() - } - - fn with_nix_path(&self, f: F) -> Result where F: FnOnce(&CStr) -> T { - self.as_os_str().as_bytes().with_nix_path(f) - } -} - -impl NixPath for PathBuf { - fn len(&self) -> usize { - self.as_os_str().as_bytes().len() - } - - fn with_nix_path(&self, f: F) -> Result where F: FnOnce(&CStr) -> T { - self.as_os_str().as_bytes().with_nix_path(f) - } -} diff --git a/src/mount.rs b/src/mount.rs index 0535cdd048..262c4268ab 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -1,5 +1,5 @@ use libc::{c_ulong, c_int}; -use NixPath; +use NixString; use errno::{Errno, Result}; bitflags!( @@ -50,18 +50,15 @@ bitflags!( ); mod ffi { - use libc::{c_char, c_int}; + use libc::{c_char, c_int, c_ulong, c_void}; extern { - /* - * TODO: Bring back pub fn mount( source: *const c_char, target: *const c_char, fstype: *const c_char, flags: c_ulong, data: *const c_void) -> c_int; - */ pub fn umount(target: *const c_char) -> c_int; @@ -72,47 +69,42 @@ mod ffi { /* * TODO: Bring this back with a test * -pub fn mount( - source: Option<&P1>, +pub fn mount( + source: Option, target: P2, - fstype: Option<&P3>, + fstype: Option, flags: MsFlags, - data: Option<&P4>) -> Result<()> { + data: Option) -> Result<()> { + use std::ffi::CStr; + use std::ptr; use libc; - let res = try!(try!(try!(try!( - source.with_nix_path(|source| { - target.with_nix_path(|target| { - fstype.with_nix_path(|fstype| { - data.with_nix_path(|data| { - unsafe { - ffi::mount(source.as_ext_str(), - target.as_ext_str(), - fstype, - flags.bits, - data as *const libc::c_void) - } - }) - }) - }) - }))))); + let source = source.as_ref().map(NixString::as_ref); + let fstype = fstype.as_ref().map(NixString::as_ref); + let data = data.as_ref().map(NixString::as_ref); + let res = unsafe { + ffi::mount(source.map(CStr::as_ptr).unwrap_or(ptr::null()), + target.as_ref().as_ptr(), + fstype.map(CStr::as_ptr).unwrap_or(ptr::null()), + flags.bits, + data.map(CStr::as_ptr).unwrap_or(ptr::null()) as *const libc::c_void) + }; - return from_ffi(res); -} -*/ + Errno::result(res).map(drop) +}*/ -pub fn umount(target: &P) -> Result<()> { - let res = try!(target.with_nix_path(|cstr| { - unsafe { ffi::umount(cstr.as_ptr()) } - })); +pub fn umount(target: P) -> Result<()> { + let res = unsafe { + ffi::umount(target.as_ref().as_ptr()) + }; Errno::result(res).map(drop) } -pub fn umount2(target: &P, flags: MntFlags) -> Result<()> { - let res = try!(target.with_nix_path(|cstr| { - unsafe { ffi::umount2(cstr.as_ptr(), flags.bits) } - })); +pub fn umount2(target: P, flags: MntFlags) -> Result<()> { + let res = unsafe { + ffi::umount2(target.as_ref().as_ptr(), flags.bits) + }; Errno::result(res).map(drop) } diff --git a/src/nix_string.rs b/src/nix_string.rs new file mode 100644 index 0000000000..ab4ca46fed --- /dev/null +++ b/src/nix_string.rs @@ -0,0 +1,47 @@ +use std::ffi::{CStr, CString}; +use std::borrow::Cow; + +/// Represents a type that can be converted to a `&CStr` without fail. +/// +/// Note: this trait exists in place of `AsRef` because is not +/// implemented until Rust 1.7.0 +pub trait NixString { + fn as_ref(&self) -> &CStr; +} + +impl<'a> NixString for Cow<'a, CStr> { + fn as_ref(&self) -> &CStr { + self + } +} + +impl NixString for CStr { + fn as_ref(&self) -> &CStr { + self + } +} + +impl NixString for CString { + fn as_ref(&self) -> &CStr { + self + } +} + +impl<'a, T: ?Sized + NixString> NixString for &'a T { + fn as_ref(&self) -> &CStr { + NixString::as_ref(*self) + } +} + +impl<'a, T: ?Sized + NixString> NixString for &'a mut T { + fn as_ref(&self) -> &CStr { + NixString::as_ref(*self) + } +} + +#[macro_export] +macro_rules! cstr { + ($s:expr) => { + unsafe { ::std::ffi::CStr::from_ptr(concat!($s, "\0").as_ptr() as *const _) } + } +} diff --git a/src/sys/mman.rs b/src/sys/mman.rs index cb36cf7bfd..919e257721 100644 --- a/src/sys/mman.rs +++ b/src/sys/mman.rs @@ -1,4 +1,4 @@ -use {NixPath, Error}; +use NixString; use errno::{Errno, Result}; use fcntl::OFlag; 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, let ret = unsafe { ffi::mmap(addr, length, prot, flags, fd, offset) }; if ret as isize == MAP_FAILED { - Err(Error::Sys(Errno::last())) + Err(Errno::last()) } else { Ok(ret) } @@ -222,20 +222,14 @@ pub fn msync(addr: *const c_void, length: size_t, flags: MmapSync) -> Result<()> Errno::result(unsafe { ffi::msync(addr, length, flags) }).map(drop) } -pub fn shm_open(name: &P, flag: OFlag, mode: Mode) -> Result { - let ret = try!(name.with_nix_path(|cstr| { - unsafe { - ffi::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as mode_t) - } - })); - - Errno::result(ret) +pub fn shm_open(name: P, flag: OFlag, mode: Mode) -> Result { + unsafe { + Errno::result(ffi::shm_open(name.as_ref().as_ptr(), flag.bits(), mode.bits() as mode_t)) + } } -pub fn shm_unlink(name: &P) -> Result<()> { - let ret = try!(name.with_nix_path(|cstr| { - unsafe { ffi::shm_unlink(cstr.as_ptr()) } - })); - - Errno::result(ret).map(drop) +pub fn shm_unlink(name: P) -> Result<()> { + unsafe { + Errno::result(ffi::shm_unlink(name.as_ref().as_ptr())).map(drop) + } } diff --git a/src/sys/ptrace.rs b/src/sys/ptrace.rs index 9d8e6932a2..8520235c43 100644 --- a/src/sys/ptrace.rs +++ b/src/sys/ptrace.rs @@ -1,4 +1,3 @@ -use Error; use errno::{Errno, Result}; use libc::{pid_t, c_void, c_long}; @@ -87,7 +86,7 @@ fn ptrace_peek(request: ptrace::PtraceRequest, pid: pid_t, addr: *mut c_void, da ffi::ptrace(request, pid, addr, data) }; match Errno::result(ret) { - Ok(..) | Err(Error::Sys(Errno::UnknownErrno)) => Ok(ret), + Ok(..) | Err(Errno::UnknownErrno) => Ok(ret), err @ Err(..) => err, } } diff --git a/src/sys/quota.rs b/src/sys/quota.rs index 7a7718e45a..2390b71cdc 100644 --- a/src/sys/quota.rs +++ b/src/sys/quota.rs @@ -1,4 +1,4 @@ -use NixPath; +use NixString; use errno::{Errno, Result}; use libc::{c_int, c_char}; @@ -80,45 +80,40 @@ mod ffi { } use std::ptr; +use std::ffi::CStr; -fn quotactl(cmd: quota::QuotaCmd, special: Option<&P>, id: c_int, addr: *mut c_char) -> Result<()> { +fn quotactl(cmd: quota::QuotaCmd, special: Option

, id: c_int, addr: *mut c_char) -> Result<()> { unsafe { Errno::clear(); - let res = try!( - match special { - Some(dev) => dev.with_nix_path(|path| ffi::quotactl(cmd.as_int(), path.as_ptr(), id, addr)), - None => Ok(ffi::quotactl(cmd.as_int(), ptr::null(), id, addr)), - } - ); + let special = special.as_ref().map(NixString::as_ref); + let res = ffi::quotactl(cmd.as_int(), special.map(CStr::as_ptr).unwrap_or(ptr::null()), id, addr); Errno::result(res).map(drop) } } -pub fn quotactl_on(which: quota::QuotaType, special: &P, format: quota::QuotaFmt, quota_file: &P) -> Result<()> { - try!(quota_file.with_nix_path(|path| { - let mut path_copy = path.to_bytes_with_nul().to_owned(); - let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char; - quotactl(quota::QuotaCmd(quota::Q_QUOTAON, which), Some(special), format as c_int, p) - })) +pub fn quotactl_on(which: quota::QuotaType, special: P0, format: quota::QuotaFmt, quota_file: P1) -> Result<()> { + let mut path_copy = quota_file.as_ref().to_bytes_with_nul().to_owned(); + let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char; + quotactl(quota::QuotaCmd(quota::Q_QUOTAON, which), Some(special), format as c_int, p) } -pub fn quotactl_off(which: quota::QuotaType, special: &P) -> Result<()> { +pub fn quotactl_off(which: quota::QuotaType, special: P) -> Result<()> { quotactl(quota::QuotaCmd(quota::Q_QUOTAOFF, which), Some(special), 0, ptr::null_mut()) } -pub fn quotactl_sync(which: quota::QuotaType, special: Option<&P>) -> Result<()> { +pub fn quotactl_sync(which: quota::QuotaType, special: Option

) -> Result<()> { quotactl(quota::QuotaCmd(quota::Q_SYNC, which), special, 0, ptr::null_mut()) } -pub fn quotactl_get(which: quota::QuotaType, special: &P, id: c_int, dqblk: &mut quota::Dqblk) -> Result<()> { +pub fn quotactl_get(which: quota::QuotaType, special: P, id: c_int, dqblk: &mut quota::Dqblk) -> Result<()> { use std::mem; unsafe { quotactl(quota::QuotaCmd(quota::Q_GETQUOTA, which), Some(special), id, mem::transmute(dqblk)) } } -pub fn quotactl_set(which: quota::QuotaType, special: &P, id: c_int, dqblk: "a::Dqblk) -> Result<()> { +pub fn quotactl_set(which: quota::QuotaType, special: P, id: c_int, dqblk: "a::Dqblk) -> Result<()> { use std::mem; let mut dqblk_copy = *dqblk; unsafe { diff --git a/src/sys/signalfd.rs b/src/sys/signalfd.rs index 7d1455e605..ed9ddf3e6f 100644 --- a/src/sys/signalfd.rs +++ b/src/sys/signalfd.rs @@ -113,7 +113,7 @@ impl SignalFd { match unistd::read(self.0, &mut buffer) { Ok(SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute_copy(&buffer) })), Ok(_) => unreachable!("partial read on signalfd"), - Err(Error::Sys(Errno::EAGAIN)) => Ok(None), + Err(Errno::EAGAIN) => Ok(None), Err(error) => Err(error) } } diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 49a1ecf5a9..b2968d955d 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -1,5 +1,5 @@ use super::{consts, sa_family_t}; -use {NixPath, Error}; +use NixString; use errno::{Errno, Result}; use libc; use std::{fmt, hash, mem, net, ptr}; @@ -342,27 +342,26 @@ pub struct UnixAddr(pub libc::sockaddr_un, pub usize); impl UnixAddr { /// Create a new sockaddr_un representing a filesystem path. - pub fn new(path: &P) -> Result { - try!(path.with_nix_path(|cstr| { - unsafe { - let mut ret = libc::sockaddr_un { - sun_family: AddressFamily::Unix as sa_family_t, - .. mem::zeroed() - }; + pub fn new(path: P) -> Result { + let cstr = path.as_ref(); + unsafe { + let mut ret = libc::sockaddr_un { + sun_family: AddressFamily::Unix as sa_family_t, + .. mem::zeroed() + }; - let bytes = cstr.to_bytes_with_nul(); + let bytes = cstr.to_bytes_with_nul(); - if bytes.len() > ret.sun_path.len() { - return Err(Error::Sys(Errno::ENAMETOOLONG)); - } + if bytes.len() > ret.sun_path.len() { + return Err(Errno::ENAMETOOLONG); + } - ptr::copy_nonoverlapping(bytes.as_ptr(), - ret.sun_path.as_mut_ptr() as *mut u8, - bytes.len()); + ptr::copy_nonoverlapping(bytes.as_ptr(), + ret.sun_path.as_mut_ptr() as *mut u8, + bytes.len()); - Ok(UnixAddr(ret, bytes.len())) - } - })) + Ok(UnixAddr(ret, bytes.len())) + } } /// Create a new sockaddr_un representing an address in the @@ -377,7 +376,7 @@ impl UnixAddr { }; if path.len() > ret.sun_path.len() { - return Err(Error::Sys(Errno::ENAMETOOLONG)); + return Err(Errno::ENAMETOOLONG); } // Abstract addresses are represented by sun_path[0] == @@ -458,7 +457,7 @@ impl SockAddr { SockAddr::Inet(addr) } - pub fn new_unix(path: &P) -> Result { + pub fn new_unix(path: P) -> Result { Ok(SockAddr::Unix(try!(UnixAddr::new(path)))) } diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 60b138eddd..30c8cab591 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1,7 +1,6 @@ //! Socket interface functions //! //! [Further reading](http://man7.org/linux/man-pages/man7/socket.7.html) -use Error; use errno::{Errno, Result}; use features; use fcntl::{fcntl, FD_CLOEXEC, O_NONBLOCK}; @@ -610,7 +609,7 @@ pub unsafe fn sockaddr_storage_to_addr( len: usize) -> Result { if len < mem::size_of_val(&addr.ss_family) { - return Err(Error::Sys(Errno::ENOTCONN)); + return Err(Errno::ENOTCONN); } match addr.ss_family as c_int { diff --git a/src/sys/stat.rs b/src/sys/stat.rs index 391924dac0..4e2680ba11 100644 --- a/src/sys/stat.rs +++ b/src/sys/stat.rs @@ -1,7 +1,7 @@ pub use libc::dev_t; pub use libc::stat as FileStat; -use NixPath; +use NixString; use errno::{Errno, Result}; use libc::mode_t; use std::mem; @@ -50,12 +50,10 @@ bitflags! { } } -pub fn mknod(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> { - let res = try!(path.with_nix_path(|cstr| { - unsafe { - ffi::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) - } - })); +pub fn mknod(path: P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> { + let res = unsafe { + ffi::mknod(path.as_ref().as_ptr(), kind.bits | perm.bits() as mode_t, dev) + }; Errno::result(res).map(drop) } @@ -73,26 +71,22 @@ pub fn umask(mode: Mode) -> Mode { Mode::from_bits(prev).expect("[BUG] umask returned invalid Mode") } -pub fn stat(path: &P) -> Result { +pub fn stat(path: P) -> Result { let mut dst = unsafe { mem::uninitialized() }; - let res = try!(path.with_nix_path(|cstr| { - unsafe { - ffi::stat(cstr.as_ptr(), &mut dst as *mut FileStat) - } - })); + let res = unsafe { + ffi::stat(path.as_ref().as_ptr(), &mut dst as *mut FileStat) + }; try!(Errno::result(res)); Ok(dst) } -pub fn lstat(path: &P) -> Result { +pub fn lstat(path: P) -> Result { let mut dst = unsafe { mem::uninitialized() }; - let res = try!(path.with_nix_path(|cstr| { - unsafe { - ffi::lstat(cstr.as_ptr(), &mut dst as *mut FileStat) - } - })); + let res = unsafe { + ffi::lstat(path.as_ref().as_ptr(), &mut dst as *mut FileStat) + }; try!(Errno::result(res)); diff --git a/src/sys/statfs.rs b/src/sys/statfs.rs index 0552e3d064..d18f318974 100644 --- a/src/sys/statfs.rs +++ b/src/sys/statfs.rs @@ -1,4 +1,4 @@ -use NixPath; +use NixString; use errno::{Errno, Result}; use std::os::unix::io::AsRawFd; @@ -98,14 +98,10 @@ mod ffi { } } -pub fn statfs(path: &P, stat: &mut vfs::Statfs) -> Result<()> { +pub fn statfs(path: P, stat: &mut vfs::Statfs) -> Result<()> { unsafe { Errno::clear(); - let res = try!( - path.with_nix_path(|path| ffi::statfs(path.as_ptr(), stat)) - ); - - Errno::result(res).map(drop) + Errno::result(ffi::statfs(path.as_ref().as_ptr(), stat)).map(drop) } } diff --git a/src/sys/statvfs.rs b/src/sys/statvfs.rs index abfc6c9b3d..4203ae12b8 100644 --- a/src/sys/statvfs.rs +++ b/src/sys/statvfs.rs @@ -2,7 +2,7 @@ //! //! See the `vfs::Statvfs` struct for some rusty wrappers -use NixPath; +use NixString; use errno::{Errno, Result}; use std::os::unix::io::AsRawFd; @@ -14,7 +14,7 @@ pub mod vfs { use libc::{c_ulong,c_int}; use std::os::unix::io::AsRawFd; - use {Result, NixPath}; + use {Result, NixString}; use super::{statvfs, fstatvfs}; @@ -85,14 +85,14 @@ pub mod vfs { impl Statvfs { /// Create a new `Statvfs` object and fill it with information about /// the mount that contains `path` - pub fn for_path(path: &P) -> Result { + pub fn for_path(path: P) -> Result { let mut stat = Statvfs::default(); let res = statvfs(path, &mut stat); res.map(|_| stat) } /// Replace information in this struct with information about `path` - pub fn update_with_path(&mut self, path: &P) -> Result<()> { + pub fn update_with_path(&mut self, path: P) -> Result<()> { statvfs(path, self) } @@ -141,13 +141,10 @@ mod ffi { } /// Fill an existing `Statvfs` object with information about the `path` -pub fn statvfs(path: &P, stat: &mut vfs::Statvfs) -> Result<()> { +pub fn statvfs(path: P, stat: &mut vfs::Statvfs) -> Result<()> { unsafe { Errno::clear(); - let res = try!( - path.with_nix_path(|path| ffi::statvfs(path.as_ptr(), stat)) - ); - + let res = ffi::statvfs(path.as_ref().as_ptr(), stat); Errno::result(res).map(drop) } } @@ -168,7 +165,7 @@ mod test { #[test] fn statvfs_call() { let mut stat = vfs::Statvfs::default(); - statvfs("/".as_bytes(), &mut stat).unwrap() + statvfs(cstr!("/"), &mut stat).unwrap() } #[test] diff --git a/src/unistd.rs b/src/unistd.rs index f2c1fdced0..8e89d44cc9 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1,6 +1,6 @@ //! Standard symbolic constants and types //! -use {NixPath, Error}; +use NixString; use errno::{Errno, Result}; use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC}; use fcntl::FcntlArg::{F_SETFD, F_SETFL}; @@ -134,7 +134,7 @@ pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { #[inline] fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { if oldfd == newfd { - return Err(Error::Sys(Errno::EINVAL)); + return Err(Errno::EINVAL); } let fd = try!(dup2(oldfd, newfd)); @@ -150,14 +150,15 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { } #[inline] -pub fn chdir(path: &P) -> Result<()> { - let res = try!(path.with_nix_path(|cstr| { - unsafe { ffi::chdir(cstr.as_ptr()) } - })); +pub fn chdir(path: P) -> Result<()> { + let res = unsafe { + ffi::chdir(path.as_ref().as_ptr()) + }; Errno::result(res).map(drop) } +// TODO: do this without allocations fn to_exec_array(args: &[CString]) -> Vec<*const c_char> { use std::ptr; use libc::c_char; @@ -168,26 +169,26 @@ fn to_exec_array(args: &[CString]) -> Vec<*const c_char> { } #[inline] -pub fn execv(path: &CString, argv: &[CString]) -> Result<()> { +pub fn execv(path: P, argv: &[CString]) -> Result<()> { let args_p = to_exec_array(argv); unsafe { - ffi::execv(path.as_ptr(), args_p.as_ptr()) + ffi::execv(path.as_ref().as_ptr(), args_p.as_ptr()) }; - Err(Error::Sys(Errno::last())) + Err(Errno::last()) } #[inline] -pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<()> { +pub fn execve(path: P, args: &[CString], env: &[CString]) -> Result<()> { let args_p = to_exec_array(args); let env_p = to_exec_array(env); unsafe { - ffi::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + ffi::execve(path.as_ref().as_ptr(), args_p.as_ptr(), env_p.as_ptr()) }; - Err(Error::Sys(Errno::last())) + Err(Errno::last()) } #[inline] @@ -198,7 +199,7 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<()> { ffi::execvp(filename.as_ptr(), args_p.as_ptr()) }; - Err(Error::Sys(Errno::last())) + Err(Errno::last()) } pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> { @@ -305,27 +306,25 @@ pub fn isatty(fd: RawFd) -> Result { } else { match Errno::last() { Errno::ENOTTY => Ok(false), - err => Err(Error::Sys(err)), + err => Err(err), } } } } -pub fn unlink(path: &P) -> Result<()> { - let res = try!(path.with_nix_path(|cstr| { - unsafe { - ffi::unlink(cstr.as_ptr()) - } - })); +pub fn unlink(path: P) -> Result<()> { + let res = unsafe { + ffi::unlink(path.as_ref().as_ptr()) + }; Errno::result(res).map(drop) } #[inline] -pub fn chroot(path: &P) -> Result<()> { - let res = try!(path.with_nix_path(|cstr| { - unsafe { ffi::chroot(cstr.as_ptr()) } - })); +pub fn chroot(path: P) -> Result<()> { + let res = unsafe { + ffi::chroot(path.as_ref().as_ptr()) + }; Errno::result(res).map(drop) } @@ -373,28 +372,24 @@ pub fn getegid() -> gid_t { #[cfg(any(target_os = "linux", target_os = "android"))] mod linux { use sys::syscall::{syscall, SYSPIVOTROOT}; - use NixPath; + use NixString; use errno::{Errno, Result}; #[cfg(feature = "execvpe")] use std::ffi::CString; - pub fn pivot_root( - new_root: &P1, put_old: &P2) -> Result<()> { - let res = try!(try!(new_root.with_nix_path(|new_root| { - put_old.with_nix_path(|put_old| { - unsafe { - syscall(SYSPIVOTROOT, new_root.as_ptr(), put_old.as_ptr()) - } - }) - }))); + pub fn pivot_root( + new_root: P1, put_old: P2) -> Result<()> { + let res = unsafe { + syscall(SYSPIVOTROOT, new_root.as_ref().as_ptr(), put_old.as_ref().as_ptr()) + }; Errno::result(res).map(drop) } #[inline] #[cfg(feature = "execvpe")] - pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<()> { + pub fn execvpe(filename: F, args: &[CString], env: &[CString]) -> Result<()> { use std::ptr; use libc::c_char; @@ -405,9 +400,9 @@ mod linux { env_p.push(ptr::null()); unsafe { - super::ffi::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + super::ffi::execvpe(filename.as_ref().as_ptr(), args_p.as_ptr(), env_p.as_ptr()) }; - Err(Error::Sys(Errno::last())) + Err(Errno::last()) } } diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 258cde07dd..7dc4b07baa 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -1,7 +1,7 @@ use nix::sys::socket::{InetAddr, UnixAddr, getsockname}; -use std::{mem, net}; use std::path::Path; -use std::str::FromStr; +use std::{mem, net}; +use std::str::{self, FromStr}; use std::os::unix::io::{AsRawFd, RawFd}; use ports::localhost; use libc::c_char; @@ -30,13 +30,14 @@ pub fn test_inetv4_addr_to_sock_addr() { #[test] pub fn test_path_to_sock_addr() { - let actual = Path::new("/foo/bar"); + let actual = cstr!("/foo/bar"); let addr = UnixAddr::new(actual).unwrap(); let expect: &'static [c_char] = unsafe { mem::transmute(&b"/foo/bar"[..]) }; assert_eq!(&addr.0.sun_path[..8], expect); - assert_eq!(addr.path(), Some(actual)); + let actual = str::from_utf8(actual.to_bytes()).unwrap(); + assert_eq!(addr.path(), Some(Path::new(actual))); } #[test] diff --git a/test/sys/test_termios.rs b/test/sys/test_termios.rs index a41304d73f..ce82282b3f 100644 --- a/test/sys/test_termios.rs +++ b/test/sys/test_termios.rs @@ -1,6 +1,6 @@ use nix::errno::Errno; use nix::sys::termios; -use nix::{Error, unistd}; +use nix::unistd; #[test] fn test_tcgetattr() { @@ -11,8 +11,8 @@ fn test_tcgetattr() { Ok(true) => assert!(termios.is_ok()), // If it's an invalid file descriptor, tcgetattr should also return // the same error - Err(Error::Sys(Errno::EBADF)) => { - assert_eq!(termios.err(), Some(Error::Sys(Errno::EBADF))); + Err(Errno::EBADF) => { + assert_eq!(termios.err(), Some(Errno::EBADF)); }, // Otherwise it should return any error _ => assert!(termios.is_err()) diff --git a/test/test_mq.rs b/test/test_mq.rs index 2d7a895594..f953047483 100644 --- a/test/test_mq.rs +++ b/test/test_mq.rs @@ -12,7 +12,6 @@ use nix::unistd::{fork, read, write, pipe}; use nix::unistd::Fork::{Child, Parent}; use nix::sys::wait::*; use nix::errno::Errno::*; -use nix::Error::Sys; #[test] fn test_mq_send_and_receive() { @@ -118,10 +117,10 @@ fn test_mq_unlink() { assert!(res_unlink == Ok(()) ); let res_unlink_not_opened = mq_unlink(mq_name_not_opened); - assert!(res_unlink_not_opened == Err(Sys(ENOENT)) ); + assert!(res_unlink_not_opened == Err(ENOENT) ); mq_close(mqd).unwrap(); let res_unlink_after_close = mq_unlink(mq_name_opened); - assert!(res_unlink_after_close == Err(Sys(ENOENT)) ); + assert!(res_unlink_after_close == Err(ENOENT) ); } diff --git a/test/test_stat.rs b/test/test_stat.rs index 4b22c29640..471a564945 100644 --- a/test/test_stat.rs +++ b/test/test_stat.rs @@ -1,6 +1,8 @@ use std::fs::File; use std::os::unix::fs::symlink; +use std::os::unix::ffi::OsStrExt; use std::os::unix::prelude::AsRawFd; +use std::ffi::CString; use libc::{S_IFMT, S_IFLNK}; @@ -67,7 +69,7 @@ fn test_stat_and_fstat() { let filename = tempdir.path().join("foo.txt"); let file = File::create(&filename).unwrap(); - let stat_result = stat(&filename); + let stat_result = stat(CString::new(filename.as_os_str().as_bytes()).unwrap()); assert_stat_results(stat_result); let fstat_result = fstat(file.as_raw_fd()); @@ -86,10 +88,10 @@ fn test_stat_fstat_lstat() { // should be the same result as calling stat, // since it's a regular file - let stat_result = lstat(&filename); + let stat_result = lstat(CString::new(filename.as_os_str().as_bytes()).unwrap()); assert_stat_results(stat_result); - let lstat_result = lstat(&linkname); + let lstat_result = lstat(CString::new(linkname.as_os_str().as_bytes()).unwrap()); assert_lstat_results(lstat_result); let fstat_result = fstat(link.as_raw_fd());