diff --git a/src/sys/select.rs b/src/sys/select.rs index eae191b6e4..513f4e4891 100644 --- a/src/sys/select.rs +++ b/src/sys/select.rs @@ -1,70 +1,38 @@ -use std::ptr::null_mut; +use std::mem; use std::os::unix::io::RawFd; -use libc::{c_int, timeval}; +use std::ptr::null_mut; +use libc::{self, c_int}; use {Errno, Result}; use sys::time::TimeVal; -pub const FD_SETSIZE: RawFd = 1024; - -#[cfg(any(target_os = "macos", target_os = "ios"))] -#[repr(C)] -#[derive(Clone)] -pub struct FdSet { - bits: [i32; FD_SETSIZE as usize / 32] -} - -#[cfg(any(target_os = "macos", target_os = "ios"))] -const BITS: usize = 32; +pub use libc::FD_SETSIZE; -#[cfg(not(any(target_os = "macos", target_os = "ios")))] +// FIXME: Change to repr(transparent) once it's stable #[repr(C)] -#[derive(Clone)] -pub struct FdSet { - bits: [u64; FD_SETSIZE as usize / 64] -} - -#[cfg(not(any(target_os = "macos", target_os = "ios")))] -const BITS: usize = 64; +pub struct FdSet(libc::fd_set); impl FdSet { pub fn new() -> FdSet { - FdSet { - bits: [0; FD_SETSIZE as usize / BITS] - } + let mut fdset = unsafe { mem::uninitialized() }; + unsafe { libc::FD_ZERO(&mut fdset) }; + FdSet(fdset) } pub fn insert(&mut self, fd: RawFd) { - let fd = fd as usize; - self.bits[fd / BITS] |= 1 << (fd % BITS); + unsafe { libc::FD_SET(fd, &mut self.0) }; } pub fn remove(&mut self, fd: RawFd) { - let fd = fd as usize; - self.bits[fd / BITS] &= !(1 << (fd % BITS)); + unsafe { libc::FD_CLR(fd, &mut self.0) }; } - pub fn contains(&self, fd: RawFd) -> bool { - let fd = fd as usize; - self.bits[fd / BITS] & (1 << (fd % BITS)) > 0 + // FIXME: Change to take `&self` once https://github.com/rust-lang/libc/pull/718 lands + pub fn contains(&mut self, fd: RawFd) -> bool { + unsafe { libc::FD_ISSET(fd, &mut self.0) } } pub fn clear(&mut self) { - for bits in &mut self.bits { - *bits = 0 - } - } -} - -mod ffi { - use libc::{c_int, 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; + unsafe { libc::FD_ZERO(&mut self.0) }; } } @@ -73,14 +41,14 @@ pub fn select(nfds: c_int, writefds: Option<&mut FdSet>, errorfds: Option<&mut FdSet>, timeout: Option<&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.map(|tv| tv as *mut TimeVal as *mut timeval) + let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); + let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval) .unwrap_or(null_mut()); let res = unsafe { - ffi::select(nfds, readfds, writefds, errorfds, timeout) + libc::select(nfds, readfds, writefds, errorfds, timeout) }; Errno::result(res) diff --git a/test/sys/test_select.rs b/test/sys/test_select.rs index d50c7d74e5..3ce97c16d6 100644 --- a/test/sys/test_select.rs +++ b/test/sys/test_select.rs @@ -7,7 +7,7 @@ fn test_fdset() { let mut fd_set = FdSet::new(); for i in 0..FD_SETSIZE { - assert!(!fd_set.contains(i)); + assert!(!fd_set.contains(i as i32)); } fd_set.insert(7); @@ -17,17 +17,17 @@ fn test_fdset() { fd_set.remove(7); for i in 0..FD_SETSIZE { - assert!(!fd_set.contains(i)); + assert!(!fd_set.contains(i as i32)); } fd_set.insert(1); - fd_set.insert(FD_SETSIZE / 2); - fd_set.insert(FD_SETSIZE - 1); + fd_set.insert(FD_SETSIZE as i32 / 2); + fd_set.insert(FD_SETSIZE as i32 - 1); fd_set.clear(); for i in 0..FD_SETSIZE { - assert!(!fd_set.contains(i)); + assert!(!fd_set.contains(i as i32)); } }