summaryrefslogtreecommitdiff
path: root/src/sys/select.rs
diff options
context:
space:
mode:
authorUtkarsh Kukreti <utkarshkukreti@gmail.com>2015-09-14 21:00:35 +0530
committerCarl Lerche <me@carllerche.com>2015-09-28 10:58:05 -0700
commitee9affe12fa216c84eb11cc3169673b55af1bb56 (patch)
treecebc05fad8069bcf60c5a160603e760af2c2aba5 /src/sys/select.rs
parent6e27e16d633a8dbb632bf3cbd6c7d542cd547033 (diff)
downloadnix-ee9affe12fa216c84eb11cc3169673b55af1bb56.zip
Add sys::select::FdSet and sys::select::select.
Diffstat (limited to 'src/sys/select.rs')
-rw-r--r--src/sys/select.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/sys/select.rs b/src/sys/select.rs
new file mode 100644
index 00000000..1060d618
--- /dev/null
+++ b/src/sys/select.rs
@@ -0,0 +1,84 @@
+use std::ptr::null_mut;
+use std::os::unix::io::RawFd;
+use libc::c_int;
+use {Result, Error};
+use errno::Errno;
+use sys::time::TimeVal;
+
+pub const FD_SETSIZE: RawFd = 1024;
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[repr(C)]
+pub struct FdSet {
+ bits: [i32; FD_SETSIZE as usize / 32]
+}
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+const BITS: usize = 32;
+
+#[cfg(not(any(target_os = "macos", target_os = "ios")))]
+#[repr(C)]
+pub struct FdSet {
+ bits: [u64; FD_SETSIZE as usize / 64]
+}
+
+#[cfg(not(any(target_os = "macos", target_os = "ios")))]
+const BITS: usize = 64;
+
+impl FdSet {
+ pub fn new() -> FdSet {
+ FdSet {
+ bits: [0; FD_SETSIZE as usize / BITS]
+ }
+ }
+
+ pub fn insert(&mut self, fd: RawFd) {
+ let fd = fd as usize;
+ self.bits[fd / BITS] |= 1 << (fd % BITS);
+ }
+
+ pub fn remove(&mut self, fd: RawFd) {
+ let fd = fd as usize;
+ self.bits[fd / BITS] &= !(1 << (fd % BITS));
+ }
+
+ pub fn contains(&mut self, fd: RawFd) -> bool {
+ let fd = fd as usize;
+ self.bits[fd / BITS] & (1 << (fd % BITS)) > 0
+ }
+}
+
+mod ffi {
+ use libc::c_int;
+ use sys::time::TimeVal;
+ use super::FdSet;
+
+ extern {
+ pub fn select(nfds: c_int,
+ readfds: *mut FdSet,
+ writefds: *mut FdSet,
+ errorfds: *mut FdSet,
+ timeout: *mut TimeVal) -> c_int;
+ }
+}
+
+pub fn select(nfds: c_int,
+ readfds: Option<&mut FdSet>,
+ writefds: Option<&mut FdSet>,
+ errorfds: Option<&mut FdSet>,
+ timeout: &mut TimeVal) -> Result<c_int> {
+ let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
+ let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
+ let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
+ let timeout = timeout as *mut TimeVal;
+
+ let res = unsafe {
+ ffi::select(nfds, readfds, writefds, errorfds, timeout)
+ };
+
+ if res == -1 {
+ Err(Error::Sys(Errno::last()))
+ } else {
+ Ok(res)
+ }
+}