Skip to content

Commit 1fbf1fe

Browse files
committed
Auto merge of #486 - hicqu:master, r=fiveop
fix #480 and add simple test cases for that. r? @fiveop
2 parents 5d81571 + acc1513 commit 1fbf1fe

File tree

4 files changed

+59
-6
lines changed

4 files changed

+59
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
3030
([#491](https://github.com/nix-rust/nix/pull/491))
3131

3232
### Changed
33+
- `epoll_ctl` now could accept None as argument `event`
34+
when op is `EpollOp::EpollCtlDel`.
35+
([#480](https://github.com/nix-rust/nix/pull/480))
3336
- Removed the `bad` keyword from the `ioctl!` macro
3437
([#478](https://github.com/nix-rust/nix/pull/478))
3538
- Changed `TimeVal` into an opaque Newtype

src/sys/epoll.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use {Errno, Result};
22
use libc::{self, c_int};
33
use std::os::unix::io::RawFd;
4+
use std::ptr;
5+
use std::mem;
6+
use ::Error;
47

58
bitflags!(
69
#[repr(C)]
@@ -23,7 +26,7 @@ bitflags!(
2326
}
2427
);
2528

26-
#[derive(Clone, Copy)]
29+
#[derive(Clone, Copy, Eq, PartialEq)]
2730
#[repr(C)]
2831
pub enum EpollOp {
2932
EpollCtlAdd = 1,
@@ -44,10 +47,14 @@ pub struct EpollEvent {
4447
}
4548

4649
impl EpollEvent {
47-
pub fn new(events: EpollFlags, data: u64) -> EpollEvent {
50+
pub fn new(events: EpollFlags, data: u64) -> Self {
4851
EpollEvent { event: libc::epoll_event { events: events.bits(), u64: data } }
4952
}
5053

54+
pub fn empty() -> Self {
55+
unsafe { mem::zeroed::<EpollEvent>() }
56+
}
57+
5158
pub fn events(&self) -> EpollFlags {
5259
EpollFlags::from_bits(self.event.events).unwrap()
5360
}
@@ -57,6 +64,16 @@ impl EpollEvent {
5764
}
5865
}
5966

67+
impl<'a> Into<&'a mut EpollEvent> for Option<&'a mut EpollEvent> {
68+
#[inline]
69+
fn into(self) -> &'a mut EpollEvent {
70+
match self {
71+
Some(epoll_event) => epoll_event,
72+
None => unsafe { &mut *ptr::null_mut::<EpollEvent>() }
73+
}
74+
}
75+
}
76+
6077
#[inline]
6178
pub fn epoll_create() -> Result<RawFd> {
6279
let res = unsafe { libc::epoll_create(1024) };
@@ -72,10 +89,16 @@ pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
7289
}
7390

7491
#[inline]
75-
pub fn epoll_ctl(epfd: RawFd, op: EpollOp, fd: RawFd, event: &mut EpollEvent) -> Result<()> {
76-
let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) };
77-
78-
Errno::result(res).map(drop)
92+
pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()>
93+
where T: Into<&'a mut EpollEvent>
94+
{
95+
let event: &mut EpollEvent = event.into();
96+
if event as *const EpollEvent == ptr::null() && op != EpollOp::EpollCtlDel {
97+
Err(Error::Sys(Errno::EINVAL))
98+
} else {
99+
let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) };
100+
Errno::result(res).map(drop)
101+
}
79102
}
80103

81104
#[inline]

test/sys/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ mod test_ioctl;
66
mod test_wait;
77
mod test_select;
88
mod test_uio;
9+
10+
#[cfg(target_os = "linux")]
11+
mod test_epoll;

test/sys/test_epoll.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use nix::sys::epoll::{EpollCreateFlags, EpollOp, EpollEvent};
2+
use nix::sys::epoll::{EPOLLIN, EPOLLERR};
3+
use nix::sys::epoll::{epoll_create1, epoll_ctl};
4+
use nix::{Error, Errno};
5+
6+
#[test]
7+
pub fn test_epoll_errno() {
8+
let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
9+
let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None);
10+
assert!(result.is_err());
11+
assert_eq!(result.unwrap_err(), Error::Sys(Errno::ENOENT));
12+
13+
let result = epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, None);
14+
assert!(result.is_err());
15+
assert_eq!(result.unwrap_err(), Error::Sys(Errno::EINVAL));
16+
}
17+
18+
#[test]
19+
pub fn test_epoll_ctl() {
20+
let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
21+
let mut event = EpollEvent::new(EPOLLIN | EPOLLERR, 1);
22+
epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap();
23+
epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap();
24+
}

0 commit comments

Comments
 (0)