1
- use rustix:: fd:: { FromRawFd , IntoRawFd , OwnedFd } ;
2
- use rustix:: io:: epoll:: { CreateFlags , Epoll , Owning } ;
1
+ use rustix:: fd:: { BorrowedFd , IntoRawFd } ;
2
+ use rustix:: io:: epoll:: { epoll_add , epoll_del , epoll_mod , CreateFlags , EventFlags , EventVec } ;
3
3
4
4
use errno:: { set_errno, Errno } ;
5
5
use libc:: c_int;
@@ -24,7 +24,7 @@ unsafe extern "C" fn epoll_create1(flags: c_int) -> c_int {
24
24
25
25
let flags = CreateFlags :: from_bits ( flags as _ ) . unwrap ( ) ;
26
26
27
- match convert_res ( Epoll :: new ( flags , Owning :: < OwnedFd > :: new ( ) ) ) {
27
+ match convert_res ( rustix :: io :: epoll :: epoll_create ( flags ) ) {
28
28
Some ( epoll) => epoll. into_raw_fd ( ) ,
29
29
None => -1 ,
30
30
}
@@ -38,27 +38,68 @@ unsafe extern "C" fn epoll_ctl(
38
38
fd : c_int ,
39
39
event : * mut libc:: epoll_event ,
40
40
) -> c_int {
41
- let epoll = Epoll :: from_raw_fd ( epfd) ;
41
+ libc ! ( libc :: epoll_ctl ( epfd, op , fd , event ) ) ;
42
42
43
- // let res = match op {
44
- // libc::EPOLL_CTL_ADD => epoll.add(),
45
- // };
43
+ let epfd = BorrowedFd :: borrow_raw ( epfd) ;
44
+ let fd = BorrowedFd :: borrow_raw ( fd) ;
45
+ let res = match op {
46
+ libc:: EPOLL_CTL_ADD => {
47
+ let libc:: epoll_event { events, r#u64 } = event. read ( ) ;
48
+ let events = EventFlags :: from_bits ( events) . unwrap ( ) ;
49
+ epoll_add ( epfd, fd, r#u64, events)
50
+ }
51
+ libc:: EPOLL_CTL_MOD => {
52
+ let libc:: epoll_event { events, r#u64 } = event. read ( ) ;
53
+ let events = EventFlags :: from_bits ( events) . unwrap ( ) ;
54
+ epoll_mod ( epfd, fd, r#u64, events)
55
+ }
56
+ libc:: EPOLL_CTL_DEL => epoll_del ( epfd, fd) ,
57
+ _ => {
58
+ set_errno ( Errno ( libc:: EINVAL ) ) ;
59
+ return -1 ;
60
+ }
61
+ } ;
46
62
47
- todo ! ( )
63
+ match convert_res ( res) {
64
+ Some ( ( ) ) => 0 ,
65
+ None => -1 ,
66
+ }
48
67
}
49
68
50
69
#[ no_mangle]
51
70
unsafe extern "C" fn epoll_wait (
52
- _epfd : c_int ,
53
- _events : * mut libc:: epoll_event ,
54
- _maxevents : c_int ,
55
- _timeout : c_int ,
71
+ epfd : c_int ,
72
+ events : * mut libc:: epoll_event ,
73
+ maxevents : c_int ,
74
+ timeout : c_int ,
56
75
) -> c_int {
57
- libc ! ( libc:: epoll_wait(
58
- _epfd,
59
- _events,
60
- _maxevents,
61
- _timeout
62
- ) ) ;
63
- unimplemented ! ( "epoll_wait" )
76
+ libc ! ( libc:: epoll_wait( epfd, events, maxevents, timeout) ) ;
77
+
78
+ if maxevents <= 0 {
79
+ set_errno ( Errno ( libc:: EINVAL ) ) ;
80
+ return -1 ;
81
+ }
82
+
83
+ // TODO: We should add an `EventVec::from_raw_parts` to allow `epoll_wait`
84
+ // to write events directly into the user's buffer, rather then allocating
85
+ // and copying here.
86
+ let mut events_vec = EventVec :: with_capacity ( maxevents as usize ) ;
87
+ match convert_res ( rustix:: io:: epoll:: epoll_wait (
88
+ BorrowedFd :: borrow_raw ( epfd) ,
89
+ & mut events_vec,
90
+ timeout,
91
+ ) ) {
92
+ Some ( ( ) ) => {
93
+ let mut events = events;
94
+ for ( flags, data) in events_vec. iter ( ) {
95
+ events. write ( libc:: epoll_event {
96
+ events : flags. bits ( ) ,
97
+ r#u64 : data,
98
+ } ) ;
99
+ events = events. add ( 1 ) ;
100
+ }
101
+ events_vec. len ( ) as c_int
102
+ }
103
+ None => -1 ,
104
+ }
64
105
}
0 commit comments