| use nix::{ |
| errno::Errno, |
| poll::{poll, PollFd, PollFlags, PollTimeout}, |
| unistd::{pipe, write}, |
| }; |
| use std::os::unix::io::{AsFd, BorrowedFd}; |
| |
| macro_rules! loop_while_eintr { |
| ($poll_expr: expr) => { |
| loop { |
| match $poll_expr { |
| Ok(nfds) => break nfds, |
| Err(Errno::EINTR) => (), |
| Err(e) => panic!("{}", e), |
| } |
| } |
| }; |
| } |
| |
| #[test] |
| fn test_poll() { |
| let (r, w) = pipe().unwrap(); |
| let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)]; |
| |
| // Poll an idle pipe. Should timeout |
| let nfds = loop_while_eintr!(poll(&mut fds, PollTimeout::from(100u8))); |
| assert_eq!(nfds, 0); |
| assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN)); |
| |
| write(&w, b".").unwrap(); |
| |
| // Poll a readable pipe. Should return an event. |
| let nfds = poll(&mut fds, PollTimeout::from(100u8)).unwrap(); |
| assert_eq!(nfds, 1); |
| assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN)); |
| } |
| |
| // 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. |
| #[cfg(any(linux_android, freebsdlike))] |
| #[test] |
| fn test_ppoll() { |
| use nix::poll::ppoll; |
| use nix::sys::signal::SigSet; |
| use nix::sys::time::{TimeSpec, TimeValLike}; |
| |
| let timeout = TimeSpec::milliseconds(1); |
| let (r, w) = pipe().unwrap(); |
| let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)]; |
| |
| // Poll an idle pipe. Should timeout |
| let sigset = SigSet::empty(); |
| let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), Some(sigset))); |
| assert_eq!(nfds, 0); |
| assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN)); |
| |
| write(&w, b".").unwrap(); |
| |
| // Poll a readable pipe. Should return an event. |
| let nfds = ppoll(&mut fds, Some(timeout), None).unwrap(); |
| assert_eq!(nfds, 1); |
| assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN)); |
| } |
| |
| #[test] |
| fn test_pollfd_events() { |
| let fd_zero = unsafe { BorrowedFd::borrow_raw(0) }; |
| let mut pfd = PollFd::new(fd_zero.as_fd(), PollFlags::POLLIN); |
| assert_eq!(pfd.events(), PollFlags::POLLIN); |
| pfd.set_events(PollFlags::POLLOUT); |
| assert_eq!(pfd.events(), PollFlags::POLLOUT); |
| } |