Skip to content

Commit

Permalink
Add NixPath, NixError, and NixResult.
Browse files Browse the repository at this point in the history
  • Loading branch information
utkarshkukreti authored and carllerche committed Feb 11, 2015
1 parent 51becf7 commit effb423
Show file tree
Hide file tree
Showing 19 changed files with 618 additions and 554 deletions.
626 changes: 303 additions & 323 deletions src/errno.rs

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::old_path::Path;
use libc::{c_int, mode_t};
use errno::{SysResult, SysError};
use errno::Errno;
use {NixError, NixResult, NixPath};
use sys::stat::Mode;
use utils::ToCStr;

pub use self::consts::*;
pub use self::ffi::flock;
Expand Down Expand Up @@ -71,11 +70,15 @@ mod ffi {
}
}

pub fn open(path: &Path, oflag: OFlag, mode: Mode) -> SysResult<Fd> {
let fd = unsafe { ffi::open(path.to_c_str().as_ptr(), oflag.bits(), mode.bits() as mode_t) };
pub fn open<P: NixPath>(path: P, oflag: OFlag, mode: Mode) -> NixResult<Fd> {
let fd = try!(path.with_nix_path(|ptr| {
unsafe {
ffi::open(ptr, oflag.bits(), mode.bits() as mode_t)
}
}));

if fd < 0 {
return Err(SysError::last());
return Err(NixError::Sys(Errno::last()));
}

Ok(fd)
Expand All @@ -102,7 +105,7 @@ pub enum FcntlArg<'a> {
}

// TODO: Figure out how to handle value fcntl returns
pub fn fcntl(fd: Fd, arg: FcntlArg) -> SysResult<()> {
pub fn fcntl(fd: Fd, arg: FcntlArg) -> NixResult<()> {
use self::FcntlArg::*;

let res = unsafe {
Expand All @@ -114,7 +117,7 @@ pub fn fcntl(fd: Fd, arg: FcntlArg) -> SysResult<()> {
};

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

Ok(())
Expand Down
8 changes: 3 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![crate_name = "nix"]

#![feature(core, linkage, libc, hash, os, path, std_misc)]
#![feature(collections, core, linkage, libc, hash, os)]
#![allow(non_camel_case_types)]

#[macro_use]
Expand All @@ -12,8 +12,8 @@ extern crate core;
// Re-export some libc constants
pub use libc::{c_int, c_void};

#[cfg(unix)]
pub use errno::{SysResult, SysError};
mod nix;
pub use nix::{NixResult, NixError, NixPath, from_ffi};

#[cfg(unix)]
pub mod errno;
Expand All @@ -38,5 +38,3 @@ pub mod syscall;

#[cfg(unix)]
pub mod unistd;

mod utils;
68 changes: 35 additions & 33 deletions src/mount.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use std::ptr;
use std::old_path::Path;
use libc::{c_ulong, c_int, c_void};
use errno::{SysResult, from_ffi};
use utils::ToCStr;
use {NixResult, NixPath, from_ffi};

bitflags!(
flags MsFlags: c_ulong {
Expand Down Expand Up @@ -68,42 +65,47 @@ mod ffi {
}
}

pub fn mount(
source: Option<&Path>,
target: &Path,
fstype: Option<&str>,
// XXX: Should `data` be a `NixPath` here?
pub fn mount<P1: NixPath, P2: NixPath, P3: NixPath, P4: NixPath>(
source: Option<P1>,
target: P2,
fstype: Option<P3>,
flags: MsFlags,
data: Option<&str>) -> SysResult<()> {

let source = source.map(|s| s.to_c_str());
let target = target.to_c_str();
let fstype = fstype.map(|s| s.to_c_str());
let data = data.map(|s| s.to_c_str());

let res = unsafe {
ffi::mount(
source.as_ref().map(|s| s.as_ptr()).unwrap_or(ptr::null()),
target.as_ptr(),
fstype.as_ref().map(|s| s.as_ptr()).unwrap_or(ptr::null()),
flags.bits,
data.map(|s| s.as_ptr() as *const c_void).unwrap_or(ptr::null()))
};

from_ffi(res)
data: Option<P4>) -> NixResult<()> {
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,
target,
fstype,
flags.bits,
data as *const libc::c_void)
}
})
})
})
})))));

return from_ffi(res);
}

