Skip to content

Commit c2fb79e

Browse files
bors[bot]kccqzy
andcommitted
Merge #887
887: Implement Debug trait for PollFd (Fixes #885) r=asomers a=kccqzy This is useful when using printf-style debugging to observe the variables and of the program. This is discussed in issue #885. Co-authored-by: Zhouyu Qian <qzy@qzy.io>
2 parents 305141c + 5e2b582 commit c2fb79e

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

src/poll.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use sys::time::TimeSpec;
44
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
55
use sys::signal::SigSet;
66
use std::os::unix::io::RawFd;
7+
use std::fmt;
78

89
use libc;
910
use Result;
@@ -19,7 +20,6 @@ use errno::Errno;
1920
/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
2021
#[repr(C)]
2122
#[derive(Clone, Copy)]
22-
#[allow(missing_debug_implementations)]
2323
pub struct PollFd {
2424
pollfd: libc::pollfd,
2525
}
@@ -43,6 +43,23 @@ impl PollFd {
4343
}
4444
}
4545

46+
impl fmt::Debug for PollFd {
47+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48+
let pfd = self.pollfd;
49+
let mut ds = f.debug_struct("PollFd");
50+
ds.field("fd", &pfd.fd);
51+
match EventFlags::from_bits(pfd.events) {
52+
None => ds.field("events", &pfd.events),
53+
Some(ef) => ds.field("events", &ef),
54+
};
55+
match EventFlags::from_bits(pfd.revents) {
56+
None => ds.field("revents", &pfd.revents),
57+
Some(ef) => ds.field("revents", &ef),
58+
};
59+
ds.finish()
60+
}
61+
}
62+
4663
libc_bitflags! {
4764
/// These flags define the different events that can be monitored by `poll` and `ppoll`
4865
pub struct EventFlags: libc::c_short {

test/test_poll.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use nix::poll::{EventFlags, poll, PollFd};
22
use nix::sys::signal::SigSet;
33
use nix::sys::time::{TimeSpec, TimeValLike};
4-
use nix::unistd::{write, pipe};
4+
use nix::unistd::{write, pipe, close};
55

66
#[test]
77
fn test_poll() {
@@ -21,6 +21,24 @@ fn test_poll() {
2121
assert!(fds[0].revents().unwrap().contains(EventFlags::POLLIN));
2222
}
2323

24+
#[test]
25+
fn test_poll_debug() {
26+
assert_eq!(format!("{:?}", PollFd::new(0, EventFlags::empty())),
27+
"PollFd { fd: 0, events: (empty), revents: (empty) }");
28+
assert_eq!(format!("{:?}", PollFd::new(1, EventFlags::POLLIN)),
29+
"PollFd { fd: 1, events: POLLIN, revents: (empty) }");
30+
31+
// Testing revents requires doing some I/O
32+
let (r, w) = pipe().unwrap();
33+
let mut fds = [PollFd::new(r, EventFlags::POLLIN)];
34+
write(w, b" ").unwrap();
35+
close(w).unwrap();
36+
poll(&mut fds, -1).unwrap();
37+
assert_eq!(format!("{:?}", fds[0]),
38+
format!("PollFd {{ fd: {}, events: POLLIN, revents: POLLIN | POLLHUP }}", r));
39+
close(r).unwrap();
40+
}
41+
2442
// ppoll(2) is the same as poll except for how it handles timeouts and signals.
2543
// Repeating the test for poll(2) should be sufficient to check that our
2644
// bindings are correct.

0 commit comments

Comments
 (0)