1 use nix::{
2 Error,
3 errno::Errno,
4 poll::{PollFlags, poll, PollFd},
5 unistd::{write, pipe}
6 };
7
8 macro_rules! loop_while_eintr {
9 ($poll_expr: expr) => {
10 loop {
11 match $poll_expr {
12 Ok(nfds) => break nfds,
13 Err(Error::Sys(Errno::EINTR)) => (),
14 Err(e) => panic!(e)
15 }
16 }
17 }
18 }
19
20 #[test]
test_poll()21 fn test_poll() {
22 let (r, w) = pipe().unwrap();
23 let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
24
25 // Poll an idle pipe. Should timeout
26 let nfds = loop_while_eintr!(poll(&mut fds, 100));
27 assert_eq!(nfds, 0);
28 assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
29
30 write(w, b".").unwrap();
31
32 // Poll a readable pipe. Should return an event.
33 let nfds = poll(&mut fds, 100).unwrap();
34 assert_eq!(nfds, 1);
35 assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
36 }
37
38 // ppoll(2) is the same as poll except for how it handles timeouts and signals.
39 // Repeating the test for poll(2) should be sufficient to check that our
40 // bindings are correct.
41 #[cfg(any(target_os = "android",
42 target_os = "dragonfly",
43 target_os = "freebsd",
44 target_os = "linux"))]
45 #[test]
test_ppoll()46 fn test_ppoll() {
47 use nix::poll::ppoll;
48 use nix::sys::signal::SigSet;
49 use nix::sys::time::{TimeSpec, TimeValLike};
50
51 let timeout = TimeSpec::milliseconds(1);
52 let (r, w) = pipe().unwrap();
53 let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
54
55 // Poll an idle pipe. Should timeout
56 let sigset = SigSet::empty();
57 let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), sigset));
58 assert_eq!(nfds, 0);
59 assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
60
61 write(w, b".").unwrap();
62
63 // Poll a readable pipe. Should return an event.
64 let nfds = ppoll(&mut fds, Some(timeout), SigSet::empty()).unwrap();
65 assert_eq!(nfds, 1);
66 assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
67 }
68