• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::super::c;
2 use super::super::conv::borrowed_fd;
3 #[cfg(windows)]
4 use super::super::fd::RawFd;
5 use super::super::fd::{AsFd, AsRawFd, BorrowedFd, LibcFd};
6 use bitflags::bitflags;
7 use core::marker::PhantomData;
8 #[cfg(windows)]
9 use std::fmt;
10 
11 bitflags! {
12     /// `POLL*` flags for use with [`poll`].
13     ///
14     /// [`poll`]: crate::io::poll
15     pub struct PollFlags: c::c_short {
16         /// `POLLIN`
17         const IN = c::POLLIN;
18         /// `POLLPRI`
19         #[cfg(not(target_os = "wasi"))]
20         const PRI = c::POLLPRI;
21         /// `POLLOUT`
22         const OUT = c::POLLOUT;
23         /// `POLLRDNORM`
24         #[cfg(not(target_os = "redox"))]
25         const RDNORM = c::POLLRDNORM;
26         /// `POLLWRNORM`
27         #[cfg(not(target_os = "redox"))]
28         const WRNORM = c::POLLWRNORM;
29         /// `POLLRDBAND`
30         #[cfg(not(any(target_os = "redox", target_os = "wasi")))]
31         const RDBAND = c::POLLRDBAND;
32         /// `POLLWRBAND`
33         #[cfg(not(any(target_os = "redox", target_os = "wasi")))]
34         const WRBAND = c::POLLWRBAND;
35         /// `POLLERR`
36         const ERR = c::POLLERR;
37         /// `POLLHUP`
38         const HUP = c::POLLHUP;
39         /// `POLLNVAL`
40         const NVAL = c::POLLNVAL;
41         /// `POLLRDHUP`
42         #[cfg(all(
43             any(target_os = "android", target_os = "linux"),
44             not(any(target_arch = "sparc", target_arch = "sparc64"))),
45         )]
46         const RDHUP = c::POLLRDHUP;
47     }
48 }
49 
50 /// `struct pollfd`—File descriptor and flags for use with [`poll`].
51 ///
52 /// [`poll`]: crate::io::poll
53 #[doc(alias = "pollfd")]
54 #[derive(Clone)]
55 #[cfg_attr(not(windows), derive(Debug))]
56 #[repr(transparent)]
57 pub struct PollFd<'fd> {
58     pollfd: c::pollfd,
59     _phantom: PhantomData<BorrowedFd<'fd>>,
60 }
61 
62 #[cfg(windows)]
63 impl<'fd> fmt::Debug for PollFd<'fd> {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result64     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
65         fmt.debug_struct("pollfd")
66             .field("fd", &self.pollfd.fd)
67             .field("events", &self.pollfd.events)
68             .field("revents", &self.pollfd.revents)
69             .finish()
70     }
71 }
72 
73 impl<'fd> PollFd<'fd> {
74     /// Constructs a new `PollFd` holding `fd` and `events`.
75     #[inline]
new<Fd: AsFd>(fd: &'fd Fd, events: PollFlags) -> Self76     pub fn new<Fd: AsFd>(fd: &'fd Fd, events: PollFlags) -> Self {
77         Self::from_borrowed_fd(fd.as_fd(), events)
78     }
79 
80     /// Sets the contained file descriptor to `fd`.
81     #[inline]
set_fd<Fd: AsFd>(&mut self, fd: &'fd Fd)82     pub fn set_fd<Fd: AsFd>(&mut self, fd: &'fd Fd) {
83         self.pollfd.fd = fd.as_fd().as_raw_fd() as LibcFd;
84     }
85 
86     /// Clears the ready events.
87     #[inline]
clear_revents(&mut self)88     pub fn clear_revents(&mut self) {
89         self.pollfd.revents = 0;
90     }
91 
92     /// Constructs a new `PollFd` holding `fd` and `events`.
93     ///
94     /// This is the same as `new`, but can be used to avoid borrowing the
95     /// `BorrowedFd`, which can be tricky in situations where the `BorrowedFd`
96     /// is a temporary.
97     #[inline]
from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self98     pub fn from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self {
99         Self {
100             pollfd: c::pollfd {
101                 fd: borrowed_fd(fd),
102                 events: events.bits(),
103                 revents: 0,
104             },
105             _phantom: PhantomData,
106         }
107     }
108 
109     /// Returns the ready events.
110     #[inline]
revents(&self) -> PollFlags111     pub fn revents(&self) -> PollFlags {
112         // Use `unwrap()` here because in theory we know we know all the bits
113         // the OS might set here, but OS's have added extensions in the past.
114         PollFlags::from_bits(self.pollfd.revents).unwrap()
115     }
116 }
117 
118 #[cfg(not(windows))]
119 impl<'fd> AsFd for PollFd<'fd> {
120     #[inline]
as_fd(&self) -> BorrowedFd<'_>121     fn as_fd(&self) -> BorrowedFd<'_> {
122         // Safety: Our constructors and `set_fd` require `pollfd.fd` to be
123         // valid for the `fd lifetime.
124         unsafe { BorrowedFd::borrow_raw(self.pollfd.fd) }
125     }
126 }
127 
128 #[cfg(windows)]
129 impl<'fd> io_lifetimes::AsSocket for PollFd<'fd> {
130     #[inline]
as_socket(&self) -> BorrowedFd<'_>131     fn as_socket(&self) -> BorrowedFd<'_> {
132         // Safety: Our constructors and `set_fd` require `pollfd.fd` to be
133         // valid for the `fd lifetime.
134         unsafe { BorrowedFd::borrow_raw(self.pollfd.fd as RawFd) }
135     }
136 }
137