Skip to content

Commit f99638d

Browse files
authored
Implement epoll (#164)
Use the new epoll API from bytecodealliance/rustix#487. Fixes #86.
1 parent 8ba8e19 commit f99638d

File tree

2 files changed

+62
-21
lines changed

2 files changed

+62
-21
lines changed

c-scape/src/io/epoll.rs

+60-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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};
33

44
use errno::{set_errno, Errno};
55
use libc::c_int;
@@ -24,7 +24,7 @@ unsafe extern "C" fn epoll_create1(flags: c_int) -> c_int {
2424

2525
let flags = CreateFlags::from_bits(flags as _).unwrap();
2626

27-
match convert_res(Epoll::new(flags, Owning::<OwnedFd>::new())) {
27+
match convert_res(rustix::io::epoll::epoll_create(flags)) {
2828
Some(epoll) => epoll.into_raw_fd(),
2929
None => -1,
3030
}
@@ -38,27 +38,68 @@ unsafe extern "C" fn epoll_ctl(
3838
fd: c_int,
3939
event: *mut libc::epoll_event,
4040
) -> c_int {
41-
let epoll = Epoll::from_raw_fd(epfd);
41+
libc!(libc::epoll_ctl(epfd, op, fd, event));
4242

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+
};
4662

47-
todo!()
63+
match convert_res(res) {
64+
Some(()) => 0,
65+
None => -1,
66+
}
4867
}
4968

5069
#[no_mangle]
5170
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,
5675
) -> 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+
}
64105
}

c-scape/src/io/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(not(target_os = "wasi"))]
22
mod dup;
3-
// #[cfg(any(target_os = "android", target_os = "linux"))]
4-
// mod epoll;
3+
#[cfg(any(target_os = "android", target_os = "linux"))]
4+
mod epoll;
55
mod isatty;
66
mod pipe;
77
mod poll;

0 commit comments

Comments
 (0)