From ee9affe12fa216c84eb11cc3169673b55af1bb56 Mon Sep 17 00:00:00 2001 From: Utkarsh Kukreti Date: Mon, 14 Sep 2015 21:00:35 +0530 Subject: Add sys::select::FdSet and sys::select::select. --- src/sys/mod.rs | 2 ++ src/sys/select.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/sys/select.rs (limited to 'src/sys') diff --git a/src/sys/mod.rs b/src/sys/mod.rs index eda95972..3e4a0836 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -47,3 +47,5 @@ pub mod time; target_arch = "arm")), )] pub mod ptrace; + +pub mod select; 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 { + 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) + } +} -- cgit v1.2.3