Skip to content

Commit

Permalink
Merge nix-rust#887
Browse files Browse the repository at this point in the history
887: Implement Debug trait for PollFd (Fixes nix-rust#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 nix-rust#885.

Co-authored-by: Zhouyu Qian <[email protected]>
  • Loading branch information
bors[bot] and kccqzy committed Apr 20, 2018
2 parents 305141c + 5e2b582 commit c2fb79e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use sys::time::TimeSpec;
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
use sys::signal::SigSet;
use std::os::unix::io::RawFd;
use std::fmt;

use libc;
use Result;
Expand All @@ -19,7 +20,6 @@ use errno::Errno;
/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
#[repr(C)]
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
pub struct PollFd {
pollfd: libc::pollfd,
}
Expand All @@ -43,6 +43,23 @@ impl PollFd {
}
}

impl fmt::Debug for PollFd {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let pfd = self.pollfd;
let mut ds = f.debug_struct("PollFd");
ds.field("fd", &pfd.fd);
match EventFlags::from_bits(pfd.events) {
None => ds.field("events", &pfd.events),
Some(ef) => ds.field("events", &ef),
};
match EventFlags::from_bits(pfd.revents) {
None => ds.field("revents", &pfd.revents),
Some(ef) => ds.field("revents", &ef),
};
ds.finish()
}
}

libc_bitflags! {
/// These flags define the different events that can be monitored by `poll` and `ppoll`
pub struct EventFlags: libc::c_short {
Expand Down
20 changes: 19 additions & 1 deletion test/test_poll.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nix::poll::{EventFlags, poll, PollFd};
use nix::sys::signal::SigSet;
use nix::sys::time::{TimeSpec, TimeValLike};
use nix::unistd::{write, pipe};
use nix::unistd::{write, pipe, close};

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

#[test]
fn test_poll_debug() {
assert_eq!(format!("{:?}", PollFd::new(0, EventFlags::empty())),
"PollFd { fd: 0, events: (empty), revents: (empty) }");
assert_eq!(format!("{:?}", PollFd::new(1, EventFlags::POLLIN)),
"PollFd { fd: 1, events: POLLIN, revents: (empty) }");

// Testing revents requires doing some I/O
let (r, w) = pipe().unwrap();
let mut fds = [PollFd::new(r, EventFlags::POLLIN)];
write(w, b" ").unwrap();
close(w).unwrap();
poll(&mut fds, -1).unwrap();
assert_eq!(format!("{:?}", fds[0]),
format!("PollFd {{ fd: {}, events: POLLIN, revents: POLLIN | POLLHUP }}", r));
close(r).unwrap();
}

// ppoll(2) is the same as poll except for how it handles timeouts and signals.
// Repeating the test for poll(2) should be sufficient to check that our
// bindings are correct.
Expand Down

0 comments on commit c2fb79e

Please sign in to comment.