summaryrefslogtreecommitdiff
path: root/vendor/rustix/src/event
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/event')
-rw-r--r--vendor/rustix/src/event/epoll.rs347
-rw-r--r--vendor/rustix/src/event/eventfd.rs20
-rw-r--r--vendor/rustix/src/event/kqueue.rs466
-rw-r--r--vendor/rustix/src/event/mod.rs34
-rw-r--r--vendor/rustix/src/event/pause.rs31
-rw-r--r--vendor/rustix/src/event/poll.rs47
-rw-r--r--vendor/rustix/src/event/port.rs197
-rw-r--r--vendor/rustix/src/event/select.rs391
8 files changed, 0 insertions, 1533 deletions
diff --git a/vendor/rustix/src/event/epoll.rs b/vendor/rustix/src/event/epoll.rs
deleted file mode 100644
index 839f05de..00000000
--- a/vendor/rustix/src/event/epoll.rs
+++ /dev/null
@@ -1,347 +0,0 @@
-//! Linux `epoll` support.
-//!
-//! # Examples
-//!
-//! ```no_run
-//! # #[cfg(feature = "net")]
-//! # fn main() -> std::io::Result<()> {
-//! use rustix::buffer::spare_capacity;
-//! use rustix::event::epoll;
-//! use rustix::fd::AsFd;
-//! use rustix::io::{ioctl_fionbio, read, write};
-//! use rustix::net::{
-//! accept, bind, listen, socket, AddressFamily, Ipv4Addr, SocketAddrV4, SocketType,
-//! };
-//! use std::collections::HashMap;
-//! use std::os::unix::io::AsRawFd;
-//!
-//! // Create a socket and listen on it.
-//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, None)?;
-//! bind(&listen_sock, &SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?;
-//! listen(&listen_sock, 1)?;
-//!
-//! // Create an epoll object. Using `Owning` here means the epoll object will
-//! // take ownership of the file descriptors registered with it.
-//! let epoll = epoll::create(epoll::CreateFlags::CLOEXEC)?;
-//!
-//! // Register the socket with the epoll object.
-//! epoll::add(
-//! &epoll,
-//! &listen_sock,
-//! epoll::EventData::new_u64(1),
-//! epoll::EventFlags::IN,
-//! )?;
-//!
-//! // Keep track of the sockets we've opened.
-//! let mut next_id = epoll::EventData::new_u64(2);
-//! let mut sockets = HashMap::new();
-//!
-//! // Process events.
-//! let mut event_list = Vec::with_capacity(4);
-//! loop {
-//! epoll::wait(&epoll, spare_capacity(&mut event_list), None)?;
-//! for event in event_list.drain(..) {
-//! let target = event.data;
-//! if target.u64() == 1 {
-//! // Accept a new connection, set it to non-blocking, and
-//! // register to be notified when it's ready to write to.
-//! let conn_sock = accept(&listen_sock)?;
-//! ioctl_fionbio(&conn_sock, true)?;
-//! epoll::add(
-//! &epoll,
-//! &conn_sock,
-//! next_id,
-//! epoll::EventFlags::OUT | epoll::EventFlags::ET,
-//! )?;
-//!
-//! // Keep track of the socket.
-//! sockets.insert(next_id, conn_sock);
-//! next_id = epoll::EventData::new_u64(next_id.u64() + 1);
-//! } else {
-//! // Write a message to the stream and then unregister it.
-//! let target = sockets.remove(&target).unwrap();
-//! write(&target, b"hello\n")?;
-//! let _ = epoll::delete(&epoll, &target)?;
-//! }
-//! }
-//! }
-//! # }
-//! # #[cfg(not(feature = "net"))]
-//! # fn main() {}
-//! ```
-
-#![allow(unsafe_code)]
-#![allow(unused_qualifications)]
-
-use super::epoll;
-pub use crate::backend::event::epoll::*;
-use crate::backend::event::syscalls;
-use crate::buffer::Buffer;
-use crate::fd::{AsFd, OwnedFd};
-use crate::io;
-use crate::timespec::Timespec;
-use core::ffi::c_void;
-use core::hash::{Hash, Hasher};
-
-/// `epoll_create1(flags)`—Creates a new epoll object.
-///
-/// Use the [`epoll::CreateFlags::CLOEXEC`] flag to prevent the resulting file
-/// descriptor from being implicitly passed across `exec` boundaries.
-///
-/// # References
-/// - [Linux]
-/// - [illumos]
-///
-/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_create.2.html
-/// [illumos]: https://www.illumos.org/man/3C/epoll_create
-#[inline]
-#[doc(alias = "epoll_create1")]
-pub fn create(flags: epoll::CreateFlags) -> io::Result<OwnedFd> {
- syscalls::epoll_create(flags)
-}
-
-/// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an epoll
-/// object.
-///
-/// This registers interest in any of the events set in `event_flags` occurring
-/// on the file descriptor associated with `data`.
-///
-/// `close`ing a file descriptor does not necessarily unregister interest which
-/// can lead to spurious events being returned from [`epoll::wait`]. If a file
-/// descriptor is an `Arc<dyn SystemResource>`, then `epoll` can be thought to
-/// maintain a `Weak<dyn SystemResource>` to the file descriptor. Check the
-/// [faq] for details.
-///
-/// # References
-/// - [Linux]
-/// - [illumos]
-///
-/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html
-/// [illumos]: https://www.illumos.org/man/3C/epoll_ctl
-/// [faq]: https://man7.org/linux/man-pages/man7/epoll.7.html#:~:text=Will%20closing%20a%20file%20descriptor%20cause%20it%20to%20be%20removed%20from%20all%0A%20%20%20%20%20%20%20%20%20%20epoll%20interest%20lists%3F
-#[doc(alias = "epoll_ctl")]
-#[inline]
-pub fn add<EpollFd: AsFd, SourceFd: AsFd>(
- epoll: EpollFd,
- source: SourceFd,
- data: epoll::EventData,
- event_flags: epoll::EventFlags,
-) -> io::Result<()> {
- syscalls::epoll_add(
- epoll.as_fd(),
- source.as_fd(),
- &Event {
- flags: event_flags,
- data,
- #[cfg(all(libc, target_os = "redox"))]
- _pad: 0,
- },
- )
-}
-
-/// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in a
-/// given epoll object.
-///
-/// This sets the events of interest with `target` to `events`.
-///
-/// # References
-/// - [Linux]
-/// - [illumos]
-///
-/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html
-/// [illumos]: https://www.illumos.org/man/3C/epoll_ctl
-#[doc(alias = "epoll_ctl")]
-#[inline]
-pub fn modify<EpollFd: AsFd, SourceFd: AsFd>(
- epoll: EpollFd,
- source: SourceFd,
- data: epoll::EventData,
- event_flags: epoll::EventFlags,
-) -> io::Result<()> {
- syscalls::epoll_mod(
- epoll.as_fd(),
- source.as_fd(),
- &Event {
- flags: event_flags,
- data,
- #[cfg(all(libc, target_os = "redox"))]
- _pad: 0,
- },
- )
-}
-
-/// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in a
-/// given epoll object.
-///
-/// # References
-/// - [Linux]
-/// - [illumos]
-///
-/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html
-/// [illumos]: https://www.illumos.org/man/3C/epoll_ctl
-#[doc(alias = "epoll_ctl")]
-#[inline]
-pub fn delete<EpollFd: AsFd, SourceFd: AsFd>(epoll: EpollFd, source: SourceFd) -> io::Result<()> {
- syscalls::epoll_del(epoll.as_fd(), source.as_fd())
-}
-
-/// `epoll_wait(self, events, timeout)`—Waits for registered events of
-/// interest.
-///
-/// For each event of interest, an element is written to `events`.
-///
-/// Linux versions older than 5.11 (those that don't support `epoll_pwait2`)
-/// don't support timeouts greater than `c_int::MAX` milliseconds; if an
-/// unsupported timeout is passed, this function fails with
-/// [`io::Errno::INVAL`]. Enable the "linux_5_11" feature to enable the full
-/// range of timeouts.
-///
-/// # References
-/// - [Linux]
-/// - [illumos]
-///
-/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_wait.2.html
-/// [illumos]: https://www.illumos.org/man/3C/epoll_wait
-#[doc(alias = "epoll_wait")]
-#[inline]
-pub fn wait<EpollFd: AsFd, Buf: Buffer<Event>>(
- epoll: EpollFd,
- mut event_list: Buf,
- timeout: Option<&Timespec>,
-) -> io::Result<Buf::Output> {
- // SAFETY: `epoll_wait` behaves.
- let nfds = unsafe { syscalls::epoll_wait(epoll.as_fd(), event_list.parts_mut(), timeout)? };
- // SAFETY: `epoll_wait` behaves.
- unsafe { Ok(event_list.assume_init(nfds)) }
-}
-
-/// A record of an event that occurred.
-#[repr(C)]
-#[cfg_attr(all(not(libc), target_arch = "x86_64"), repr(packed))]
-#[cfg_attr(
- all(
- libc,
- linux_kernel,
- any(
- all(
- target_arch = "x86",
- not(target_env = "musl"),
- not(target_os = "android"),
- ),
- target_arch = "x86_64",
- )
- ),
- repr(packed)
-)]
-#[cfg_attr(
- all(solarish, any(target_arch = "x86", target_arch = "x86_64")),
- repr(packed(4))
-)]
-#[derive(Copy, Clone, Eq, PartialEq, Hash)]
-pub struct Event {
- /// Which specific event(s) occurred.
- pub flags: EventFlags,
- /// User data.
- pub data: EventData,
-
- #[cfg(all(libc, target_os = "redox"))]
- _pad: u64,
-}
-
-/// Data associated with an [`epoll::Event`]. This can either be a 64-bit
-/// integer value or a pointer which preserves pointer provenance.
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub union EventData {
- /// A 64-bit integer value.
- as_u64: u64,
-
- /// A `*mut c_void` which preserves pointer provenance, extended to be
- /// 64-bit so that if we read the value as a `u64` union field, we don't
- /// get uninitialized memory.
- sixty_four_bit_pointer: SixtyFourBitPointer,
-}
-
-impl EventData {
- /// Construct a new value containing a `u64`.
- #[inline]
- pub const fn new_u64(value: u64) -> Self {
- Self { as_u64: value }
- }
-
- /// Construct a new value containing a `*mut c_void`.
- #[inline]
- pub const fn new_ptr(value: *mut c_void) -> Self {
- Self {
- sixty_four_bit_pointer: SixtyFourBitPointer {
- pointer: value,
- #[cfg(target_pointer_width = "32")]
- _padding: 0,
- },
- }
- }
-
- /// Return the value as a `u64`.
- ///
- /// If the stored value was a pointer, the pointer is zero-extended to a
- /// `u64`.
- #[inline]
- pub fn u64(self) -> u64 {
- unsafe { self.as_u64 }
- }
-
- /// Return the value as a `*mut c_void`.
- ///
- /// If the stored value was a `u64`, the least-significant bits of the
- /// `u64` are returned as a pointer value.
- #[inline]
- pub fn ptr(self) -> *mut c_void {
- unsafe { self.sixty_four_bit_pointer.pointer }
- }
-}
-
-impl PartialEq for EventData {
- #[inline]
- fn eq(&self, other: &Self) -> bool {
- self.u64() == other.u64()
- }
-}
-
-impl Eq for EventData {}
-
-impl Hash for EventData {
- #[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.u64().hash(state)
- }
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-struct SixtyFourBitPointer {
- #[cfg(target_endian = "big")]
- #[cfg(target_pointer_width = "32")]
- _padding: u32,
-
- pointer: *mut c_void,
-
- #[cfg(target_endian = "little")]
- #[cfg(target_pointer_width = "32")]
- _padding: u32,
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::backend::c;
-
- #[test]
- fn test_epoll_layouts() {
- check_renamed_type!(Event, epoll_event);
- check_renamed_struct_renamed_field!(Event, epoll_event, flags, events);
- #[cfg(libc)]
- check_renamed_struct_renamed_field!(Event, epoll_event, data, u64);
- #[cfg(not(libc))]
- check_renamed_struct_renamed_field!(Event, epoll_event, data, data);
- }
-}
diff --git a/vendor/rustix/src/event/eventfd.rs b/vendor/rustix/src/event/eventfd.rs
deleted file mode 100644
index a76f2cfc..00000000
--- a/vendor/rustix/src/event/eventfd.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use crate::fd::OwnedFd;
-use crate::{backend, io};
-
-pub use backend::event::types::EventfdFlags;
-
-/// `eventfd(initval, flags)`—Creates a file descriptor for event
-/// notification.
-///
-/// # References
-/// - [Linux]
-/// - [FreeBSD]
-/// - [illumos]
-///
-/// [Linux]: https://man7.org/linux/man-pages/man2/eventfd.2.html
-/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?eventfd
-/// [illumos]: https://illumos.org/man/3C/eventfd
-#[inline]
-pub fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> {
- backend::event::syscalls::eventfd(initval, flags)
-}
diff --git a/vendor/rustix/src/event/kqueue.rs b/vendor/rustix/src/event/kqueue.rs
deleted file mode 100644
index 897d9398..00000000
--- a/vendor/rustix/src/event/kqueue.rs
+++ /dev/null
@@ -1,466 +0,0 @@
-//! An API for interfacing with `kqueue`.
-
-use crate::buffer::Buffer;
-use crate::fd::{AsFd, OwnedFd, RawFd};
-use crate::pid::Pid;
-use crate::signal::Signal;
-use crate::timespec::Timespec;
-use crate::{backend, io};
-
-use backend::c::{self, intptr_t, kevent as kevent_t, uintptr_t};
-use backend::event::syscalls;
-
-use core::mem::zeroed;
-use core::time::Duration;
-
-/// A `kqueue` event for use with [`kevent`].
-#[repr(transparent)]
-#[derive(Copy, Clone)]
-pub struct Event {
- // The layout varies between BSDs and macOS.
- inner: kevent_t,
-}
-
-impl Event {
- /// Create a new `Event`.
- #[allow(clippy::needless_update)]
- pub fn new(filter: EventFilter, flags: EventFlags, udata: *mut c::c_void) -> Event {
- let (ident, data, filter, fflags) = match filter {
- EventFilter::Read(fd) => (fd as uintptr_t, 0, c::EVFILT_READ, 0),
- EventFilter::Write(fd) => (fd as _, 0, c::EVFILT_WRITE, 0),
- #[cfg(target_os = "freebsd")]
- EventFilter::Empty(fd) => (fd as _, 0, c::EVFILT_EMPTY, 0),
- EventFilter::Vnode { vnode, flags } => (vnode as _, 0, c::EVFILT_VNODE, flags.bits()),
- EventFilter::Proc { pid, flags } => {
- (Pid::as_raw(Some(pid)) as _, 0, c::EVFILT_PROC, flags.bits())
- }
- EventFilter::Signal { signal, times: _ } => {
- (signal.as_raw() as _, 0, c::EVFILT_SIGNAL, 0)
- }
- EventFilter::Timer { ident, timer } => {
- #[cfg(any(apple, target_os = "freebsd", target_os = "netbsd"))]
- let (data, fflags) = match timer {
- Some(timer) => {
- if timer.subsec_millis() == 0 {
- (timer.as_secs() as _, c::NOTE_SECONDS)
- } else if timer.subsec_nanos() == 0 {
- (timer.as_micros() as _, c::NOTE_USECONDS)
- } else {
- (timer.as_nanos() as _, c::NOTE_NSECONDS)
- }
- }
- None => (intptr_t::MAX, c::NOTE_SECONDS),
- };
- #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
- let (data, fflags) = match timer {
- Some(timer) => (timer.as_millis() as _, 0),
- None => (intptr_t::MAX, 0),
- };
-
- (ident as _, data, c::EVFILT_TIMER, fflags)
- }
- #[cfg(any(apple, freebsdlike))]
- EventFilter::User {
- ident,
- flags,
- user_flags,
- } => (ident as _, 0, c::EVFILT_USER, flags.bits() | user_flags.0),
- EventFilter::Unknown => panic!("unknown filter"),
- };
-
- Event {
- inner: kevent_t {
- ident,
- filter: filter as _,
- flags: flags.bits() as _,
- fflags,
- data: {
- // On OpenBSD, data is an `i64` and not an `isize`.
- data as _
- },
- udata: {
- // On NetBSD, udata is an `isize` and not a pointer.
- udata as _
- },
- ..unsafe { zeroed() }
- },
- }
- }
-
- /// Get the event flags for this event.
- pub fn flags(&self) -> EventFlags {
- EventFlags::from_bits_retain(self.inner.flags as _)
- }
-
- /// Get the user data for this event.
- pub fn udata(&self) -> *mut c::c_void {
- // On NetBSD, udata is an isize and not a pointer.
- self.inner.udata as _
- }
-
- /// Get the raw data for this event.
- pub fn data(&self) -> i64 {
- // On some BSDs, data is an `isize` and not an `i64`.
- self.inner.data as _
- }
-
- /// Get the filter of this event.
- pub fn filter(&self) -> EventFilter {
- match self.inner.filter as _ {
- c::EVFILT_READ => EventFilter::Read(self.inner.ident as _),
- c::EVFILT_WRITE => EventFilter::Write(self.inner.ident as _),
- #[cfg(target_os = "freebsd")]
- c::EVFILT_EMPTY => EventFilter::Empty(self.inner.ident as _),
- c::EVFILT_VNODE => EventFilter::Vnode {
- vnode: self.inner.ident as _,
- flags: VnodeEvents::from_bits_retain(self.inner.fflags),
- },
- c::EVFILT_PROC => EventFilter::Proc {
- pid: Pid::from_raw(self.inner.ident as _).unwrap(),
- flags: ProcessEvents::from_bits_retain(self.inner.fflags),
- },
- c::EVFILT_SIGNAL => EventFilter::Signal {
- // SAFETY: `EventFilter::new` requires a valid `Signal`.
- signal: unsafe { Signal::from_raw_unchecked(self.inner.ident as _) },
- times: self.inner.data as _,
- },
- c::EVFILT_TIMER => EventFilter::Timer {
- ident: self.inner.ident as _,
- timer: {
- let (data, fflags) = (self.inner.data, self.inner.fflags);
- #[cfg(not(any(apple, target_os = "freebsd", target_os = "netbsd")))]
- let _ = fflags;
- #[cfg(any(apple, target_os = "freebsd", target_os = "netbsd"))]
- match fflags as _ {
- c::NOTE_SECONDS => Some(Duration::from_secs(data as _)),
- c::NOTE_USECONDS => Some(Duration::from_micros(data as _)),
- c::NOTE_NSECONDS => Some(Duration::from_nanos(data as _)),
- _ => {
- // Unknown timer flags.
- None
- }
- }
- #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
- Some(Duration::from_millis(data as _))
- },
- },
- #[cfg(any(apple, freebsdlike))]
- c::EVFILT_USER => EventFilter::User {
- ident: self.inner.ident as _,
- flags: UserFlags::from_bits_retain(self.inner.fflags),
- user_flags: UserDefinedFlags(self.inner.fflags & EVFILT_USER_FLAGS),
- },
- _ => EventFilter::Unknown,
- }
- }
-}
-
-/// Bottom 24 bits of a `u32`.
-#[cfg(any(apple, freebsdlike))]
-const EVFILT_USER_FLAGS: u32 = 0x00ff_ffff;
-
-/// The possible filters for a `kqueue`.
-#[repr(i16)]
-#[non_exhaustive]
-pub enum EventFilter {
- /// A read filter.
- Read(RawFd),
-
- /// A write filter.
- Write(RawFd),
-
- /// An empty filter.
- #[cfg(target_os = "freebsd")]
- Empty(RawFd),
-
- /// A VNode filter.
- Vnode {
- /// The file descriptor we looked for events in.
- vnode: RawFd,
-
- /// The flags for this event.
- flags: VnodeEvents,
- },
-
- /// A process filter.
- Proc {
- /// The process ID we waited on.
- pid: Pid,
-
- /// The flags for this event.
- flags: ProcessEvents,
- },
-
- /// A signal filter.
- Signal {
- /// The signal number we waited on.
- signal: Signal,
-
- /// The number of times the signal has been received since the last
- /// call to kevent.
- times: usize,
- },
-
- /// A timer filter.
- Timer {
- /// The identifier for this event.
- ident: intptr_t,
-
- /// The duration for this event.
- timer: Option<Duration>,
- },
-
- /// A user filter.
- #[cfg(any(apple, freebsdlike))]
- User {
- /// The identifier for this event.
- ident: intptr_t,
-
- /// The flags for this event.
- flags: UserFlags,
-
- /// The user-defined flags for this event.
- user_flags: UserDefinedFlags,
- },
-
- /// This filter is unknown.
- ///
- /// # Panics
- ///
- /// Passing this into `Event::new()` will result in a panic.
- Unknown,
-}
-
-bitflags::bitflags! {
- /// The flags for a `kqueue` event specifying actions to perform.
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct EventFlags: u16 {
- /// Add the event to the `kqueue`.
- const ADD = c::EV_ADD as _;
-
- /// Enable the event.
- const ENABLE = c::EV_ENABLE as _;
-
- /// Disable the event.
- const DISABLE = c::EV_DISABLE as _;
-
- /// Delete the event from the `kqueue`.
- const DELETE = c::EV_DELETE as _;
-
- /// TODO
- const RECEIPT = c::EV_RECEIPT as _;
-
- /// Clear the event after it is triggered.
- const ONESHOT = c::EV_ONESHOT as _;
-
- /// TODO
- const CLEAR = c::EV_CLEAR as _;
-
- /// TODO
- const EOF = c::EV_EOF as _;
-
- /// TODO
- const ERROR = c::EV_ERROR as _;
-
- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
- const _ = !0;
- }
-}
-
-bitflags::bitflags! {
- /// The flags for a virtual node event.
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct VnodeEvents: u32 {
- /// The file was deleted.
- const DELETE = c::NOTE_DELETE;
-
- /// The file was written to.
- const WRITE = c::NOTE_WRITE;
-
- /// The file was extended.
- const EXTEND = c::NOTE_EXTEND;
-
- /// The file had its attributes changed.
- const ATTRIBUTES = c::NOTE_ATTRIB;
-
- /// The file was renamed.
- const RENAME = c::NOTE_RENAME;
-
- /// Access to the file was revoked.
- const REVOKE = c::NOTE_REVOKE;
-
- /// The link count of the file has changed.
- const LINK = c::NOTE_LINK;
-
- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
- const _ = !0;
- }
-}
-
-bitflags::bitflags! {
- /// The flags for a process event.
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct ProcessEvents: u32 {
- /// The process exited.
- const EXIT = c::NOTE_EXIT;
-
- /// The process forked itself.
- const FORK = c::NOTE_FORK;
-
- /// The process executed a new process.
- const EXEC = c::NOTE_EXEC;
-
- /// Follow the process through `fork` calls (write only).
- const TRACK = c::NOTE_TRACK;
-
- /// An error has occurred with following the process.
- const TRACKERR = c::NOTE_TRACKERR;
-
- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
- const _ = !0;
- }
-}
-
-#[cfg(any(apple, freebsdlike))]
-bitflags::bitflags! {
- /// The flags for a user event.
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct UserFlags: u32 {
- /// Ignore the user input flags.
- #[doc(alias = "NOP")]
- const NOINPUT = c::NOTE_FFNOP;
-
- /// Bitwise AND `fflags`.
- const AND = c::NOTE_FFAND;
-
- /// Bitwise OR `fflags`.
- const OR = c::NOTE_FFOR;
-
- /// Copy `fflags`.
- const COPY = c::NOTE_FFCOPY;
-
- /// Control mask for operations.
- const CTRLMASK = c::NOTE_FFCTRLMASK;
-
- /// User defined flags for masks.
- const UDFMASK = c::NOTE_FFLAGSMASK;
-
- /// Trigger the event.
- const TRIGGER = c::NOTE_TRIGGER;
-
- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
- const _ = !0;
- }
-}
-
-/// User-defined flags.
-///
-/// Only the lower 24 bits are used in this struct.
-#[repr(transparent)]
-#[cfg(any(apple, freebsdlike))]
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct UserDefinedFlags(u32);
-
-#[cfg(any(apple, freebsdlike))]
-impl UserDefinedFlags {
- /// Create a new `UserDefinedFlags` from a `u32`.
- pub fn new(flags: u32) -> Self {
- Self(flags & EVFILT_USER_FLAGS)
- }
-
- /// Get the underlying `u32`.
- pub fn get(self) -> u32 {
- self.0
- }
-}
-
-/// `kqueue()`—Create a new `kqueue` file descriptor.
-///
-/// # References
-/// - [Apple]
-/// - [FreeBSD]
-/// - [OpenBSD]
-/// - [NetBSD]
-/// - [DragonFly BSD]
-///
-/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html
-/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
-/// [OpenBSD]: https://man.openbsd.org/kqueue.2
-/// [NetBSD]: https://man.netbsd.org/kqueue.2
-/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=kqueue&section=2
-pub fn kqueue() -> io::Result<OwnedFd> {
- syscalls::kqueue()
-}
-
-/// `kevent(kqueue, changelist, eventlist, timeout)`—Wait for events on a
-/// `kqueue`.
-///
-/// If an unsupported timeout is passed, this function fails with
-/// [`io::Errno::INVAL`].
-///
-/// # Safety
-///
-/// The file descriptors referred to by the `Event` structs must be valid for
-/// the lifetime of the `kqueue` file descriptor.
-///
-/// # References
-/// - [Apple]
-/// - [FreeBSD]
-/// - [OpenBSD]
-/// - [NetBSD]
-/// - [DragonFly BSD]
-///
-/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kevent.2.html
-/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=kevent&sektion=2
-/// [OpenBSD]: https://man.openbsd.org/kevent.2
-/// [NetBSD]: https://man.netbsd.org/kevent.2
-/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=kevent&section=2
-pub unsafe fn kevent_timespec<Fd: AsFd, Buf: Buffer<Event>>(
- kqueue: Fd,
- changelist: &[Event],
- mut eventlist: Buf,
- timeout: Option<&Timespec>,
-) -> io::Result<Buf::Output> {
- // Populate the event list with events.
- let len = syscalls::kevent(kqueue.as_fd(), changelist, eventlist.parts_mut(), timeout)
- .map(|res| res as _)?;
-
- Ok(eventlist.assume_init(len))
-}
-
-/// `kevent(kqueue, changelist, eventlist, timeout)`—Wait for events on a
-/// `kqueue`.
-///
-/// This is a wrapper around [`kevent_timespec`] which takes a `Duration`
-/// instead of a `Timespec` for the timemout value. `Timespec` has a signed
-/// `i64` seconds field; if converting `Duration` to `Timespec` overflows,
-/// `None` is passed as the timeout instead, such such a large timeout would
-/// be effectively infinite in practice.
-///
-/// # Safety
-///
-/// The file descriptors referred to by the `Event` structs must be valid for
-/// the lifetime of the `kqueue` file descriptor.
-pub unsafe fn kevent<Fd: AsFd, Buf: Buffer<Event>>(
- kqueue: Fd,
- changelist: &[Event],
- eventlist: Buf,
- timeout: Option<Duration>,
-) -> io::Result<Buf::Output> {
- let timeout = match timeout {
- Some(timeout) => match timeout.as_secs().try_into() {
- Ok(tv_sec) => Some(Timespec {
- tv_sec,
- tv_nsec: timeout.subsec_nanos() as _,
- }),
- Err(_) => None,
- },
- None => None,
- };
-
- kevent_timespec(kqueue, changelist, eventlist, timeout.as_ref())
-}
diff --git a/vendor/rustix/src/event/mod.rs b/vendor/rustix/src/event/mod.rs
deleted file mode 100644
index 29dfc227..00000000
--- a/vendor/rustix/src/event/mod.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-//! Event operations.
-
-#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))]
-pub mod epoll;
-#[cfg(any(
- linux_kernel,
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "espidf"
-))]
-mod eventfd;
-#[cfg(bsd)]
-pub mod kqueue;
-#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))]
-mod pause;
-mod poll;
-#[cfg(solarish)]
-pub mod port;
-#[cfg(any(bsd, linux_kernel, windows, target_os = "wasi"))]
-mod select;
-
-pub use crate::timespec::{Nsecs, Secs, Timespec};
-#[cfg(any(
- linux_kernel,
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "espidf"
-))]
-pub use eventfd::{eventfd, EventfdFlags};
-#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))]
-pub use pause::*;
-pub use poll::{poll, PollFd, PollFlags};
-#[cfg(any(bsd, linux_kernel, windows, target_os = "wasi"))]
-pub use select::*;
diff --git a/vendor/rustix/src/event/pause.rs b/vendor/rustix/src/event/pause.rs
deleted file mode 100644
index 41103011..00000000
--- a/vendor/rustix/src/event/pause.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use crate::backend;
-
-/// `pause()`—Sleep until interrupted by a signal.
-///
-/// The POSIX `pause` interface returns an error code, but the only thing
-/// `pause` does is sleep until interrupted by a signal. If it were exposed in
-/// the API here it would always return `Errno::INTR`, so for simplicity the
-/// return value is omitted.
-///
-/// # References
-/// - [POSIX]
-/// - [Linux]
-/// - [Apple]
-/// - [FreeBSD]
-/// - [NetBSD]
-/// - [OpenBSD]
-/// - [DragonFly BSD]
-/// - [illumos]
-///
-/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pause.html
-/// [Linux]: https://man7.org/linux/man-pages/man2/pause.2.html
-/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/pause.3.html
-/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pause&sektion=3
-/// [NetBSD]: https://man.netbsd.org/pause.3
-/// [OpenBSD]: https://man.openbsd.org/pause.3
-/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pause&section=3
-/// [illumos]: https://illumos.org/man/2/pause
-#[inline]
-pub fn pause() {
- backend::event::syscalls::pause()
-}
diff --git a/vendor/rustix/src/event/poll.rs b/vendor/rustix/src/event/poll.rs
deleted file mode 100644
index bf25fd5d..00000000
--- a/vendor/rustix/src/event/poll.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-use crate::event::Timespec;
-use crate::{backend, io};
-
-pub use backend::event::poll_fd::{PollFd, PollFlags};
-
-/// `poll(self.fds, timeout)`—Wait for events on lists of file descriptors.
-///
-/// Some platforms (those that don't support `ppoll`) don't support timeouts
-/// greater than `c_int::MAX` milliseconds; if an unsupported timeout is
-/// passed, this function fails with [`io::Errno::INVAL`].
-///
-/// On macOS, `poll` doesn't work on fds for /dev/tty or /dev/null, however
-/// [`select`] is available and does work on these fds.
-///
-/// [`select`]: crate::event::select()
-///
-/// This function does not use the [`Buffer`] trait because the `fds` list is
-/// both an input and output buffer.
-///
-/// [`Buffer`]: crate::buffer::Buffer
-///
-/// # References
-/// - [Beej's Guide to Network Programming]
-/// - [POSIX]
-/// - [Linux]
-/// - [Apple]
-/// - [Winsock]
-/// - [FreeBSD]
-/// - [NetBSD]
-/// - [OpenBSD]
-/// - [DragonFly BSD]
-/// - [illumos]
-///
-/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/slightly-advanced-techniques.html#poll
-/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/poll.html
-/// [Linux]: https://man7.org/linux/man-pages/man2/poll.2.html
-/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/poll.2.html
-/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll
-/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=poll&sektion=2
-/// [NetBSD]: https://man.netbsd.org/poll.2
-/// [OpenBSD]: https://man.openbsd.org/poll.2
-/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=poll&section=2
-/// [illumos]: https://illumos.org/man/2/poll
-#[inline]
-pub fn poll(fds: &mut [PollFd<'_>], timeout: Option<&Timespec>) -> io::Result<usize> {
- backend::event::syscalls::poll(fds, timeout)
-}
diff --git a/vendor/rustix/src/event/port.rs b/vendor/rustix/src/event/port.rs
deleted file mode 100644
index 7cc5f939..00000000
--- a/vendor/rustix/src/event/port.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-//! Solaris/illumos event ports.
-//!
-//! # Examples
-//!
-//! ```
-//! # fn test() -> std::io::Result<()> {
-//! use rustix::event::port;
-//! use rustix::stdio::stdout;
-//! use std::io;
-//!
-//! let some_fd = stdout();
-//! let some_userdata = 7 as *mut _;
-//!
-//! // Create a port.
-//! let port = port::create()?;
-//!
-//! // Associate `some_fd` with the port.
-//! unsafe {
-//! port::associate_fd(&port, some_fd, port::PollFlags::IN, some_userdata)?;
-//! }
-//!
-//! // Get a single event.
-//! let event = port::get(&port, None)?;
-//!
-//! assert_eq!(event.userdata(), some_userdata);
-//! # Ok(())
-//! # }
-//! ```
-
-use crate::backend::c;
-use crate::backend::event::syscalls;
-use crate::buffer::Buffer;
-use crate::fd::{AsFd, AsRawFd, OwnedFd};
-use crate::timespec::Timespec;
-use crate::{ffi, io};
-
-pub use super::PollFlags;
-
-/// The structure representing a port event.
-#[repr(transparent)]
-#[doc(alias = "port_event")]
-pub struct Event(pub(crate) c::port_event);
-
-impl Event {
- /// Get the events associated with this event.
- pub fn events(&self) -> i32 {
- self.0.portev_events
- }
-
- /// Get the event source associated with this event.
- pub fn object(&self) -> usize {
- self.0.portev_object
- }
-
- /// Get the userdata associated with this event.
- pub fn userdata(&self) -> *mut ffi::c_void {
- self.0.portev_user
- }
-}
-
-/// `port_create()`—Creates a new port.
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_create/
-/// [illumos]: https://illumos.org/man/3C/port_create
-#[doc(alias = "port_create")]
-pub fn create() -> io::Result<OwnedFd> {
- syscalls::port_create()
-}
-
-/// `port_associate(_, PORT_SOURCE_FD, _, _, _)`—Associates a file descriptor
-/// with a port.
-///
-/// # Safety
-///
-/// Any `object`s passed into the `port` must be valid for the lifetime of the
-/// `port`. Logically, `port` keeps a borrowed reference to the `object` until
-/// it is removed via [`dissociate_fd`].
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_associate/
-/// [illumos]: https://illumos.org/man/3C/port_associate
-#[doc(alias = "port_associate")]
-pub unsafe fn associate_fd<Fd: AsFd, RawFd: AsRawFd>(
- port: Fd,
- object: RawFd,
- events: PollFlags,
- userdata: *mut ffi::c_void,
-) -> io::Result<()> {
- syscalls::port_associate(
- port.as_fd(),
- c::PORT_SOURCE_FD,
- object.as_raw_fd() as _,
- events.bits() as _,
- userdata.cast(),
- )
-}
-
-/// `port_dissociate(_, PORT_SOURCE_FD, _)`—Dissociates a file descriptor
-/// from a port.
-///
-/// # Safety
-///
-/// The file descriptor passed into this function must have been previously
-/// associated with the port via [`associate_fd`].
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_dissociate
-/// [illumos]: https://illumos.org/man/3C/port_dissociate
-#[doc(alias = "port_dissociate")]
-pub unsafe fn dissociate_fd<Fd: AsFd, RawFd: AsRawFd>(port: Fd, object: RawFd) -> io::Result<()> {
- syscalls::port_dissociate(port.as_fd(), c::PORT_SOURCE_FD, object.as_raw_fd() as _)
-}
-
-/// `port_get(port, timeout)`—Gets an event from a port.
-///
-/// If an unsupported timeout is passed, this function fails with
-/// [`io::Errno::INVAL`].
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_get/
-/// [illumos]: https://illumos.org/man/3C/port_get
-#[doc(alias = "port_get")]
-pub fn get<Fd: AsFd>(port: Fd, timeout: Option<&Timespec>) -> io::Result<Event> {
- syscalls::port_get(port.as_fd(), timeout)
-}
-
-/// `port_getn(port, events, min_events, timeout)`—Gets multiple events from
-/// a port.
-///
-/// If `events` is empty, this does nothing and returns immediately.
-///
-/// To query the number of events without retrieving any, use [`getn_query`].
-///
-/// If an unsupported timeout is passed, this function fails with
-/// [`io::Errno::INVAL`].
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_getn/
-/// [illumos]: https://illumos.org/man/3C/port_getn
-#[doc(alias = "port_getn")]
-pub fn getn<Fd: AsFd, Buf: Buffer<Event>>(
- port: Fd,
- mut events: Buf,
- min_events: u32,
- timeout: Option<&Timespec>,
-) -> io::Result<Buf::Output> {
- // SAFETY: `port_getn` behaves.
- let nevents =
- unsafe { syscalls::port_getn(port.as_fd(), events.parts_mut(), min_events, timeout)? };
- // SAFETY: `port_getn` behaves.
- unsafe { Ok(events.assume_init(nevents)) }
-}
-
-/// `port_getn(port, NULL, 0, NULL)`—Queries the number of events
-/// available from a port.
-///
-/// To retrieve the events, use [`getn`].
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_getn/
-/// [illumos]: https://illumos.org/man/3C/port_getn
-#[doc(alias = "port_getn")]
-pub fn getn_query<Fd: AsFd>(port: Fd) -> io::Result<u32> {
- syscalls::port_getn_query(port.as_fd())
-}
-
-/// `port_send(port, events, userdata)`—Sends an event to a port.
-///
-/// # References
-/// - [OpenSolaris]
-/// - [illumos]
-///
-/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_send/
-/// [illumos]: https://illumos.org/man/3C/port_send
-#[doc(alias = "port_send")]
-pub fn send<Fd: AsFd>(port: Fd, events: i32, userdata: *mut ffi::c_void) -> io::Result<()> {
- syscalls::port_send(port.as_fd(), events, userdata.cast())
-}
diff --git a/vendor/rustix/src/event/select.rs b/vendor/rustix/src/event/select.rs
deleted file mode 100644
index 6bb93b53..00000000
--- a/vendor/rustix/src/event/select.rs
+++ /dev/null
@@ -1,391 +0,0 @@
-//! The `select` function.
-//!
-//! # Safety
-//!
-//! `select` is unsafe due to I/O safety.
-#![allow(unsafe_code)]
-
-#[cfg(any(linux_like, target_os = "wasi"))]
-use crate::backend::c;
-use crate::event::Timespec;
-use crate::fd::RawFd;
-use crate::{backend, io};
-#[cfg(any(windows, target_os = "wasi"))]
-use core::mem::align_of;
-use core::mem::size_of;
-
-/// wasi-libc's `fd_set` type. The libc bindings for it have private fields, so
-/// we redeclare it for ourselves so that we can access the fields. They're
-/// publicly exposed in wasi-libc.
-#[cfg(target_os = "wasi")]
-#[repr(C)]
-struct FD_SET {
- /// The wasi-libc headers call this `__nfds`.
- fd_count: usize,
- /// The wasi-libc headers call this `__fds`.
- fd_array: [i32; c::FD_SETSIZE],
-}
-
-#[cfg(windows)]
-use windows_sys::Win32::Networking::WinSock::FD_SET;
-
-/// Storage element type for use with [`select`].
-#[cfg(all(
- target_pointer_width = "64",
- any(windows, target_os = "freebsd", target_os = "dragonfly")
-))]
-#[repr(transparent)]
-#[derive(Copy, Clone, Default)]
-pub struct FdSetElement(pub(crate) u64);
-
-/// Storage element type for use with [`select`].
-#[cfg(linux_like)]
-#[repr(transparent)]
-#[derive(Copy, Clone, Default)]
-pub struct FdSetElement(pub(crate) c::c_ulong);
-
-/// Storage element type for use with [`select`].
-#[cfg(not(any(
- linux_like,
- target_os = "wasi",
- all(
- target_pointer_width = "64",
- any(windows, target_os = "freebsd", target_os = "dragonfly")
- )
-)))]
-#[repr(transparent)]
-#[derive(Copy, Clone, Default)]
-pub struct FdSetElement(pub(crate) u32);
-
-/// Storage element type for use with [`select`].
-#[cfg(target_os = "wasi")]
-#[repr(transparent)]
-#[derive(Copy, Clone, Default)]
-pub struct FdSetElement(pub(crate) usize);
-
-/// `select(nfds, readfds, writefds, exceptfds, timeout)`—Wait for events on
-/// sets of file descriptors.
-///
-/// `readfds`, `writefds`, `exceptfds` must point to arrays of `FdSetElement`
-/// containing at least `nfds.div_ceil(size_of::<FdSetElement>())` elements.
-///
-/// If an unsupported timeout is passed, this function fails with
-/// [`io::Errno::INVAL`].
-///
-/// This `select` wrapper differs from POSIX in that `nfds` is not limited to
-/// `FD_SETSIZE`. Instead of using the fixed-sized `fd_set` type, this function
-/// takes raw pointers to arrays of `fd_set_num_elements(max_fd + 1, num_fds)`,
-/// where `max_fd` is the maximum value of any fd that will be inserted into
-/// the set, and `num_fds` is the maximum number of fds that will be inserted
-/// into the set.
-///
-/// In particular, on Apple platforms, this function behaves as if
-/// `_DARWIN_UNLIMITED_SELECT` were predefined.
-///
-/// On illumos, this function is not defined because the `select` function on
-/// this platform always has an `FD_SETSIZE` limitation, following POSIX. This
-/// platform's documentation recommends using [`poll`] instead.
-///
-/// [`fd_set_insert`], [`fd_set_remove`], and [`FdSetIter`] are provided for
-/// setting, clearing, and iterating with sets.
-///
-/// [`poll`]: crate::event::poll()
-///
-/// # Safety
-///
-/// All fds in all the sets must correspond to open file descriptors.
-///
-/// # References
-/// - [POSIX]
-/// - [Linux]
-/// - [Apple]
-/// - [FreeBSD]
-/// - [NetBSD]
-/// - [OpenBSD]
-/// - [DragonFly BSD]
-/// - [Winsock]
-/// - [glibc]
-///
-/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/select.html
-/// [Linux]: https://man7.org/linux/man-pages/man2/select.2.html
-/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/select.2.html
-/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=select&sektion=2
-/// [NetBSD]: https://man.netbsd.org/select.2
-/// [OpenBSD]: https://man.openbsd.org/select.2
-/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=select&section=2
-/// [Winsock]: https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select
-/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Waiting-for-I_002fO.html#index-select
-pub unsafe fn select(
- nfds: i32,
- readfds: Option<&mut [FdSetElement]>,
- writefds: Option<&mut [FdSetElement]>,
- exceptfds: Option<&mut [FdSetElement]>,
- timeout: Option<&Timespec>,
-) -> io::Result<i32> {
- backend::event::syscalls::select(nfds, readfds, writefds, exceptfds, timeout)
-}
-
-#[cfg(not(any(windows, target_os = "wasi")))]
-const BITS: usize = size_of::<FdSetElement>() * 8;
-
-/// Set `fd` in the set pointed to by `fds`.
-#[doc(alias = "FD_SET")]
-#[inline]
-pub fn fd_set_insert(fds: &mut [FdSetElement], fd: RawFd) {
- #[cfg(not(any(windows, target_os = "wasi")))]
- {
- let fd = fd as usize;
- fds[fd / BITS].0 |= 1 << (fd % BITS);
- }
-
- #[cfg(any(windows, target_os = "wasi"))]
- {
- let set = unsafe { &mut *fds.as_mut_ptr().cast::<FD_SET>() };
- let fd_count = set.fd_count;
- let fd_array = &set.fd_array[..fd_count as usize];
-
- if !fd_array.contains(&(fd as _)) {
- let fd_array = &mut set.fd_array[..fd_count as usize + 1];
- set.fd_count = fd_count + 1;
- fd_array[fd_count as usize] = fd as _;
- }
- }
-}
-
-/// Clear `fd` in the set pointed to by `fds`.
-#[doc(alias = "FD_CLR")]
-#[inline]
-pub fn fd_set_remove(fds: &mut [FdSetElement], fd: RawFd) {
- #[cfg(not(any(windows, target_os = "wasi")))]
- {
- let fd = fd as usize;
- fds[fd / BITS].0 &= !(1 << (fd % BITS));
- }
-
- #[cfg(any(windows, target_os = "wasi"))]
- {
- let set = unsafe { &mut *fds.as_mut_ptr().cast::<FD_SET>() };
- let fd_count = set.fd_count;
- let fd_array = &set.fd_array[..fd_count as usize];
-
- if let Some(pos) = fd_array.iter().position(|p| *p as RawFd == fd) {
- set.fd_count = fd_count - 1;
- set.fd_array[pos] = *set.fd_array.last().unwrap();
- }
- }
-}
-
-/// Compute the minimum `nfds` value needed for the set pointed to by `fds`.
-#[inline]
-pub fn fd_set_bound(fds: &[FdSetElement]) -> RawFd {
- #[cfg(not(any(windows, target_os = "wasi")))]
- {
- if let Some(position) = fds.iter().rposition(|element| element.0 != 0) {
- let element = fds[position].0;
- (position * BITS + (BITS - element.leading_zeros() as usize)) as RawFd
- } else {
- 0
- }
- }
-
- #[cfg(any(windows, target_os = "wasi"))]
- {
- let set = unsafe { &*fds.as_ptr().cast::<FD_SET>() };
- let fd_count = set.fd_count;
- let fd_array = &set.fd_array[..fd_count as usize];
- let mut max = 0;
- for fd in fd_array {
- if *fd >= max {
- max = *fd + 1;
- }
- }
- max as RawFd
- }
-}
-
-/// Compute the number of `FdSetElement`s needed to hold a set which can
-/// contain up to `set_count` file descriptors with values less than `nfds`.
-#[inline]
-pub fn fd_set_num_elements(set_count: usize, nfds: RawFd) -> usize {
- #[cfg(any(windows, target_os = "wasi"))]
- {
- let _ = nfds;
-
- fd_set_num_elements_for_fd_array(set_count)
- }
-
- #[cfg(not(any(windows, target_os = "wasi")))]
- {
- let _ = set_count;
-
- fd_set_num_elements_for_bitvector(nfds)
- }
-}
-
-/// `fd_set_num_elements` implementation on platforms with fd array
-/// implementations.
-#[cfg(any(windows, target_os = "wasi"))]
-#[inline]
-pub(crate) fn fd_set_num_elements_for_fd_array(set_count: usize) -> usize {
- // Ensure that we always have a big enough set to dereference an `FD_SET`.
- core::cmp::max(
- fd_set_num_elements_for_fd_array_raw(set_count),
- div_ceil(size_of::<FD_SET>(), size_of::<FdSetElement>()),
- )
-}
-
-/// Compute the raw `fd_set_num_elements` value, before ensuring the value is
-/// big enough to dereference an `FD_SET`.
-#[cfg(any(windows, target_os = "wasi"))]
-#[inline]
-fn fd_set_num_elements_for_fd_array_raw(set_count: usize) -> usize {
- // Allocate space for an `fd_count` field, plus `set_count` elements
- // for the `fd_array` field.
- div_ceil(
- core::cmp::max(align_of::<FD_SET>(), align_of::<RawFd>()) + set_count * size_of::<RawFd>(),
- size_of::<FdSetElement>(),
- )
-}
-
-/// `fd_set_num_elements` implementation on platforms with bitvector
-/// implementations.
-#[cfg(not(any(windows, target_os = "wasi")))]
-#[inline]
-pub(crate) fn fd_set_num_elements_for_bitvector(nfds: RawFd) -> usize {
- // Allocate space for a dense bitvector for `nfds` bits.
- let nfds = nfds as usize;
- div_ceil(nfds, BITS)
-}
-
-fn div_ceil(lhs: usize, rhs: usize) -> usize {
- let d = lhs / rhs;
- let r = lhs % rhs;
- if r > 0 {
- d + 1
- } else {
- d
- }
-}
-
-/// An iterator over the fds in a set.
-#[doc(alias = "FD_ISSET")]
-#[cfg(not(any(windows, target_os = "wasi")))]
-pub struct FdSetIter<'a> {
- current: RawFd,
- fds: &'a [FdSetElement],
-}
-
-/// An iterator over the fds in a set.
-#[doc(alias = "FD_ISSET")]
-#[cfg(any(windows, target_os = "wasi"))]
-pub struct FdSetIter<'a> {
- current: usize,
- fds: &'a [FdSetElement],
-}
-
-impl<'a> FdSetIter<'a> {
- /// Construct a `FdSetIter` for the given set.
- pub fn new(fds: &'a [FdSetElement]) -> Self {
- Self { current: 0, fds }
- }
-}
-
-#[cfg(not(any(windows, target_os = "wasi")))]
-impl<'a> Iterator for FdSetIter<'a> {
- type Item = RawFd;
-
- fn next(&mut self) -> Option<Self::Item> {
- if let Some(element) = self.fds.get(self.current as usize / BITS) {
- // Test whether the current element has more bits set.
- let shifted = element.0 >> ((self.current as usize % BITS) as u32);
- if shifted != 0 {
- let fd = self.current + shifted.trailing_zeros() as RawFd;
- self.current = fd + 1;
- return Some(fd);
- }
-
- // Search through the array for the next element with bits set.
- if let Some(index) = self.fds[(self.current as usize / BITS) + 1..]
- .iter()
- .position(|element| element.0 != 0)
- {
- let index = index + (self.current as usize / BITS) + 1;
- let element = self.fds[index].0;
- let fd = (index * BITS) as RawFd + element.trailing_zeros() as RawFd;
- self.current = fd + 1;
- return Some(fd);
- }
- }
- None
- }
-}
-
-#[cfg(any(windows, target_os = "wasi"))]
-impl<'a> Iterator for FdSetIter<'a> {
- type Item = RawFd;
-
- fn next(&mut self) -> Option<Self::Item> {
- let current = self.current;
-
- let set = unsafe { &*self.fds.as_ptr().cast::<FD_SET>() };
- let fd_count = set.fd_count;
- let fd_array = &set.fd_array[..fd_count as usize];
-
- if current == fd_count as usize {
- return None;
- }
- let fd = fd_array[current as usize];
- self.current = current + 1;
- Some(fd as RawFd)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use core::mem::{align_of, size_of};
-
- #[test]
- #[cfg(any(windows, target_os = "wasi"))]
- fn layouts() {
- // The `FdSetElement` array should be suitably aligned.
- assert_eq!(align_of::<FdSetElement>(), align_of::<FD_SET>());
-
- // The layout of `FD_SET` should match our layout of a set of the same
- // size.
- assert_eq!(
- fd_set_num_elements_for_fd_array_raw(
- memoffset::span_of!(FD_SET, fd_array).len() / size_of::<RawFd>()
- ) * size_of::<FdSetElement>(),
- size_of::<FD_SET>()
- );
- assert_eq!(
- fd_set_num_elements_for_fd_array(
- memoffset::span_of!(FD_SET, fd_array).len() / size_of::<RawFd>()
- ) * size_of::<FdSetElement>(),
- size_of::<FD_SET>()
- );
-
- // Don't create fd sets smaller than `FD_SET`.
- assert_eq!(
- fd_set_num_elements_for_fd_array(0) * size_of::<FdSetElement>(),
- size_of::<FD_SET>()
- );
- }
-
- #[test]
- #[cfg(any(bsd, linux_kernel))]
- fn layouts() {
- use crate::backend::c;
-
- // The `FdSetElement` array should be suitably aligned.
- assert_eq!(align_of::<FdSetElement>(), align_of::<c::fd_set>());
-
- // The layout of `fd_set` should match our layout of a set of the same
- // size.
- assert_eq!(
- fd_set_num_elements_for_bitvector(c::FD_SETSIZE as RawFd) * size_of::<FdSetElement>(),
- size_of::<c::fd_set>()
- );
- }
-}