Skip to content

Commit da53464

Browse files
committed
select: use libc
1 parent c2f9605 commit da53464

File tree

1 file changed

+38
-48
lines changed

1 file changed

+38
-48
lines changed

src/sys/select.rs

+38-48
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,75 @@
1-
use std::ptr::null_mut;
1+
use std::ptr::{null, null_mut};
22
use std::os::unix::io::RawFd;
3-
use libc::c_int;
3+
use std::mem;
4+
use libc;
5+
use libc::{fd_set, c_int, timeval};
46
use {Errno, Result};
57
use sys::time::TimeVal;
8+
use sys::signal::SigSet;
69

7-
pub const FD_SETSIZE: RawFd = 1024;
8-
9-
#[cfg(any(target_os = "macos", target_os = "ios"))]
10-
#[repr(C)]
1110
pub struct FdSet {
12-
bits: [i32; FD_SETSIZE as usize / 32]
11+
set: fd_set
1312
}
1413

15-
#[cfg(any(target_os = "macos", target_os = "ios"))]
16-
const BITS: usize = 32;
17-
18-
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
19-
#[repr(C)]
20-
#[derive(Clone)]
21-
pub struct FdSet {
22-
bits: [u64; FD_SETSIZE as usize / 64]
14+
impl AsRef<fd_set> for FdSet {
15+
fn as_ref(&self) -> &fd_set {
16+
&self.set
17+
}
2318
}
2419

25-
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
26-
const BITS: usize = 64;
20+
pub const FD_SETSIZE: RawFd = libc::FD_SETSIZE as RawFd;
2721

2822
impl FdSet {
2923
pub fn new() -> FdSet {
30-
FdSet {
31-
bits: [0; FD_SETSIZE as usize / BITS]
32-
}
24+
let mut set = FdSet {
25+
set: unsafe { mem::uninitialized() }
26+
};
27+
set.clear();
28+
set
3329
}
3430

3531
pub fn insert(&mut self, fd: RawFd) {
36-
let fd = fd as usize;
37-
self.bits[fd / BITS] |= 1 << (fd % BITS);
32+
assert!(fd >= 0 && fd < FD_SETSIZE, "RawFd out of bounds");
33+
unsafe {
34+
libc::FD_SET(fd, &mut self.set as *mut _);
35+
}
3836
}
3937

4038
pub fn remove(&mut self, fd: RawFd) {
41-
let fd = fd as usize;
42-
self.bits[fd / BITS] &= !(1 << (fd % BITS));
39+
assert!(fd >= 0 && fd < FD_SETSIZE, "RawFd out of bounds");
40+
unsafe {
41+
libc::FD_CLR(fd, &mut self.set as *mut _);
42+
}
4343
}
4444

45-
pub fn contains(&mut self, fd: RawFd) -> bool {
46-
let fd = fd as usize;
47-
self.bits[fd / BITS] & (1 << (fd % BITS)) > 0
45+
pub fn contains(&self, fd: RawFd) -> bool {
46+
assert!(fd >= 0 && fd < FD_SETSIZE, "RawFd out of bounds");
47+
unsafe {
48+
// We require `transmute` here because FD_ISSET wants a mutable pointer,
49+
// when in fact it doesn't mutate.
50+
libc::FD_ISSET(fd, mem::transmute(&self.set as *const fd_set))
51+
}
4852
}
4953

5054
pub fn clear(&mut self) {
51-
for bits in &mut self.bits {
52-
*bits = 0
55+
unsafe {
56+
libc::FD_ZERO(&mut self.set as *mut _);
5357
}
5458
}
5559
}
5660

57-
mod ffi {
58-
use libc::c_int;
59-
use sys::time::TimeVal;
60-
use super::FdSet;
61-
62-
extern {
63-
pub fn select(nfds: c_int,
64-
readfds: *mut FdSet,
65-
writefds: *mut FdSet,
66-
errorfds: *mut FdSet,
67-
timeout: *mut TimeVal) -> c_int;
68-
}
69-
}
70-
7161
pub fn select(nfds: c_int,
7262
readfds: Option<&mut FdSet>,
7363
writefds: Option<&mut FdSet>,
7464
errorfds: Option<&mut FdSet>,
7565
timeout: Option<&mut TimeVal>) -> Result<c_int> {
76-
let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
77-
let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
78-
let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
79-
let timeout = timeout.map(|tv| tv as *mut TimeVal).unwrap_or(null_mut());
66+
let readfds = readfds.map(|set| &mut set.set as *mut fd_set).unwrap_or(null_mut());
67+
let writefds = writefds.map(|set| &mut set.set as *mut fd_set).unwrap_or(null_mut());
68+
let errorfds = errorfds.map(|set| &mut set.set as *mut fd_set).unwrap_or(null_mut());
69+
let timeout = timeout.map(|tv| tv.as_mut() as *mut timeval).unwrap_or(null_mut());
8070

8171
let res = unsafe {
82-
ffi::select(nfds, readfds, writefds, errorfds, timeout)
72+
libc::select(nfds, readfds, writefds, errorfds, timeout)
8373
};
8474

8575
Errno::result(res)

0 commit comments

Comments
 (0)