1
- use std:: ptr :: null_mut ;
1
+ use std:: mem ;
2
2
use std:: os:: unix:: io:: RawFd ;
3
- use libc:: { c_int, timeval} ;
3
+ use std:: ptr:: null_mut;
4
+ use libc:: { self , c_int} ;
4
5
use { Errno , Result } ;
5
6
use sys:: time:: TimeVal ;
6
7
7
- pub const FD_SETSIZE : RawFd = 1024 ;
8
-
9
- #[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
10
- #[ repr( C ) ]
11
- #[ derive( Clone ) ]
12
- pub struct FdSet {
13
- bits : [ i32 ; FD_SETSIZE as usize / 32 ]
14
- }
15
-
16
- #[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
17
- const BITS : usize = 32 ;
8
+ pub use libc:: FD_SETSIZE ;
18
9
19
- # [ cfg ( not ( any ( target_os = "macos" , target_os = "ios" ) ) ) ]
10
+ // FIXME: Change to repr(transparent) once it's stable
20
11
#[ repr( C ) ]
21
- #[ derive( Clone ) ]
22
- pub struct FdSet {
23
- bits : [ u64 ; FD_SETSIZE as usize / 64 ]
24
- }
25
-
26
- #[ cfg( not( any( target_os = "macos" , target_os = "ios" ) ) ) ]
27
- const BITS : usize = 64 ;
12
+ pub struct FdSet ( libc:: fd_set ) ;
28
13
29
14
impl FdSet {
30
15
pub fn new ( ) -> FdSet {
31
- FdSet {
32
- bits : [ 0 ; FD_SETSIZE as usize / BITS ]
33
- }
16
+ let mut fdset = unsafe { mem :: uninitialized ( ) } ;
17
+ unsafe { libc :: FD_ZERO ( & mut fdset ) } ;
18
+ FdSet ( fdset )
34
19
}
35
20
36
21
pub fn insert ( & mut self , fd : RawFd ) {
37
- let fd = fd as usize ;
38
- self . bits [ fd / BITS ] |= 1 << ( fd % BITS ) ;
22
+ unsafe { libc:: FD_SET ( fd, & mut self . 0 ) } ;
39
23
}
40
24
41
25
pub fn remove ( & mut self , fd : RawFd ) {
42
- let fd = fd as usize ;
43
- self . bits [ fd / BITS ] &= !( 1 << ( fd % BITS ) ) ;
26
+ unsafe { libc:: FD_CLR ( fd, & mut self . 0 ) } ;
44
27
}
45
28
46
- pub fn contains ( & self , fd : RawFd ) -> bool {
47
- let fd = fd as usize ;
48
- self . bits [ fd / BITS ] & ( 1 << ( fd % BITS ) ) > 0
29
+ // FIXME: Change to take ` &self` once https://github.com/rust-lang/libc/pull/718 lands
30
+ pub fn contains ( & mut self , fd : RawFd ) -> bool {
31
+ unsafe { libc :: FD_ISSET ( fd , & mut self . 0 ) }
49
32
}
50
33
51
34
pub fn clear ( & mut self ) {
52
- for bits in & mut self . bits {
53
- * bits = 0
54
- }
55
- }
56
- }
57
-
58
- mod ffi {
59
- use libc:: { c_int, 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 ;
35
+ unsafe { libc:: FD_ZERO ( & mut self . 0 ) } ;
68
36
}
69
37
}
70
38
@@ -73,14 +41,14 @@ pub fn select(nfds: c_int,
73
41
writefds : Option < & mut FdSet > ,
74
42
errorfds : Option < & mut FdSet > ,
75
43
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 as * mut timeval )
44
+ let readfds = readfds. map ( |set| set as * mut _ as * mut libc :: fd_set ) . unwrap_or ( null_mut ( ) ) ;
45
+ let writefds = writefds. map ( |set| set as * mut _ as * mut libc :: fd_set ) . unwrap_or ( null_mut ( ) ) ;
46
+ let errorfds = errorfds. map ( |set| set as * mut _ as * mut libc :: fd_set ) . unwrap_or ( null_mut ( ) ) ;
47
+ let timeout = timeout. map ( |tv| tv as * mut _ as * mut libc :: timeval )
80
48
. unwrap_or ( null_mut ( ) ) ;
81
49
82
50
let res = unsafe {
83
- ffi :: select ( nfds, readfds, writefds, errorfds, timeout)
51
+ libc :: select ( nfds, readfds, writefds, errorfds, timeout)
84
52
} ;
85
53
86
54
Errno :: result ( res)
0 commit comments