pub fn umount(target: &Path) -> SysResult<()> {
let target = target.to_c_str();

let res = unsafe { ffi::umount(target.as_ptr()) };
pub fn umount<P: NixPath>(target: P) -> NixResult<()> {
let res = try!(target.with_nix_path(|ptr| {
unsafe { ffi::umount(ptr) }
}));

from_ffi(res)
}

pub fn umount2(target: &Path, flags: MntFlags) -> SysResult<()> {
let target = target.to_c_str();

let res = unsafe { ffi::umount2(target.as_ptr(), flags.bits) };
pub fn umount2<P: NixPath>(target: P, flags: MntFlags) -> NixResult<()> {
let res = try!(target.with_nix_path(|ptr| {
unsafe { ffi::umount2(ptr, flags.bits) }
}));

from_ffi(res)
}
57 changes: 57 additions & 0 deletions src/nix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use libc;
use std;

use errno::Errno;

pub type NixResult<T> = Result<T, NixError>;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum NixError {
Sys(Errno),
InvalidPath
}

pub trait NixPath {
fn with_nix_path<T, F>(&self, f: F) -> Result<T, NixError>
where F: FnOnce(*const libc::c_char) -> T;
}

impl<'a> NixPath for &'a [u8] {
fn with_nix_path<T, F>(&self, f: F) -> Result<T, NixError>
where F: FnOnce(*const libc::c_char) -> T
{
// TODO: Extract this size as a const
let mut buf = [0u8; 4096];

if self.len() >= 4096 {
return Err(NixError::InvalidPath);
}

match self.position_elem(&0) {
Some(_) => Err(NixError::InvalidPath),
None => {
std::slice::bytes::copy_memory(&mut buf, self);
Ok(f(buf.as_ptr() as *const libc::c_char))
}
}
}
}

impl<P: NixPath> NixPath for Option<P> {
fn with_nix_path<T, F>(&self, f: F) -> Result<T, NixError>
where F: FnOnce(*const libc::c_char) -> T
{
match *self {
Some(ref some) => some.with_nix_path(f),
None => b"".with_nix_path(f)
}
}
}

#[inline]
pub fn from_ffi(res: libc::c_int) -> NixResult<()> {
if res != 0 {
return Err(NixError::Sys(Errno::last()));
}
Ok(())
}
15 changes: 8 additions & 7 deletions src/sched.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::mem;
use libc::{c_int, c_uint, c_void, c_ulong};
use super::{SysResult, SysError};
use errno::Errno;
use {NixResult, NixError};

pub type CloneFlags = c_uint;

Expand Down Expand Up @@ -123,21 +124,21 @@ mod ffi {
}
}

pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> SysResult<()> {
pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> NixResult<()> {
use libc::{pid_t, size_t};

let res = unsafe {
ffi::sched_setaffinity(pid as pid_t, mem::size_of::<CpuSet>() as size_t, mem::transmute(cpuset))
};

if res != 0 {
Err(SysError::last())
Err(NixError::Sys(Errno::last()))
} else {
Ok(())
}
}

pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> SysResult<()> {
pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> NixResult<()> {
extern "C" fn callback(data: *mut CloneCb) -> c_int {
let cb: &mut CloneCb = unsafe { &mut *data };
(*cb)() as c_int
Expand All @@ -149,17 +150,17 @@ pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> SysResult<
};

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

Ok(())
}

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

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

Ok(())
Expand Down
13 changes: 7 additions & 6 deletions src/sys/epoll.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::fmt;
use libc::c_int;
use errno::Errno;
use {NixError, NixResult, from_ffi};
use fcntl::Fd;
use errno::{SysResult, SysError, from_ffi};

mod ffi {
use libc::{c_int};
Expand Down Expand Up @@ -85,30 +86,30 @@ pub struct EpollEvent {
}

#[inline]
pub fn epoll_create() -> SysResult<Fd> {
pub fn epoll_create() -> NixResult<Fd> {
let res = unsafe { ffi::epoll_create(1024) };

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

Ok(res)
}

#[inline]
pub fn epoll_ctl(epfd: Fd, op: EpollOp, fd: Fd, event: &EpollEvent) -> SysResult<()> {
pub fn epoll_ctl(epfd: Fd, op: EpollOp, fd: Fd, event: &EpollEvent) -> NixResult<()> {
let res = unsafe { ffi::epoll_ctl(epfd, op as c_int, fd, event as *const EpollEvent) };
from_ffi(res)
}

#[inline]
pub fn epoll_wait(epfd: Fd, events: &mut [EpollEvent], timeout_ms: usize) -> SysResult<usize> {
pub fn epoll_wait(epfd: Fd, events: &mut [EpollEvent], timeout_ms: usize) -> NixResult<usize> {
let res = unsafe {
ffi::epoll_wait(epfd, events.as_mut_ptr(), events.len() as c_int, timeout_ms as c_int)
};

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

Ok(res as usize)
Expand Down
11 changes: 6 additions & 5 deletions src/sys/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
*/

use libc::{timespec, time_t, c_int, c_long, uintptr_t};
use errno::{SysResult, SysError};
use errno::Errno;
use fcntl::Fd;
use std::fmt;
use {NixError, NixResult};

pub use self::ffi::kevent as KEvent;

Expand Down Expand Up @@ -158,11 +159,11 @@ bitflags!(
pub const EV_POLL: EventFlag = EV_FLAG0;
pub const EV_OOBAND: EventFlag = EV_FLAG1;

pub fn kqueue() -> SysResult<Fd> {
pub fn kqueue() -> NixResult<Fd> {
let res = unsafe { ffi::kqueue() };

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

Ok(res)
Expand All @@ -171,7 +172,7 @@ pub fn kqueue() -> SysResult<Fd> {
pub fn kevent(kq: Fd,
changelist: &[KEvent],
eventlist: &mut [KEvent],
timeout_ms: usize) -> SysResult<usize> {
timeout_ms: usize) -> NixResult<usize> {

// Convert ms to timespec
let timeout = timespec {
Expand All @@ -190,7 +191,7 @@ pub fn kevent(kq: Fd,
};

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

return Ok(res as usize)
Expand Down
7 changes: 4 additions & 3 deletions src/sys/eventfd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::mem;
use libc::{c_int, c_uint};
use errno::Errno;
use fcntl::Fd;
use errno::{SysResult, SysError};
use {NixError, NixResult};

bitflags!(
flags EventFdFlag: c_int {
Expand All @@ -11,7 +12,7 @@ bitflags!(
}
);

pub fn eventfd(initval: usize, flags: EventFdFlag) -> SysResult<Fd> {
pub fn eventfd(initval: usize, flags: EventFdFlag) -> NixResult<Fd> {
type F = unsafe extern "C" fn(initval: c_uint, flags: c_int) -> c_int;

extern {
Expand All @@ -29,7 +30,7 @@ pub fn eventfd(initval: usize, flags: EventFdFlag) -> SysResult<Fd> {
};

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

Ok(res)
Expand Down
Loading

0 comments on commit effb423

Please sign in to comment.