diff options
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | src/fcntl.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/mount.rs | 3 | ||||
-rw-r--r-- | src/sys.rs | 51 | ||||
-rw-r--r-- | src/sys/epoll.rs | 77 | ||||
-rw-r--r-- | src/sys/mod.rs | 2 | ||||
-rw-r--r-- | src/sys/stat.rs | 51 | ||||
-rw-r--r-- | src/syscall.rs | 2 | ||||
-rw-r--r-- | src/unistd.rs | 2 |
11 files changed, 149 insertions, 61 deletions
@@ -1,5 +1,5 @@ [package] -name = "linux" +name = "nix" version = "0.0.1" authors = ["Carl Lerche <me@carllerche.com>"] @@ -1,8 +1,11 @@ -# Rust bindings to Linux APIs +# Rust bindings to *nix APIs -The goal is to provide rust friendly bindings to Linux APIs. This is -very much a work and progress and I am treating it as where I put -bindings that I need vs. spreading them around the various libs that I -work on. +Rust friendly bindings to various *nix platform APIs (Linux, Darwin, +...). The goal is to not provide a 100% unified interface, but try as +possible as well as providing platform specific APIs. It is up to the +consumer of this library to decide how portable they want to be. + +This is very much a work in progress and I'm mostly just adding bindings +as I need them. Of course, PRs welcome :) diff --git a/src/fcntl.rs b/src/fcntl.rs index 57325c86..f4f0fded 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -1,7 +1,8 @@ -use std::c_str::CString; +#![cfg(target_os = "linux")] + use std::path::Path; use std::io::FilePermission; -use libc::{mode_t, c_int}; +use libc::c_int; use errno::{SysResult, SysError, from_ffi}; pub type Fd = c_int; @@ -1,4 +1,4 @@ -#![crate_name = "linux"] +#![crate_name = "nix"] #![feature(globs)] extern crate libc; diff --git a/src/mount.rs b/src/mount.rs index cae6d239..9e6a2cbb 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -1,4 +1,5 @@ -use std::c_str::CString; +#![cfg(target_os = "linux")] + use std::ptr; use std::path::Path; use libc::{c_ulong, c_int, c_void}; diff --git a/src/sys.rs b/src/sys.rs deleted file mode 100644 index 1aa19534..00000000 --- a/src/sys.rs +++ /dev/null @@ -1,51 +0,0 @@ -pub mod stat { - pub use libc::dev_t; - - use std::fmt; - use std::io::FilePermission; - use std::path::Path; - use libc::mode_t; - use errno::{SysResult, from_ffi}; - - mod ffi { - use libc::{c_char, c_int, mode_t, dev_t}; - - extern { - pub fn mknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> c_int; - pub fn umask(mask: mode_t) -> mode_t; - } - } - - bitflags!( - flags SFlag: mode_t { - static S_IFREG = 0o100000, - static S_IFCHR = 0o020000, - static S_IFBLK = 0o060000, - static S_IFIFO = 0o010000, - static S_IFSOCK = 0o140000 - } - ) - - impl fmt::Show for SFlag { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "SFlag {{ bits: {} }}", self.bits()) - } - } - - pub fn mknod(path: &Path, kind: SFlag, perm: FilePermission, dev: dev_t) -> SysResult<()> { - let res = unsafe { ffi::mknod(path.to_c_str().as_ptr(), kind.bits | perm.bits(), dev) }; - from_ffi(res) - } - - static MINORBITS: uint = 20; - static MINORMASK: dev_t = ((1 << MINORBITS) - 1); - - pub fn mkdev(major: u64, minor: u64) -> dev_t { - (major << MINORBITS) | minor - } - - pub fn umask(mode: FilePermission) -> FilePermission { - let prev = unsafe { ffi::umask(mode.bits()) }; - FilePermission::from_bits(prev).expect("[BUG] umask returned invalid FilePermission") - } -} diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs new file mode 100644 index 00000000..1a828af7 --- /dev/null +++ b/src/sys/epoll.rs @@ -0,0 +1,77 @@ +#![cfg(target_os = "linux")] + +use libc::c_int; +use fcntl::Fd; +use errno::{SysResult, SysError, from_ffi}; + +mod ffi { + use libc::{c_int}; + use super::EpollEvent; + + extern { + pub fn epoll_create(size: c_int) -> c_int; + pub fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *const EpollEvent) -> c_int; + pub fn epoll_wait(epfd: c_int, events: *mut EpollEvent, max_events: c_int, timeout: c_int) -> c_int; + } +} + +bitflags!( + flags EpollEventKind: u32 { + static EPOLLIN = 0x001, + static EPOLLPRI = 0x002, + static EPOLLOUT = 0x004, + static EPOLLRDNORM = 0x040, + static EPOLLRDBAND = 0x080, + static EPOLLWRNORM = 0x100, + static EPOLLWRBAND = 0x200, + static EPOLLMSG = 0x400, + static EPOLLERR = 0x008, + static EPOLLHUP = 0x010, + static EPOLLRDHUP = 0x2000, + static EPOLLWAKEUP = 1 << 29, + static EPOLLONESHOT = 1 << 30, + static EPOLLET = 1 << 31 + } +) + +#[repr(C)] +pub enum EpollOp { + EpollCtlAdd = 1, + EpollCtlDel = 2, + EpollCtlMod = 3 +} + +pub struct EpollEvent { + pub events: EpollEventKind, + pub data: u64 +} + +#[inline] +pub fn epoll_create() -> SysResult<Fd> { + let res = unsafe { ffi::epoll_create(1024) }; + + if res < 0 { + return Err(SysError::last()); + } + + Ok(res) +} + +#[inline] +pub fn epoll_ctl(epfd: Fd, op: EpollOp, fd: Fd, event: &EpollEvent) -> SysResult<()> { + 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: uint) -> SysResult<uint> { + 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()); + } + + Ok(res as uint) +} diff --git a/src/sys/mod.rs b/src/sys/mod.rs new file mode 100644 index 00000000..0a741ecf --- /dev/null +++ b/src/sys/mod.rs @@ -0,0 +1,2 @@ +pub mod epoll; +pub mod stat; diff --git a/src/sys/stat.rs b/src/sys/stat.rs new file mode 100644 index 00000000..fc90ca67 --- /dev/null +++ b/src/sys/stat.rs @@ -0,0 +1,51 @@ +#![cfg(target_os = "linux")] + +pub use libc::dev_t; + +use std::fmt; +use std::io::FilePermission; +use std::path::Path; +use libc::mode_t; +use errno::{SysResult, from_ffi}; + +mod ffi { + use libc::{c_char, c_int, mode_t, dev_t}; + + extern { + pub fn mknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> c_int; + pub fn umask(mask: mode_t) -> mode_t; + } +} + +bitflags!( + flags SFlag: mode_t { + static S_IFREG = 0o100000, + static S_IFCHR = 0o020000, + static S_IFBLK = 0o060000, + static S_IFIFO = 0o010000, + static S_IFSOCK = 0o140000 + } +) + +impl fmt::Show for SFlag { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "SFlag {{ bits: {} }}", self.bits()) + } +} + +pub fn mknod(path: &Path, kind: SFlag, perm: FilePermission, dev: dev_t) -> SysResult<()> { + let res = unsafe { ffi::mknod(path.to_c_str().as_ptr(), kind.bits | perm.bits(), dev) }; + from_ffi(res) +} + +static MINORBITS: uint = 20; +// static MINORMASK: dev_t = ((1 << MINORBITS) - 1); + +pub fn mkdev(major: u64, minor: u64) -> dev_t { + (major << MINORBITS) | minor +} + +pub fn umask(mode: FilePermission) -> FilePermission { + let prev = unsafe { ffi::umask(mode.bits()) }; + FilePermission::from_bits(prev).expect("[BUG] umask returned invalid FilePermission") +} diff --git a/src/syscall.rs b/src/syscall.rs index 85f6e730..eb192dc2 100644 --- a/src/syscall.rs +++ b/src/syscall.rs @@ -1,3 +1,5 @@ +#![cfg(target_os = "linux")] + use libc::c_int; pub use self::arch::*; diff --git a/src/unistd.rs b/src/unistd.rs index 85770876..f4c4daa1 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1,3 +1,5 @@ +#![cfg(target_os = "linux")] + use std::ptr; use std::c_str::{CString, ToCStr}; use std::path::Path; |