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