/// This is a wrapper around `libc::pollfd`. /// /// It's meant to be used as an argument to the [`poll`](fn.poll.html) and /// [`ppoll`](fn.ppoll.html) functions to specify the events of interest /// for a specific file descriptor. /// /// After a call to `poll` or `ppoll`, the events that occurred can be /// retrieved by calling [`revents()`](#method.revents) on the `PollFd`. #[repr(transparent)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pubstruct PollFd<'fd> {
pollfd: libc::pollfd,
_fd: std::marker::PhantomData<BorrowedFd<'fd>>,
}
impl<'fd> PollFd<'fd> { /// Creates a new `PollFd` specifying the events of interest /// for a given file descriptor. /// /// # Examples /// ```no_run /// # use std::os::unix::io::{AsFd, AsRawFd, FromRawFd}; /// # use nix::{ /// # poll::{PollTimeout, PollFd, PollFlags, poll}, /// # unistd::{pipe, read} /// # }; /// let (r, w) = pipe().unwrap(); /// let pfd = PollFd::new(r.as_fd(), PollFlags::POLLIN); /// let mut fds = [pfd]; /// poll(&mut fds, PollTimeout::NONE).unwrap(); /// let mut buf = [0u8; 80]; /// read(r.as_raw_fd(), &mut buf[..]); /// ``` // Unlike I/O functions, constructors like this must take `BorrowedFd` // instead of AsFd or &AsFd. Otherwise, an `OwnedFd` argument would be // dropped at the end of the method, leaving the structure referencing a // closed file descriptor. For example: // // ```rust // let (r, _) = pipe().unwrap(); // let pollfd = PollFd::new(r, flag); // Drops the OwnedFd // // Do something with `pollfd`, which uses the CLOSED fd. // ``` pubfn new(fd: BorrowedFd<'fd>, events: PollFlags) -> PollFd<'fd> {
PollFd {
pollfd: libc::pollfd {
fd: fd.as_raw_fd(),
events: events.bits(),
revents: PollFlags::empty().bits(),
},
_fd: std::marker::PhantomData,
}
}
/// Returns the events that occurred in the last call to `poll` or `ppoll`. Will only return /// `None` if the kernel provides status flags that Nix does not know about. pubfn revents(self) -> Option<PollFlags> {
PollFlags::from_bits(self.pollfd.revents)
}
/// Returns if any of the events of interest occured in the last call to `poll` or `ppoll`. Will /// only return `None` if the kernel provides status flags that Nix does not know about. /// /// Equivalent to `x.revents()? != PollFlags::empty()`. /// /// This is marginally more efficient than [`PollFd::all`]. pubfn any(self) -> Option<bool> {
Some(self.revents()? != PollFlags::empty())
}
/// Returns if all the events of interest occured in the last call to `poll` or `ppoll`. Will /// only return `None` if the kernel provides status flags that Nix does not know about. /// /// Equivalent to `x.revents()? & x.events() == x.events()`. /// /// This is marginally less efficient than [`PollFd::any`]. pubfn all(self) -> Option<bool> {
Some(self.revents()? & self.events() == self.events())
}
/// The events of interest for this `PollFd`. pubfn events(self) -> PollFlags {
PollFlags::from_bits(self.pollfd.events).unwrap()
}
/// Modify the events of interest for this `PollFd`. pubfn set_events(&mutself, events: PollFlags) { self.pollfd.events = events.bits();
}
}
impl<'fd> AsFd for PollFd<'fd> { fn as_fd(&self) -> BorrowedFd<'_> { // Safety: // // BorrowedFd::borrow_raw(RawFd) requires that the raw fd being passed // must remain open for the duration of the returned BorrowedFd, this is // guaranteed as the returned BorrowedFd has the lifetime parameter same // as `self`: // "fn as_fd<'self>(&'self self) -> BorrowedFd<'self>" // which means that `self` (PollFd) is guaranteed to outlive the returned // BorrowedFd. (Lifetime: PollFd > BorrowedFd) // // And the lifetime parameter of PollFd::new(fd, ...) ensures that `fd` // (an owned file descriptor) must outlive the returned PollFd: // "pub fn new<Fd: AsFd>(fd: &'fd Fd, events: PollFlags) -> PollFd<'fd>" // (Lifetime: Owned fd > PollFd) // // With two above relationships, we can conclude that the `Owned file // descriptor` will outlive the returned BorrowedFd, // (Lifetime: Owned fd > BorrowedFd) // i.e., the raw fd being passed will remain valid for the lifetime of // the returned BorrowedFd. unsafe { BorrowedFd::borrow_raw(self.pollfd.fd) }
}
}
libc_bitflags! { /// These flags define the different events that can be monitored by `poll` and `ppoll` pubstruct PollFlags: libc::c_short { /// There is data to read.
POLLIN; /// There is some exceptional condition on the file descriptor. /// /// Possibilities include: /// /// * There is out-of-band data on a TCP socket (see /// [tcp(7)](https://man7.org/linux/man-pages/man7/tcp.7.html)). /// * A pseudoterminal master in packet mode has seen a state /// change on the slave (see /// [ioctl_tty(2)](https://man7.org/linux/man-pages/man2/ioctl_tty.2.html)). /// * A cgroup.events file has been modified (see /// [cgroups(7)](https://man7.org/linux/man-pages/man7/cgroups.7.html)).
POLLPRI; /// Writing is now possible, though a write larger that the /// available space in a socket or pipe will still block (unless /// `O_NONBLOCK` is set).
POLLOUT; /// Equivalent to [`POLLIN`](constant.POLLIN.html) #[cfg(not(target_os = "redox"))]
POLLRDNORM; #[cfg(not(target_os = "redox"))] /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
POLLWRNORM; /// Priority band data can be read (generally unused on Linux). #[cfg(not(target_os = "redox"))]
POLLRDBAND; /// Priority data may be written. #[cfg(not(target_os = "redox"))]
POLLWRBAND; /// Error condition (only returned in /// [`PollFd::revents`](struct.PollFd.html#method.revents); /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)). /// This bit is also set for a file descriptor referring to the /// write end of a pipe when the read end has been closed.
POLLERR; /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents); /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)). /// Note that when reading from a channel such as a pipe or a stream /// socket, this event merely indicates that the peer closed its /// end of the channel. Subsequent reads from the channel will /// return 0 (end of file) only after all outstanding data in the /// channel has been consumed.
POLLHUP; /// Invalid request: `fd` not open (only returned in /// [`PollFd::revents`](struct.PollFd.html#method.revents); /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
POLLNVAL;
}
}
/// `poll` waits for one of a set of file descriptors to become ready to perform I/O. /// ([`poll(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)) /// /// `fds` contains all [`PollFd`](struct.PollFd.html) to poll. /// The function will return as soon as any event occur for any of these `PollFd`s. /// /// The `timeout` argument specifies the number of milliseconds that `poll()` /// should block waiting for a file descriptor to become ready. The call /// will block until either: /// /// * a file descriptor becomes ready; /// * the call is interrupted by a signal handler; or /// * the timeout expires. /// /// Note that the timeout interval will be rounded up to the system clock /// granularity, and kernel scheduling delays mean that the blocking /// interval may overrun by a small amount. Specifying a [`PollTimeout::NONE`] /// in timeout means an infinite timeout. Specifying a timeout of /// [`PollTimeout::ZERO`] causes `poll()` to return immediately, even if no file /// descriptors are ready. pubfn poll<T: Into<PollTimeout>>(
fds: &mut [PollFd],
timeout: T,
) -> Result<libc::c_int> { let res = unsafe {
libc::poll(
fds.as_mut_ptr().cast(),
fds.len() as libc::nfds_t,
i32::from(timeout.into()),
)
};
Errno::result(res)
}
feature! { #![feature = "signal"] /// `ppoll()` allows an application to safely wait until either a file /// descriptor becomes ready or until a signal is caught. /// ([`poll(2)`](https://man7.org/linux/man-pages/man2/poll.2.html)) /// /// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it /// with the `sigmask` argument. If you want `ppoll` to block indefinitely, /// specify `None` as `timeout` (it is like `timeout = -1` for `poll`). /// If `sigmask` is `None`, then no signal mask manipulation is performed, /// so in that case `ppoll` differs from `poll` only in the precision of the /// timeout argument. /// #[cfg(any(linux_android, freebsdlike))] pubfn ppoll(
fds: &mut [PollFd],
timeout: Option<crate::sys::time::TimeSpec>,
sigmask: Option<crate::sys::signal::SigSet>
) -> Result<libc::c_int>
{ let timeout = timeout.as_ref().map_or(core::ptr::null(), |r| r.as_ref()); let sigmask = sigmask.as_ref().map_or(core::ptr::null(), |r| r.as_ref()); let res = unsafe {
libc::ppoll(fds.as_mut_ptr().cast(),
fds.len() as libc::nfds_t,
timeout,
sigmask)
};
Errno::result(res)
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-06-23)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.