]>
git.proxmox.com Git - rustc.git/blob - vendor/nix/src/poll.rs
1 //! Wait for events to trigger on specific file descriptors
2 use std
::os
::unix
::io
::{AsRawFd, RawFd}
;
4 use crate::errno
::Errno
;
7 /// This is a wrapper around `libc::pollfd`.
9 /// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
10 /// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
11 /// for a specific file descriptor.
13 /// After a call to `poll` or `ppoll`, the events that occurred can be
14 /// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
16 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
22 /// Creates a new `PollFd` specifying the events of interest
23 /// for a given file descriptor.
24 pub const fn new(fd
: RawFd
, events
: PollFlags
) -> PollFd
{
26 pollfd
: libc
::pollfd
{
28 events
: events
.bits(),
29 revents
: PollFlags
::empty().bits(),
34 /// Returns the events that occurred in the last call to `poll` or `ppoll`. Will only return
35 /// `None` if the kernel provides status flags that Nix does not know about.
36 pub fn revents(self) -> Option
<PollFlags
> {
37 PollFlags
::from_bits(self.pollfd
.revents
)
40 /// Returns if any of the events of interest occured in the last call to `poll` or `ppoll`. Will
41 /// only return `None` if the kernel provides status flags that Nix does not know about.
43 /// Equivalent to `x.revents()? != PollFlags::empty()`.
45 /// This is marginally more efficient than [`PollFd::all`].
46 pub fn any(self) -> Option
<bool
> {
47 Some(self.revents()?
!= PollFlags
::empty())
50 /// Returns if all the events of interest occured in the last call to `poll` or `ppoll`. Will
51 /// only return `None` if the kernel provides status flags that Nix does not know about.
53 /// Equivalent to `x.revents()? & x.events() == x.events()`.
55 /// This is marginally less efficient than [`PollFd::any`].
56 pub fn all(self) -> Option
<bool
> {
57 Some(self.revents()?
& self.events() == self.events())
60 /// The events of interest for this `PollFd`.
61 pub fn events(self) -> PollFlags
{
62 PollFlags
::from_bits(self.pollfd
.events
).unwrap()
65 /// Modify the events of interest for this `PollFd`.
66 pub fn set_events(&mut self, events
: PollFlags
) {
67 self.pollfd
.events
= events
.bits();
71 impl AsRawFd
for PollFd
{
72 fn as_raw_fd(&self) -> RawFd
{
78 /// These flags define the different events that can be monitored by `poll` and `ppoll`
79 pub struct PollFlags
: libc
::c_short
{
80 /// There is data to read.
82 /// There is some exceptional condition on the file descriptor.
84 /// Possibilities include:
86 /// * There is out-of-band data on a TCP socket (see
87 /// [tcp(7)](https://man7.org/linux/man-pages/man7/tcp.7.html)).
88 /// * A pseudoterminal master in packet mode has seen a state
89 /// change on the slave (see
90 /// [ioctl_tty(2)](https://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
91 /// * A cgroup.events file has been modified (see
92 /// [cgroups(7)](https://man7.org/linux/man-pages/man7/cgroups.7.html)).
94 /// Writing is now possible, though a write larger that the
95 /// available space in a socket or pipe will still block (unless
96 /// `O_NONBLOCK` is set).
98 /// Equivalent to [`POLLIN`](constant.POLLIN.html)
99 #[cfg(not(target_os = "redox"))]
100 #[cfg_attr(docsrs, doc(cfg(all())))]
102 #[cfg(not(target_os = "redox"))]
103 #[cfg_attr(docsrs, doc(cfg(all())))]
104 /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
106 /// Priority band data can be read (generally unused on Linux).
107 #[cfg(not(target_os = "redox"))]
108 #[cfg_attr(docsrs, doc(cfg(all())))]
110 /// Priority data may be written.
111 #[cfg(not(target_os = "redox"))]
112 #[cfg_attr(docsrs, doc(cfg(all())))]
114 /// Error condition (only returned in
115 /// [`PollFd::revents`](struct.PollFd.html#method.revents);
116 /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
117 /// This bit is also set for a file descriptor referring to the
118 /// write end of a pipe when the read end has been closed.
120 /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
121 /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
122 /// Note that when reading from a channel such as a pipe or a stream
123 /// socket, this event merely indicates that the peer closed its
124 /// end of the channel. Subsequent reads from the channel will
125 /// return 0 (end of file) only after all outstanding data in the
126 /// channel has been consumed.
128 /// Invalid request: `fd` not open (only returned in
129 /// [`PollFd::revents`](struct.PollFd.html#method.revents);
130 /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
135 /// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
136 /// ([`poll(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html))
138 /// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
139 /// The function will return as soon as any event occur for any of these `PollFd`s.
141 /// The `timeout` argument specifies the number of milliseconds that `poll()`
142 /// should block waiting for a file descriptor to become ready. The call
143 /// will block until either:
145 /// * a file descriptor becomes ready;
146 /// * the call is interrupted by a signal handler; or
147 /// * the timeout expires.
149 /// Note that the timeout interval will be rounded up to the system clock
150 /// granularity, and kernel scheduling delays mean that the blocking
151 /// interval may overrun by a small amount. Specifying a negative value
152 /// in timeout means an infinite timeout. Specifying a timeout of zero
153 /// causes `poll()` to return immediately, even if no file descriptors are
155 pub fn poll(fds
: &mut [PollFd
], timeout
: libc
::c_int
) -> Result
<libc
::c_int
> {
158 fds
.as_mut_ptr() as *mut libc
::pollfd
,
159 fds
.len() as libc
::nfds_t
,
168 #![feature = "signal"]
169 /// `ppoll()` allows an application to safely wait until either a file
170 /// descriptor becomes ready or until a signal is caught.
171 /// ([`poll(2)`](https://man7.org/linux/man-pages/man2/poll.2.html))
173 /// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
174 /// with the `sigmask` argument. If you want `ppoll` to block indefinitely,
175 /// specify `None` as `timeout` (it is like `timeout = -1` for `poll`).
176 /// If `sigmask` is `None`, then no signal mask manipulation is performed,
177 /// so in that case `ppoll` differs from `poll` only in the precision of the
178 /// timeout argument.
180 #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
183 timeout
: Option
<crate::sys
::time
::TimeSpec
>,
184 sigmask
: Option
<crate::sys
::signal
::SigSet
>
185 ) -> Result
<libc
::c_int
>
187 let timeout
= timeout
.as_ref().map_or(core
::ptr
::null(), |r
| r
.as_ref());
188 let sigmask
= sigmask
.as_ref().map_or(core
::ptr
::null(), |r
| r
.as_ref());
190 libc
::ppoll(fds
.as_mut_ptr() as *mut libc
::pollfd
,
191 fds
.len() as libc
::nfds_t
,