summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/epoll.rs25
-rw-r--r--test/sys/mod.rs3
-rw-r--r--test/sys/test_epoll.rs20
3 files changed, 44 insertions, 4 deletions
diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs
index 9774318f..1f2054a1 100644
--- a/src/sys/epoll.rs
+++ b/src/sys/epoll.rs
@@ -1,6 +1,8 @@
use {Errno, Result};
use libc::{self, c_int};
use std::os::unix::io::RawFd;
+use std::ptr;
+use std::mem;
bitflags!(
#[repr(C)]
@@ -44,10 +46,14 @@ pub struct EpollEvent {
}
impl EpollEvent {
- pub fn new(events: EpollFlags, data: u64) -> EpollEvent {
+ pub fn new(events: EpollFlags, data: u64) -> Self {
EpollEvent { event: libc::epoll_event { events: events.bits(), u64: data } }
}
+ pub fn empty() -> Self {
+ unsafe { mem::zeroed::<EpollEvent>() }
+ }
+
pub fn events(&self) -> EpollFlags {
EpollFlags::from_bits(self.event.events).unwrap()
}
@@ -57,6 +63,16 @@ impl EpollEvent {
}
}
+impl<'a> Into<&'a mut EpollEvent> for Option<&'a mut EpollEvent> {
+ #[inline]
+ fn into(self) -> &'a mut EpollEvent {
+ match self {
+ Some(epoll_event) => epoll_event,
+ None => unsafe { &mut *ptr::null_mut::<EpollEvent>() }
+ }
+ }
+}
+
#[inline]
pub fn epoll_create() -> Result<RawFd> {
let res = unsafe { libc::epoll_create(1024) };
@@ -72,9 +88,10 @@ pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
}
#[inline]
-pub fn epoll_ctl(epfd: RawFd, op: EpollOp, fd: RawFd, event: &mut EpollEvent) -> Result<()> {
- let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) };
-
+pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()>
+ where T: Into<&'a mut EpollEvent>
+{
+ let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.into().event) };
Errno::result(res).map(drop)
}
diff --git a/test/sys/mod.rs b/test/sys/mod.rs
index 6176eb32..d2c38c3e 100644
--- a/test/sys/mod.rs
+++ b/test/sys/mod.rs
@@ -6,3 +6,6 @@ mod test_ioctl;
mod test_wait;
mod test_select;
mod test_uio;
+
+#[cfg(target_os = "linux")]
+mod test_epoll;
diff --git a/test/sys/test_epoll.rs b/test/sys/test_epoll.rs
new file mode 100644
index 00000000..f31d874f
--- /dev/null
+++ b/test/sys/test_epoll.rs
@@ -0,0 +1,20 @@
+use nix::sys::epoll::{EpollCreateFlags, EpollOp, EpollEvent};
+use nix::sys::epoll::{EPOLLIN, EPOLLERR};
+use nix::sys::epoll::{epoll_create1, epoll_ctl};
+use nix::{Error, Errno};
+
+#[test]
+pub fn test_epoll_errno() {
+ let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
+ let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None);
+ assert!(result.is_err());
+ assert_eq!(result.unwrap_err(), Error::Sys(Errno::ENOENT));
+}
+
+#[test]
+pub fn test_epoll_ctl() {
+ let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
+ let mut event = EpollEvent::new(EPOLLIN | EPOLLERR, 1);
+ epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap();
+ epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap();
+}