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