summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/imp/libc/io
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/imp/libc/io')
-rw-r--r--vendor/rustix/src/imp/libc/io/epoll.rs568
-rw-r--r--vendor/rustix/src/imp/libc/io/errno.rs997
-rw-r--r--vendor/rustix/src/imp/libc/io/io_slice.rs85
-rw-r--r--vendor/rustix/src/imp/libc/io/mod.rs13
-rw-r--r--vendor/rustix/src/imp/libc/io/poll_fd.rs136
-rw-r--r--vendor/rustix/src/imp/libc/io/syscalls.rs456
-rw-r--r--vendor/rustix/src/imp/libc/io/types.rs89
-rw-r--r--vendor/rustix/src/imp/libc/io/windows_syscalls.rs39
8 files changed, 2383 insertions, 0 deletions
diff --git a/vendor/rustix/src/imp/libc/io/epoll.rs b/vendor/rustix/src/imp/libc/io/epoll.rs
new file mode 100644
index 000000000..a95e6b5cd
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/epoll.rs
@@ -0,0 +1,568 @@
+//! epoll support.
+//!
+//! This is an experiment, and it isn't yet clear whether epoll is the right
+//! level of abstraction at which to introduce safety. But it works fairly well
+//! in simple examples 🙂.
+//!
+//! # Examples
+//!
+//! ```rust,no_run
+//! # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
+//! # #[cfg(feature = "net")]
+//! # fn main() -> std::io::Result<()> {
+//! use io_lifetimes::AsFd;
+//! use rustix::io::epoll::{self, Epoll};
+//! use rustix::io::{ioctl_fionbio, read, write};
+//! use rustix::net::{
+//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4,
+//! SocketType,
+//! };
+//! use std::os::unix::io::AsRawFd;
+//!
+//! // Create a socket and listen on it.
+//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
+//! bind_v4(&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::new(epoll::CreateFlags::CLOEXEC, epoll::Owning::new())?;
+//!
+//! // Remember the socket raw fd, which we use for comparisons only.
+//! let raw_listen_sock = listen_sock.as_fd().as_raw_fd();
+//!
+//! // Register the socket with the epoll object.
+//! epoll.add(listen_sock, epoll::EventFlags::IN)?;
+//!
+//! // Process events.
+//! let mut event_list = epoll::EventVec::with_capacity(4);
+//! loop {
+//! epoll.wait(&mut event_list, -1)?;
+//! for (_event_flags, target) in &event_list {
+//! if target.as_raw_fd() == raw_listen_sock {
+//! // 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(&*target)?;
+//! ioctl_fionbio(&conn_sock, true)?;
+//! epoll.add(conn_sock, epoll::EventFlags::OUT | epoll::EventFlags::ET)?;
+//! } else {
+//! // Write a message to the stream and then unregister it.
+//! write(&*target, b"hello\n")?;
+//! let _ = epoll.del(target)?;
+//! }
+//! }
+//! }
+//! # }
+//! # #[cfg(not(feature = "net"))]
+//! # fn main() {}
+//! ```
+
+use super::super::c;
+use super::super::conv::{ret, ret_owned_fd, ret_u32};
+use crate::fd::{AsFd, AsRawFd, BorrowedFd, RawFd};
+#[cfg(not(feature = "rustc-dep-of-std"))]
+use crate::fd::{FromFd, FromRawFd, IntoFd, IntoRawFd};
+use crate::io::{self, OwnedFd};
+use alloc::vec::Vec;
+use bitflags::bitflags;
+use core::convert::TryInto;
+use core::fmt;
+use core::marker::PhantomData;
+use core::ops::Deref;
+use core::ptr::{null, null_mut};
+
+bitflags! {
+ /// `EPOLL_*` for use with [`Epoll::new`].
+ pub struct CreateFlags: c::c_int {
+ /// `EPOLL_CLOEXEC`
+ const CLOEXEC = c::EPOLL_CLOEXEC;
+ }
+}
+
+bitflags! {
+ /// `EPOLL*` for use with [`Epoll::add`].
+ #[derive(Default)]
+ pub struct EventFlags: u32 {
+ /// `EPOLLIN`
+ const IN = c::EPOLLIN as u32;
+
+ /// `EPOLLOUT`
+ const OUT = c::EPOLLOUT as u32;
+
+ /// `EPOLLPRI`
+ const PRI = c::EPOLLPRI as u32;
+
+ /// `EPOLLERR`
+ const ERR = c::EPOLLERR as u32;
+
+ /// `EPOLLHUP`
+ const HUP = c::EPOLLHUP as u32;
+
+ /// `EPOLLET`
+ const ET = c::EPOLLET as u32;
+
+ /// `EPOLLONESHOT`
+ const ONESHOT = c::EPOLLONESHOT as u32;
+
+ /// `EPOLLWAKEUP`
+ const WAKEUP = c::EPOLLWAKEUP as u32;
+
+ /// `EPOLLEXCLUSIVE`
+ #[cfg(not(target_os = "android"))]
+ const EXCLUSIVE = c::EPOLLEXCLUSIVE as u32;
+ }
+}
+
+/// A reference to a `T`.
+pub struct Ref<'a, T> {
+ t: T,
+ _phantom: PhantomData<&'a T>,
+}
+
+impl<'a, T> Ref<'a, T> {
+ #[inline]
+ fn new(t: T) -> Self {
+ Self {
+ t,
+ _phantom: PhantomData,
+ }
+ }
+
+ #[inline]
+ fn consume(self) -> T {
+ self.t
+ }
+}
+
+impl<'a, T> Deref for Ref<'a, T> {
+ type Target = T;
+
+ #[inline]
+ fn deref(&self) -> &T {
+ &self.t
+ }
+}
+
+impl<'a, T: fmt::Debug> fmt::Debug for Ref<'a, T> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.t.fmt(fmt)
+ }
+}
+
+/// A trait for data stored within an [`Epoll`] instance.
+pub trait Context {
+ /// The type of an element owned by this context.
+ type Data;
+
+ /// The type of a value used to refer to an element owned by this context.
+ type Target: AsFd;
+
+ /// Assume ownership of `data`, and returning a `Target`.
+ fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target>;
+
+ /// Encode `target` as a `u64`. The only requirement on this value is that
+ /// it be decodable by `decode`.
+ fn encode(&self, target: Ref<'_, Self::Target>) -> u64;
+
+ /// Decode `raw`, which is a value encoded by `encode`, into a `Target`.
+ ///
+ /// # Safety
+ ///
+ /// `raw` must be a `u64` value returned from `encode`, from the same
+ /// context, and within the context's lifetime.
+ unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target>;
+
+ /// Release ownership of the value referred to by `target` and return it.
+ fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data;
+}
+
+/// A type implementing [`Context`] where the `Data` type is `BorrowedFd<'a>`.
+pub struct Borrowing<'a> {
+ _phantom: PhantomData<BorrowedFd<'a>>,
+}
+
+impl<'a> Context for Borrowing<'a> {
+ type Data = BorrowedFd<'a>;
+ type Target = BorrowedFd<'a>;
+
+ #[inline]
+ fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> {
+ Ref::new(data)
+ }
+
+ #[inline]
+ fn encode(&self, target: Ref<'_, Self::Target>) -> u64 {
+ target.as_raw_fd() as u64
+ }
+
+ #[inline]
+ unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> {
+ Ref::new(BorrowedFd::<'a>::borrow_raw(raw as RawFd))
+ }
+
+ #[inline]
+ fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data {
+ target.consume()
+ }
+}
+
+/// A type implementing [`Context`] where the `Data` type is `T`, a type
+/// implementing `IntoFd` and `FromFd`.
+///
+/// This may be used with [`OwnedFd`], or higher-level types like
+/// [`std::fs::File`] or [`std::net::TcpStream`].
+#[cfg(not(feature = "rustc-dep-of-std"))]
+pub struct Owning<'context, T: IntoFd + FromFd> {
+ _phantom: PhantomData<&'context T>,
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: IntoFd + FromFd> Owning<'context, T> {
+ /// Creates a new empty `Owning`.
+ #[allow(clippy::new_without_default)] // This is a specialized type that doesn't need to be generically constructible.
+ #[inline]
+ pub fn new() -> Self {
+ Self {
+ _phantom: PhantomData,
+ }
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> Context for Owning<'context, T> {
+ type Data = T;
+ type Target = BorrowedFd<'context>;
+
+ #[inline]
+ fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> {
+ let raw_fd = data.into_fd().into_raw_fd();
+ // Safety: `epoll` will assign ownership of the file descriptor to the
+ // kernel epoll object. We use `IntoFd`+`IntoRawFd` to consume the
+ // `Data` and extract the raw file descriptor and then "borrow" it
+ // with `borrow_raw` knowing that the borrow won't outlive the
+ // kernel epoll object.
+ unsafe { Ref::new(BorrowedFd::<'context>::borrow_raw(raw_fd)) }
+ }
+
+ #[inline]
+ fn encode(&self, target: Ref<'_, Self::Target>) -> u64 {
+ target.as_fd().as_raw_fd() as u64
+ }
+
+ #[inline]
+ unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> {
+ Ref::new(BorrowedFd::<'context>::borrow_raw(raw as RawFd))
+ }
+
+ #[inline]
+ fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data {
+ // The file descriptor was held by the kernel epoll object and is now
+ // being released, so we can create a new `OwnedFd` that assumes
+ // ownership.
+ let raw_fd = target.consume().as_raw_fd();
+ unsafe { T::from_fd(io_lifetimes::OwnedFd::from_raw_fd(raw_fd)) }
+ }
+}
+
+/// An "epoll", an interface to an OS object allowing one to repeatedly wait
+/// for events from a set of file descriptors efficiently.
+pub struct Epoll<Context: self::Context> {
+ epoll_fd: OwnedFd,
+ context: Context,
+}
+
+impl<Context: self::Context> Epoll<Context> {
+ /// `epoll_create1(flags)`—Creates a new `Epoll`.
+ ///
+ /// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file
+ /// descriptor from being implicitly passed across `exec` boundaries.
+ #[inline]
+ #[doc(alias = "epoll_create1")]
+ pub fn new(flags: CreateFlags, context: Context) -> io::Result<Self> {
+ // Safety: We're calling `epoll_create1` via FFI and we know how it
+ // behaves.
+ unsafe {
+ Ok(Self {
+ epoll_fd: ret_owned_fd(c::epoll_create1(flags.bits()))?,
+ context,
+ })
+ }
+ }
+
+ /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an
+ /// `Epoll`.
+ ///
+ /// This registers interest in any of the events set in `events` occurring
+ /// on the file descriptor associated with `data`.
+ #[doc(alias = "epoll_ctl")]
+ pub fn add(
+ &self,
+ data: Context::Data,
+ event_flags: EventFlags,
+ ) -> io::Result<Ref<'_, Context::Target>> {
+ // Safety: We're calling `epoll_ctl` via FFI and we know how it
+ // behaves.
+ unsafe {
+ let target = self.context.acquire(data);
+ let raw_fd = target.as_fd().as_raw_fd();
+ let encoded = self.context.encode(target);
+ ret(c::epoll_ctl(
+ self.epoll_fd.as_fd().as_raw_fd(),
+ c::EPOLL_CTL_ADD,
+ raw_fd,
+ &mut c::epoll_event {
+ events: event_flags.bits(),
+ r#u64: encoded,
+ },
+ ))?;
+ Ok(self.context.decode(encoded))
+ }
+ }
+
+ /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in
+ /// this `Epoll`.
+ ///
+ /// This sets the events of interest with `target` to `events`.
+ #[doc(alias = "epoll_ctl")]
+ pub fn mod_(
+ &self,
+ target: Ref<'_, Context::Target>,
+ event_flags: EventFlags,
+ ) -> io::Result<()> {
+ let raw_fd = target.as_fd().as_raw_fd();
+ let encoded = self.context.encode(target);
+ // Safety: We're calling `epoll_ctl` via FFI and we know how it
+ // behaves.
+ unsafe {
+ ret(c::epoll_ctl(
+ self.epoll_fd.as_fd().as_raw_fd(),
+ c::EPOLL_CTL_MOD,
+ raw_fd,
+ &mut c::epoll_event {
+ events: event_flags.bits(),
+ r#u64: encoded,
+ },
+ ))
+ }
+ }
+
+ /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in
+ /// this `Epoll`.
+ ///
+ /// This also returns the owning `Data`.
+ #[doc(alias = "epoll_ctl")]
+ pub fn del(&self, target: Ref<'_, Context::Target>) -> io::Result<Context::Data> {
+ // Safety: We're calling `epoll_ctl` via FFI and we know how it
+ // behaves.
+ unsafe {
+ let raw_fd = target.as_fd().as_raw_fd();
+ ret(c::epoll_ctl(
+ self.epoll_fd.as_fd().as_raw_fd(),
+ c::EPOLL_CTL_DEL,
+ raw_fd,
+ null_mut(),
+ ))?;
+ }
+ Ok(self.context.release(target))
+ }
+
+ /// `epoll_wait(self, events, timeout)`—Waits for registered events of
+ /// interest.
+ ///
+ /// For each event of interest, an element is written to `events`. On
+ /// success, this returns the number of written elements.
+ #[doc(alias = "epoll_wait")]
+ pub fn wait<'context>(
+ &'context self,
+ event_list: &mut EventVec<'context, Context>,
+ timeout: c::c_int,
+ ) -> io::Result<()> {
+ // Safety: We're calling `epoll_wait` via FFI and we know how it
+ // behaves.
+ unsafe {
+ event_list.events.set_len(0);
+ let nfds = ret_u32(c::epoll_wait(
+ self.epoll_fd.as_fd().as_raw_fd(),
+ event_list.events.as_mut_ptr().cast::<c::epoll_event>(),
+ event_list.events.capacity().try_into().unwrap_or(i32::MAX),
+ timeout,
+ ))?;
+ event_list.events.set_len(nfds as usize);
+ event_list.context = &self.context;
+ }
+
+ Ok(())
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> AsRawFd for Epoll<Owning<'context, T>> {
+ fn as_raw_fd(&self) -> RawFd {
+ self.epoll_fd.as_raw_fd()
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> IntoRawFd for Epoll<Owning<'context, T>> {
+ fn into_raw_fd(self) -> RawFd {
+ self.epoll_fd.into_raw_fd()
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> FromRawFd for Epoll<Owning<'context, T>> {
+ unsafe fn from_raw_fd(fd: RawFd) -> Self {
+ Self {
+ epoll_fd: OwnedFd::from_raw_fd(fd),
+ context: Owning::new(),
+ }
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> AsFd for Epoll<Owning<'context, T>> {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ self.epoll_fd.as_fd()
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> From<Epoll<Owning<'context, T>>> for OwnedFd {
+ fn from(epoll: Epoll<Owning<'context, T>>) -> Self {
+ epoll.epoll_fd
+ }
+}
+
+#[cfg(not(feature = "rustc-dep-of-std"))]
+impl<'context, T: AsFd + IntoFd + FromFd> From<OwnedFd> for Epoll<Owning<'context, T>> {
+ fn from(fd: OwnedFd) -> Self {
+ Self {
+ epoll_fd: fd,
+ context: Owning::new(),
+ }
+ }
+}
+
+/// An iterator over the `Event`s in an `EventVec`.
+pub struct Iter<'context, Context: self::Context> {
+ iter: core::slice::Iter<'context, Event>,
+ context: *const Context,
+ _phantom: PhantomData<&'context Context>,
+}
+
+impl<'context, Context: self::Context> Iterator for Iter<'context, Context> {
+ type Item = (EventFlags, Ref<'context, Context::Target>);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ // Safety: `self.context` is guaranteed to be valid because we hold
+ // `'context` for it. And we know this event is associated with this
+ // context because `wait` sets both.
+ self.iter.next().map(|event| {
+ (event.event_flags, unsafe {
+ (*self.context).decode(event.encoded)
+ })
+ })
+ }
+}
+
+/// A record of an event that occurred.
+#[repr(C)]
+#[cfg_attr(
+ any(
+ all(
+ target_arch = "x86",
+ not(target_env = "musl"),
+ not(target_os = "android"),
+ ),
+ target_arch = "x86_64",
+ ),
+ repr(packed)
+)]
+struct Event {
+ // Match the layout of `c::epoll_event`. We just use a `u64` instead of
+ // the full union; `Context` implementations will simply need to deal with
+ // casting the value into and out of the `u64` themselves.
+ event_flags: EventFlags,
+ encoded: u64,
+}
+
+/// A vector of `Event`s, plus context for interpreting them.
+pub struct EventVec<'context, Context: self::Context> {
+ events: Vec<Event>,
+ context: *const Context,
+ _phantom: PhantomData<&'context Context>,
+}
+
+impl<'context, Context: self::Context> EventVec<'context, Context> {
+ /// Constructs an `EventVec` with memory for `capacity` `Event`s.
+ #[inline]
+ pub fn with_capacity(capacity: usize) -> Self {
+ Self {
+ events: Vec::with_capacity(capacity),
+ context: null(),
+ _phantom: PhantomData,
+ }
+ }
+
+ /// Returns the current `Event` capacity of this `EventVec`.
+ #[inline]
+ pub fn capacity(&self) -> usize {
+ self.events.capacity()
+ }
+
+ /// Reserves enough memory for at least `additional` more `Event`s.
+ #[inline]
+ pub fn reserve(&mut self, additional: usize) {
+ self.events.reserve(additional);
+ }
+
+ /// Reserves enough memory for exactly `additional` more `Event`s.
+ #[inline]
+ pub fn reserve_exact(&mut self, additional: usize) {
+ self.events.reserve_exact(additional);
+ }
+
+ /// Clears all the `Events` out of this `EventVec`.
+ #[inline]
+ pub fn clear(&mut self) {
+ self.events.clear();
+ }
+
+ /// Shrinks the capacity of this `EventVec` as much as possible.
+ #[inline]
+ pub fn shrink_to_fit(&mut self) {
+ self.events.shrink_to_fit();
+ }
+
+ /// Returns an iterator over the `Event`s in this `EventVec`.
+ #[inline]
+ pub fn iter(&self) -> Iter<'_, Context> {
+ Iter {
+ iter: self.events.iter(),
+ context: self.context,
+ _phantom: PhantomData,
+ }
+ }
+
+ /// Returns the number of `Event`s logically contained in this `EventVec`.
+ #[inline]
+ pub fn len(&mut self) -> usize {
+ self.events.len()
+ }
+
+ /// Tests whether this `EventVec` is logically empty.
+ #[inline]
+ pub fn is_empty(&mut self) -> bool {
+ self.events.is_empty()
+ }
+}
+
+impl<'context, Context: self::Context> IntoIterator for &'context EventVec<'context, Context> {
+ type IntoIter = Iter<'context, Context>;
+ type Item = (EventFlags, Ref<'context, Context::Target>);
+
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
diff --git a/vendor/rustix/src/imp/libc/io/errno.rs b/vendor/rustix/src/imp/libc/io/errno.rs
new file mode 100644
index 000000000..470cf205c
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/errno.rs
@@ -0,0 +1,997 @@
+//! The `rustix` `Errno` type.
+//!
+//! This type holds an OS error code, which conceptually corresponds to an
+//! `errno` value.
+
+use super::super::c;
+use libc_errno::errno;
+
+/// The error type for `rustix` APIs.
+///
+/// This is similar to `std::io::Error`, but only holds an OS error code,
+/// and no extra error value.
+#[repr(transparent)]
+#[doc(alias = "errno")]
+#[derive(Eq, PartialEq, Hash, Copy, Clone)]
+pub struct Errno(pub(crate) c::c_int);
+
+impl Errno {
+ /// `EACCES`
+ #[doc(alias = "ACCES")]
+ pub const ACCESS: Self = Self(c::EACCES);
+ /// `EADDRINUSE`
+ pub const ADDRINUSE: Self = Self(c::EADDRINUSE);
+ /// `EADDRNOTAVAIL`
+ pub const ADDRNOTAVAIL: Self = Self(c::EADDRNOTAVAIL);
+ /// `EADV`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const ADV: Self = Self(c::EADV);
+ /// `EAFNOSUPPORT`
+ pub const AFNOSUPPORT: Self = Self(c::EAFNOSUPPORT);
+ /// `EAGAIN`
+ pub const AGAIN: Self = Self(c::EAGAIN);
+ /// `EALREADY`
+ pub const ALREADY: Self = Self(c::EALREADY);
+ /// `EAUTH`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const AUTH: Self = Self(c::EAUTH);
+ /// `EBADE`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const BADE: Self = Self(c::EBADE);
+ /// `EBADF`
+ pub const BADF: Self = Self(c::EBADF);
+ /// `EBADFD`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const BADFD: Self = Self(c::EBADFD);
+ /// `EBADMSG`
+ #[cfg(not(windows))]
+ pub const BADMSG: Self = Self(c::EBADMSG);
+ /// `EBADR`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const BADR: Self = Self(c::EBADR);
+ /// `EBADRPC`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const BADRPC: Self = Self(c::EBADRPC);
+ /// `EBADRQC`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const BADRQC: Self = Self(c::EBADRQC);
+ /// `EBADSLT`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const BADSLT: Self = Self(c::EBADSLT);
+ /// `EBFONT`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const BFONT: Self = Self(c::EBFONT);
+ /// `EBUSY`
+ #[cfg(not(windows))]
+ pub const BUSY: Self = Self(c::EBUSY);
+ /// `ECANCELED`
+ pub const CANCELED: Self = Self(c::ECANCELED);
+ /// `ECAPMODE`
+ #[cfg(any(target_os = "freebsd"))]
+ pub const CAPMODE: Self = Self(c::ECAPMODE);
+ /// `ECHILD`
+ #[cfg(not(windows))]
+ pub const CHILD: Self = Self(c::ECHILD);
+ /// `ECHRNG`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const CHRNG: Self = Self(c::ECHRNG);
+ /// `ECOMM`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const COMM: Self = Self(c::ECOMM);
+ /// `ECONNABORTED`
+ pub const CONNABORTED: Self = Self(c::ECONNABORTED);
+ /// `ECONNREFUSED`
+ pub const CONNREFUSED: Self = Self(c::ECONNREFUSED);
+ /// `ECONNRESET`
+ pub const CONNRESET: Self = Self(c::ECONNRESET);
+ /// `EDEADLK`
+ #[cfg(not(windows))]
+ pub const DEADLK: Self = Self(c::EDEADLK);
+ /// `EDEADLOCK`
+ #[cfg(not(any(
+ windows,
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const DEADLOCK: Self = Self(c::EDEADLOCK);
+ /// `EDESTADDRREQ`
+ pub const DESTADDRREQ: Self = Self(c::EDESTADDRREQ);
+ /// `EDISCON`
+ #[cfg(windows)]
+ pub const DISCON: Self = Self(c::EDISCON);
+ /// `EDOM`
+ #[cfg(not(windows))]
+ pub const DOM: Self = Self(c::EDOM);
+ /// `EDOOFUS`
+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
+ pub const DOOFUS: Self = Self(c::EDOOFUS);
+ /// `EDOTDOT`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const DOTDOT: Self = Self(c::EDOTDOT);
+ /// `EDQUOT`
+ pub const DQUOT: Self = Self(c::EDQUOT);
+ /// `EEXIST`
+ #[cfg(not(windows))]
+ pub const EXIST: Self = Self(c::EEXIST);
+ /// `EFAULT`
+ pub const FAULT: Self = Self(c::EFAULT);
+ /// `EFBIG`
+ #[cfg(not(windows))]
+ pub const FBIG: Self = Self(c::EFBIG);
+ /// `EFTYPE`
+ #[cfg(any(
+ target_env = "newlib",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const FTYPE: Self = Self(c::EFTYPE);
+ /// `EHOSTDOWN`
+ #[cfg(not(target_os = "wasi"))]
+ pub const HOSTDOWN: Self = Self(c::EHOSTDOWN);
+ /// `EHOSTUNREACH`
+ pub const HOSTUNREACH: Self = Self(c::EHOSTUNREACH);
+ /// `EHWPOISON`
+ #[cfg(not(any(
+ windows,
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "wasi",
+ )))]
+ pub const HWPOISON: Self = Self(c::EHWPOISON);
+ /// `EIDRM`
+ #[cfg(not(windows))]
+ pub const IDRM: Self = Self(c::EIDRM);
+ /// `EILSEQ`
+ #[cfg(not(windows))]
+ pub const ILSEQ: Self = Self(c::EILSEQ);
+ /// `EINPROGRESS`
+ pub const INPROGRESS: Self = Self(c::EINPROGRESS);
+ /// `EINTR`
+ ///
+ /// For a convenient way to retry system calls that exit with `INTR`, use
+ /// [`retry_on_intr`].
+ ///
+ /// [`retry_on_intr`]: crate::io::retry_on_intr
+ pub const INTR: Self = Self(c::EINTR);
+ /// `EINVAL`
+ pub const INVAL: Self = Self(c::EINVAL);
+ /// `EINVALIDPROCTABLE`
+ #[cfg(windows)]
+ pub const INVALIDPROCTABLE: Self = Self(c::EINVALIDPROCTABLE);
+ /// `EINVALIDPROVIDER`
+ #[cfg(windows)]
+ pub const INVALIDPROVIDER: Self = Self(c::EINVALIDPROVIDER);
+ /// `EIO`
+ #[cfg(not(windows))]
+ pub const IO: Self = Self(c::EIO);
+ /// `EISCONN`
+ pub const ISCONN: Self = Self(c::EISCONN);
+ /// `EISDIR`
+ #[cfg(not(windows))]
+ pub const ISDIR: Self = Self(c::EISDIR);
+ /// `EISNAM`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const ISNAM: Self = Self(c::EISNAM);
+ /// `EKEYEXPIRED`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const KEYEXPIRED: Self = Self(c::EKEYEXPIRED);
+ /// `EKEYREJECTED`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const KEYREJECTED: Self = Self(c::EKEYREJECTED);
+ /// `EKEYREVOKED`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const KEYREVOKED: Self = Self(c::EKEYREVOKED);
+ /// `EL2HLT`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const L2HLT: Self = Self(c::EL2HLT);
+ /// `EL2NSYNC`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const L2NSYNC: Self = Self(c::EL2NSYNC);
+ /// `EL3HLT`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const L3HLT: Self = Self(c::EL3HLT);
+ /// `EL3RST`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const L3RST: Self = Self(c::EL3RST);
+ /// `ELIBACC`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const LIBACC: Self = Self(c::ELIBACC);
+ /// `ELIBBAD`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const LIBBAD: Self = Self(c::ELIBBAD);
+ /// `ELIBEXEC`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const LIBEXEC: Self = Self(c::ELIBEXEC);
+ /// `ELIBMAX`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const LIBMAX: Self = Self(c::ELIBMAX);
+ /// `ELIBSCN`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const LIBSCN: Self = Self(c::ELIBSCN);
+ /// `ELNRNG`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const LNRNG: Self = Self(c::ELNRNG);
+ /// `ELOOP`
+ pub const LOOP: Self = Self(c::ELOOP);
+ /// `EMEDIUMTYPE`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const MEDIUMTYPE: Self = Self(c::EMEDIUMTYPE);
+ /// `EMFILE`
+ pub const MFILE: Self = Self(c::EMFILE);
+ /// `EMLINK`
+ #[cfg(not(windows))]
+ pub const MLINK: Self = Self(c::EMLINK);
+ /// `EMSGSIZE`
+ pub const MSGSIZE: Self = Self(c::EMSGSIZE);
+ /// `EMULTIHOP`
+ #[cfg(not(any(windows, target_os = "openbsd")))]
+ pub const MULTIHOP: Self = Self(c::EMULTIHOP);
+ /// `ENAMETOOLONG`
+ pub const NAMETOOLONG: Self = Self(c::ENAMETOOLONG);
+ /// `ENAVAIL`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NAVAIL: Self = Self(c::ENAVAIL);
+ /// `ENEEDAUTH`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const NEEDAUTH: Self = Self(c::ENEEDAUTH);
+ /// `ENETDOWN`
+ pub const NETDOWN: Self = Self(c::ENETDOWN);
+ /// `ENETRESET`
+ pub const NETRESET: Self = Self(c::ENETRESET);
+ /// `ENETUNREACH`
+ pub const NETUNREACH: Self = Self(c::ENETUNREACH);
+ /// `ENFILE`
+ #[cfg(not(windows))]
+ pub const NFILE: Self = Self(c::ENFILE);
+ /// `ENOANO`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOANO: Self = Self(c::ENOANO);
+ /// `ENOATTR`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const NOATTR: Self = Self(c::ENOATTR);
+ /// `ENOBUFS`
+ pub const NOBUFS: Self = Self(c::ENOBUFS);
+ /// `ENOCSI`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOCSI: Self = Self(c::ENOCSI);
+ /// `ENODATA`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NODATA: Self = Self(c::ENODATA);
+ /// `ENODEV`
+ #[cfg(not(windows))]
+ pub const NODEV: Self = Self(c::ENODEV);
+ /// `ENOENT`
+ #[cfg(not(windows))]
+ pub const NOENT: Self = Self(c::ENOENT);
+ /// `ENOEXEC`
+ #[cfg(not(windows))]
+ pub const NOEXEC: Self = Self(c::ENOEXEC);
+ /// `ENOKEY`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOKEY: Self = Self(c::ENOKEY);
+ /// `ENOLCK`
+ #[cfg(not(windows))]
+ pub const NOLCK: Self = Self(c::ENOLCK);
+ /// `ENOLINK`
+ #[cfg(not(any(windows, target_os = "openbsd")))]
+ pub const NOLINK: Self = Self(c::ENOLINK);
+ /// `ENOMEDIUM`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOMEDIUM: Self = Self(c::ENOMEDIUM);
+ /// `ENOMEM`
+ #[cfg(not(windows))]
+ pub const NOMEM: Self = Self(c::ENOMEM);
+ /// `ENOMORE`
+ #[cfg(windows)]
+ pub const NOMORE: Self = Self(c::ENOMORE);
+ /// `ENOMSG`
+ #[cfg(not(windows))]
+ pub const NOMSG: Self = Self(c::ENOMSG);
+ /// `ENONET`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NONET: Self = Self(c::ENONET);
+ /// `ENOPKG`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOPKG: Self = Self(c::ENOPKG);
+ /// `ENOPROTOOPT`
+ pub const NOPROTOOPT: Self = Self(c::ENOPROTOOPT);
+ /// `ENOSPC`
+ #[cfg(not(windows))]
+ pub const NOSPC: Self = Self(c::ENOSPC);
+ /// `ENOSR`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOSR: Self = Self(c::ENOSR);
+ /// `ENOSTR`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOSTR: Self = Self(c::ENOSTR);
+ /// `ENOSYS`
+ #[cfg(not(windows))]
+ pub const NOSYS: Self = Self(c::ENOSYS);
+ /// `ENOTBLK`
+ #[cfg(not(any(windows, target_os = "wasi")))]
+ pub const NOTBLK: Self = Self(c::ENOTBLK);
+ /// `ENOTCAPABLE`
+ #[cfg(any(target_os = "freebsd", target_os = "wasi"))]
+ pub const NOTCAPABLE: Self = Self(c::ENOTCAPABLE);
+ /// `ENOTCONN`
+ pub const NOTCONN: Self = Self(c::ENOTCONN);
+ /// `ENOTDIR`
+ #[cfg(not(windows))]
+ pub const NOTDIR: Self = Self(c::ENOTDIR);
+ /// `ENOTEMPTY`
+ pub const NOTEMPTY: Self = Self(c::ENOTEMPTY);
+ /// `ENOTNAM`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOTNAM: Self = Self(c::ENOTNAM);
+ /// `ENOTRECOVERABLE`
+ #[cfg(not(any(windows, target_os = "dragonfly", target_os = "netbsd")))]
+ pub const NOTRECOVERABLE: Self = Self(c::ENOTRECOVERABLE);
+ /// `ENOTSOCK`
+ pub const NOTSOCK: Self = Self(c::ENOTSOCK);
+ /// `ENOTSUP`
+ #[cfg(not(any(windows, target_os = "redox")))]
+ pub const NOTSUP: Self = Self(c::ENOTSUP);
+ /// `ENOTTY`
+ #[cfg(not(windows))]
+ pub const NOTTY: Self = Self(c::ENOTTY);
+ /// `ENOTUNIQ`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const NOTUNIQ: Self = Self(c::ENOTUNIQ);
+ /// `ENXIO`
+ #[cfg(not(windows))]
+ pub const NXIO: Self = Self(c::ENXIO);
+ /// `EOPNOTSUPP`
+ pub const OPNOTSUPP: Self = Self(c::EOPNOTSUPP);
+ /// `EOVERFLOW`
+ #[cfg(not(windows))]
+ pub const OVERFLOW: Self = Self(c::EOVERFLOW);
+ /// `EOWNERDEAD`
+ #[cfg(not(any(windows, target_os = "dragonfly", target_os = "netbsd")))]
+ pub const OWNERDEAD: Self = Self(c::EOWNERDEAD);
+ /// `EPERM`
+ #[cfg(not(windows))]
+ pub const PERM: Self = Self(c::EPERM);
+ /// `EPFNOSUPPORT`
+ #[cfg(not(target_os = "wasi"))]
+ pub const PFNOSUPPORT: Self = Self(c::EPFNOSUPPORT);
+ /// `EPIPE`
+ #[cfg(not(windows))]
+ pub const PIPE: Self = Self(c::EPIPE);
+ /// `EPROCLIM`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const PROCLIM: Self = Self(c::EPROCLIM);
+ /// `EPROCUNAVAIL`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const PROCUNAVAIL: Self = Self(c::EPROCUNAVAIL);
+ /// `EPROGMISMATCH`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const PROGMISMATCH: Self = Self(c::EPROGMISMATCH);
+ /// `EPROGUNAVAIL`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const PROGUNAVAIL: Self = Self(c::EPROGUNAVAIL);
+ /// `EPROTO`
+ #[cfg(not(windows))]
+ pub const PROTO: Self = Self(c::EPROTO);
+ /// `EPROTONOSUPPORT`
+ pub const PROTONOSUPPORT: Self = Self(c::EPROTONOSUPPORT);
+ /// `EPROTOTYPE`
+ pub const PROTOTYPE: Self = Self(c::EPROTOTYPE);
+ /// `EPROVIDERFAILEDINIT`
+ #[cfg(windows)]
+ pub const PROVIDERFAILEDINIT: Self = Self(c::EPROVIDERFAILEDINIT);
+ /// `ERANGE`
+ #[cfg(not(windows))]
+ pub const RANGE: Self = Self(c::ERANGE);
+ /// `EREFUSED`
+ #[cfg(windows)]
+ pub const REFUSED: Self = Self(c::EREFUSED);
+ /// `EREMCHG`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const REMCHG: Self = Self(c::EREMCHG);
+ /// `EREMOTE`
+ #[cfg(not(target_os = "wasi"))]
+ pub const REMOTE: Self = Self(c::EREMOTE);
+ /// `EREMOTEIO`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const REMOTEIO: Self = Self(c::EREMOTEIO);
+ /// `ERESTART`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const RESTART: Self = Self(c::ERESTART);
+ /// `ERFKILL`
+ #[cfg(not(any(
+ windows,
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "wasi",
+ )))]
+ pub const RFKILL: Self = Self(c::ERFKILL);
+ /// `EROFS`
+ #[cfg(not(windows))]
+ pub const ROFS: Self = Self(c::EROFS);
+ /// `ERPCMISMATCH`
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ ))]
+ pub const RPCMISMATCH: Self = Self(c::ERPCMISMATCH);
+ /// `ESHUTDOWN`
+ #[cfg(not(target_os = "wasi"))]
+ pub const SHUTDOWN: Self = Self(c::ESHUTDOWN);
+ /// `ESOCKTNOSUPPORT`
+ #[cfg(not(target_os = "wasi"))]
+ pub const SOCKTNOSUPPORT: Self = Self(c::ESOCKTNOSUPPORT);
+ /// `ESPIPE`
+ #[cfg(not(windows))]
+ pub const SPIPE: Self = Self(c::ESPIPE);
+ /// `ESRCH`
+ #[cfg(not(windows))]
+ pub const SRCH: Self = Self(c::ESRCH);
+ /// `ESRMNT`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const SRMNT: Self = Self(c::ESRMNT);
+ /// `ESTALE`
+ pub const STALE: Self = Self(c::ESTALE);
+ /// `ESTRPIPE`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const STRPIPE: Self = Self(c::ESTRPIPE);
+ /// `ETIME`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const TIME: Self = Self(c::ETIME);
+ /// `ETIMEDOUT`
+ pub const TIMEDOUT: Self = Self(c::ETIMEDOUT);
+ /// `E2BIG`
+ #[cfg(not(windows))]
+ #[doc(alias = "2BIG")]
+ pub const TOOBIG: Self = Self(c::E2BIG);
+ /// `ETOOMANYREFS`
+ #[cfg(not(target_os = "wasi"))]
+ pub const TOOMANYREFS: Self = Self(c::ETOOMANYREFS);
+ /// `ETXTBSY`
+ #[cfg(not(windows))]
+ pub const TXTBSY: Self = Self(c::ETXTBSY);
+ /// `EUCLEAN`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const UCLEAN: Self = Self(c::EUCLEAN);
+ /// `EUNATCH`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const UNATCH: Self = Self(c::EUNATCH);
+ /// `EUSERS`
+ #[cfg(not(target_os = "wasi"))]
+ pub const USERS: Self = Self(c::EUSERS);
+ /// `EWOULDBLOCK`
+ pub const WOULDBLOCK: Self = Self(c::EWOULDBLOCK);
+ /// `EXDEV`
+ #[cfg(not(windows))]
+ pub const XDEV: Self = Self(c::EXDEV);
+ /// `EXFULL`
+ #[cfg(not(any(
+ windows,
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "wasi",
+ )))]
+ pub const XFULL: Self = Self(c::EXFULL);
+}
+
+impl Errno {
+ /// Extract an `Errno` value from a `std::io::Error`.
+ ///
+ /// This isn't a `From` conversion because it's expected to be relatively
+ /// uncommon.
+ #[cfg(feature = "std")]
+ #[inline]
+ pub fn from_io_error(io_err: &std::io::Error) -> Option<Self> {
+ io_err
+ .raw_os_error()
+ .and_then(|raw| if raw != 0 { Some(Self(raw)) } else { None })
+ }
+
+ /// Extract the raw OS error number from this error.
+ #[inline]
+ pub const fn raw_os_error(self) -> i32 {
+ self.0
+ }
+
+ /// Construct an `Errno` from a raw OS error number.
+ #[inline]
+ pub const fn from_raw_os_error(raw: i32) -> Self {
+ Self(raw)
+ }
+
+ pub(crate) fn last_os_error() -> Self {
+ Self(errno().0)
+ }
+}
diff --git a/vendor/rustix/src/imp/libc/io/io_slice.rs b/vendor/rustix/src/imp/libc/io/io_slice.rs
new file mode 100644
index 000000000..81c504d25
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/io_slice.rs
@@ -0,0 +1,85 @@
+//! The following is derived from Rust's
+//! library/std/src/sys/unix/io.rs
+//! dca3f1b786efd27be3b325ed1e01e247aa589c3b.
+
+use super::super::c;
+use core::marker::PhantomData;
+use core::slice;
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub struct IoSlice<'a> {
+ vec: c::iovec,
+ _p: PhantomData<&'a [u8]>,
+}
+
+impl<'a> IoSlice<'a> {
+ #[inline]
+ pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
+ IoSlice {
+ vec: c::iovec {
+ iov_base: buf.as_ptr() as *mut u8 as *mut c::c_void,
+ iov_len: buf.len(),
+ },
+ _p: PhantomData,
+ }
+ }
+
+ #[inline]
+ pub fn advance(&mut self, n: usize) {
+ if self.vec.iov_len < n {
+ panic!("advancing IoSlice beyond its length");
+ }
+
+ unsafe {
+ self.vec.iov_len -= n;
+ self.vec.iov_base = self.vec.iov_base.add(n);
+ }
+ }
+
+ #[inline]
+ pub fn as_slice(&self) -> &[u8] {
+ unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+ }
+}
+
+#[repr(transparent)]
+pub struct IoSliceMut<'a> {
+ vec: c::iovec,
+ _p: PhantomData<&'a mut [u8]>,
+}
+
+impl<'a> IoSliceMut<'a> {
+ #[inline]
+ pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
+ IoSliceMut {
+ vec: c::iovec {
+ iov_base: buf.as_mut_ptr() as *mut c::c_void,
+ iov_len: buf.len(),
+ },
+ _p: PhantomData,
+ }
+ }
+
+ #[inline]
+ pub fn advance(&mut self, n: usize) {
+ if self.vec.iov_len < n {
+ panic!("advancing IoSliceMut beyond its length");
+ }
+
+ unsafe {
+ self.vec.iov_len -= n;
+ self.vec.iov_base = self.vec.iov_base.add(n);
+ }
+ }
+
+ #[inline]
+ pub fn as_slice(&self) -> &[u8] {
+ unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+ }
+
+ #[inline]
+ pub fn as_mut_slice(&mut self) -> &mut [u8] {
+ unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+ }
+}
diff --git a/vendor/rustix/src/imp/libc/io/mod.rs b/vendor/rustix/src/imp/libc/io/mod.rs
new file mode 100644
index 000000000..1378adf3d
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/mod.rs
@@ -0,0 +1,13 @@
+pub(crate) mod errno;
+#[cfg(not(windows))]
+#[cfg(not(feature = "std"))]
+pub(crate) mod io_slice;
+pub(crate) mod poll_fd;
+#[cfg(not(windows))]
+pub(crate) mod types;
+
+#[cfg_attr(windows, path = "windows_syscalls.rs")]
+pub(crate) mod syscalls;
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+pub mod epoll;
diff --git a/vendor/rustix/src/imp/libc/io/poll_fd.rs b/vendor/rustix/src/imp/libc/io/poll_fd.rs
new file mode 100644
index 000000000..c516a9309
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/poll_fd.rs
@@ -0,0 +1,136 @@
+use super::super::c;
+use super::super::conv::borrowed_fd;
+#[cfg(windows)]
+use super::super::fd::RawFd;
+use super::super::fd::{AsFd, AsRawFd, BorrowedFd, LibcFd};
+use bitflags::bitflags;
+use core::marker::PhantomData;
+#[cfg(windows)]
+use std::fmt;
+
+bitflags! {
+ /// `POLL*` flags for use with [`poll`].
+ ///
+ /// [`poll`]: crate::io::poll
+ pub struct PollFlags: c::c_short {
+ /// `POLLIN`
+ const IN = c::POLLIN;
+ /// `POLLPRI`
+ #[cfg(not(target_os = "wasi"))]
+ const PRI = c::POLLPRI;
+ /// `POLLOUT`
+ const OUT = c::POLLOUT;
+ /// `POLLRDNORM`
+ #[cfg(not(target_os = "redox"))]
+ const RDNORM = c::POLLRDNORM;
+ /// `POLLWRNORM`
+ #[cfg(not(target_os = "redox"))]
+ const WRNORM = c::POLLWRNORM;
+ /// `POLLRDBAND`
+ #[cfg(not(any(target_os = "redox", target_os = "wasi")))]
+ const RDBAND = c::POLLRDBAND;
+ /// `POLLWRBAND`
+ #[cfg(not(any(target_os = "redox", target_os = "wasi")))]
+ const WRBAND = c::POLLWRBAND;
+ /// `POLLERR`
+ const ERR = c::POLLERR;
+ /// `POLLHUP`
+ const HUP = c::POLLHUP;
+ /// `POLLNVAL`
+ const NVAL = c::POLLNVAL;
+ /// `POLLRDHUP`
+ #[cfg(all(
+ any(target_os = "android", target_os = "linux"),
+ not(any(target_arch = "sparc", target_arch = "sparc64"))),
+ )]
+ const RDHUP = c::POLLRDHUP;
+ }
+}
+
+/// `struct pollfd`—File descriptor and flags for use with [`poll`].
+///
+/// [`poll`]: crate::io::poll
+#[doc(alias = "pollfd")]
+#[derive(Clone)]
+#[cfg_attr(not(windows), derive(Debug))]
+#[repr(transparent)]
+pub struct PollFd<'fd> {
+ pollfd: c::pollfd,
+ _phantom: PhantomData<BorrowedFd<'fd>>,
+}
+
+#[cfg(windows)]
+impl<'fd> fmt::Debug for PollFd<'fd> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_struct("pollfd")
+ .field("fd", &self.pollfd.fd)
+ .field("events", &self.pollfd.events)
+ .field("revents", &self.pollfd.revents)
+ .finish()
+ }
+}
+
+impl<'fd> PollFd<'fd> {
+ /// Constructs a new `PollFd` holding `fd` and `events`.
+ #[inline]
+ pub fn new<Fd: AsFd>(fd: &'fd Fd, events: PollFlags) -> Self {
+ Self::from_borrowed_fd(fd.as_fd(), events)
+ }
+
+ /// Sets the contained file descriptor to `fd`.
+ #[inline]
+ pub fn set_fd<Fd: AsFd>(&mut self, fd: &'fd Fd) {
+ self.pollfd.fd = fd.as_fd().as_raw_fd() as LibcFd;
+ }
+
+ /// Clears the ready events.
+ #[inline]
+ pub fn clear_revents(&mut self) {
+ self.pollfd.revents = 0;
+ }
+
+ /// Constructs a new `PollFd` holding `fd` and `events`.
+ ///
+ /// This is the same as `new`, but can be used to avoid borrowing the
+ /// `BorrowedFd`, which can be tricky in situations where the `BorrowedFd`
+ /// is a temporary.
+ #[inline]
+ pub fn from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self {
+ Self {
+ pollfd: c::pollfd {
+ fd: borrowed_fd(fd),
+ events: events.bits(),
+ revents: 0,
+ },
+ _phantom: PhantomData,
+ }
+ }
+
+ /// Returns the ready events.
+ #[inline]
+ pub fn revents(&self) -> PollFlags {
+ // Use `unwrap()` here because in theory we know we know all the bits
+ // the OS might set here, but OS's have added extensions in the past.
+ PollFlags::from_bits(self.pollfd.revents).unwrap()
+ }
+}
+
+#[cfg(not(windows))]
+impl<'fd> AsFd for PollFd<'fd> {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ // Safety: Our constructors and `set_fd` require `pollfd.fd` to be
+ // valid for the `fd lifetime.
+ unsafe { BorrowedFd::borrow_raw(self.pollfd.fd) }
+ }
+}
+
+#[cfg(windows)]
+impl<'fd> io_lifetimes::AsSocket for PollFd<'fd> {
+ #[inline]
+ fn as_socket(&self) -> BorrowedFd<'_> {
+ // Safety: Our constructors and `set_fd` require `pollfd.fd` to be
+ // valid for the `fd lifetime.
+ unsafe { BorrowedFd::borrow_raw(self.pollfd.fd as RawFd) }
+ }
+}
diff --git a/vendor/rustix/src/imp/libc/io/syscalls.rs b/vendor/rustix/src/imp/libc/io/syscalls.rs
new file mode 100644
index 000000000..4fafbfd66
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/syscalls.rs
@@ -0,0 +1,456 @@
+//! libc syscalls supporting `rustix::io`.
+
+use super::super::c;
+#[cfg(any(target_os = "android", target_os = "linux"))]
+use super::super::conv::syscall_ret_owned_fd;
+use super::super::conv::{
+ borrowed_fd, ret, ret_c_int, ret_discarded_fd, ret_owned_fd, ret_ssize_t,
+};
+use super::super::offset::{libc_pread, libc_pwrite};
+#[cfg(not(target_os = "redox"))]
+use super::super::offset::{libc_preadv, libc_pwritev};
+#[cfg(all(target_os = "linux", target_env = "gnu"))]
+use super::super::offset::{libc_preadv2, libc_pwritev2};
+use crate::fd::{AsFd, BorrowedFd, RawFd};
+#[cfg(not(target_os = "wasi"))]
+use crate::io::DupFlags;
+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))]
+use crate::io::PipeFlags;
+use crate::io::{self, IoSlice, IoSliceMut, OwnedFd, PollFd};
+#[cfg(any(target_os = "android", target_os = "linux"))]
+use crate::io::{EventfdFlags, ReadWriteFlags};
+use core::cmp::min;
+use core::convert::TryInto;
+use core::mem::MaybeUninit;
+#[cfg(feature = "net")]
+use libc_errno::errno;
+
+pub(crate) fn read(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> {
+ let nread = unsafe {
+ ret_ssize_t(c::read(
+ borrowed_fd(fd),
+ buf.as_mut_ptr().cast(),
+ min(buf.len(), READ_LIMIT),
+ ))?
+ };
+ Ok(nread as usize)
+}
+
+pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result<usize> {
+ let nwritten = unsafe {
+ ret_ssize_t(c::write(
+ borrowed_fd(fd),
+ buf.as_ptr().cast(),
+ min(buf.len(), READ_LIMIT),
+ ))?
+ };
+ Ok(nwritten as usize)
+}
+
+pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Result<usize> {
+ let len = min(buf.len(), READ_LIMIT);
+
+ // Silently cast; we'll get `EINVAL` if the value is negative.
+ let offset = offset as i64;
+
+ let nread = unsafe {
+ ret_ssize_t(libc_pread(
+ borrowed_fd(fd),
+ buf.as_mut_ptr().cast(),
+ len,
+ offset,
+ ))?
+ };
+ Ok(nread as usize)
+}
+
+pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result<usize> {
+ let len = min(buf.len(), READ_LIMIT);
+
+ // Silently cast; we'll get `EINVAL` if the value is negative.
+ let offset = offset as i64;
+
+ let nwritten = unsafe {
+ ret_ssize_t(libc_pwrite(
+ borrowed_fd(fd),
+ buf.as_ptr().cast(),
+ len,
+ offset,
+ ))?
+ };
+ Ok(nwritten as usize)
+}
+
+pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut]) -> io::Result<usize> {
+ let nread = unsafe {
+ ret_ssize_t(c::readv(
+ borrowed_fd(fd),
+ bufs.as_ptr().cast::<c::iovec>(),
+ min(bufs.len(), max_iov()) as c::c_int,
+ ))?
+ };
+ Ok(nread as usize)
+}
+
+pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice]) -> io::Result<usize> {
+ let nwritten = unsafe {
+ ret_ssize_t(c::writev(
+ borrowed_fd(fd),
+ bufs.as_ptr().cast::<c::iovec>(),
+ min(bufs.len(), max_iov()) as c::c_int,
+ ))?
+ };
+ Ok(nwritten as usize)
+}
+
+#[cfg(not(target_os = "redox"))]
+pub(crate) fn preadv(
+ fd: BorrowedFd<'_>,
+ bufs: &mut [IoSliceMut],
+ offset: u64,
+) -> io::Result<usize> {
+ // Silently cast; we'll get `EINVAL` if the value is negative.
+ let offset = offset as i64;
+ let nread = unsafe {
+ ret_ssize_t(libc_preadv(
+ borrowed_fd(fd),
+ bufs.as_ptr().cast::<c::iovec>(),
+ min(bufs.len(), max_iov()) as c::c_int,
+ offset,
+ ))?
+ };
+ Ok(nread as usize)
+}
+
+#[cfg(not(target_os = "redox"))]
+pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
+ // Silently cast; we'll get `EINVAL` if the value is negative.
+ let offset = offset as i64;
+ let nwritten = unsafe {
+ ret_ssize_t(libc_pwritev(
+ borrowed_fd(fd),
+ bufs.as_ptr().cast::<c::iovec>(),
+ min(bufs.len(), max_iov()) as c::c_int,
+ offset,
+ ))?
+ };
+ Ok(nwritten as usize)
+}
+
+#[cfg(all(target_os = "linux", target_env = "gnu"))]
+pub(crate) fn preadv2(
+ fd: BorrowedFd<'_>,
+ bufs: &mut [IoSliceMut],
+ offset: u64,
+ flags: ReadWriteFlags,
+) -> io::Result<usize> {
+ // Silently cast; we'll get `EINVAL` if the value is negative.
+ let offset = offset as i64;
+ let nread = unsafe {
+ ret_ssize_t(libc_preadv2(
+ borrowed_fd(fd),
+ bufs.as_ptr().cast::<c::iovec>(),
+ min(bufs.len(), max_iov()) as c::c_int,
+ offset,
+ flags.bits(),
+ ))?
+ };
+ Ok(nread as usize)
+}
+
+/// At present, `libc` only has `preadv2` defined for glibc. On other
+/// ABIs, `ReadWriteFlags` has no flags defined, and we use plain `preadv`.
+#[cfg(any(
+ target_os = "android",
+ all(target_os = "linux", not(target_env = "gnu")),
+))]
+#[inline]
+pub(crate) fn preadv2(
+ fd: BorrowedFd<'_>,
+ bufs: &mut [IoSliceMut],
+ offset: u64,
+ flags: ReadWriteFlags,
+) -> io::Result<usize> {
+ assert!(flags.is_empty());
+ preadv(fd, bufs, offset)
+}
+
+#[cfg(all(target_os = "linux", target_env = "gnu"))]
+pub(crate) fn pwritev2(
+ fd: BorrowedFd<'_>,
+ bufs: &[IoSlice],
+ offset: u64,
+ flags: ReadWriteFlags,
+) -> io::Result<usize> {
+ // Silently cast; we'll get `EINVAL` if the value is negative.
+ let offset = offset as i64;
+ let nwritten = unsafe {
+ ret_ssize_t(libc_pwritev2(
+ borrowed_fd(fd),
+ bufs.as_ptr().cast::<c::iovec>(),
+ min(bufs.len(), max_iov()) as c::c_int,
+ offset,
+ flags.bits(),
+ ))?
+ };
+ Ok(nwritten as usize)
+}
+
+/// At present, `libc` only has `pwritev2` defined for glibc. On other
+/// ABIs, `ReadWriteFlags` has no flags defined, and we use plain `pwritev`.
+#[cfg(any(
+ target_os = "android",
+ all(target_os = "linux", not(target_env = "gnu")),
+))]
+#[inline]
+pub(crate) fn pwritev2(
+ fd: BorrowedFd<'_>,
+ bufs: &[IoSlice],
+ offset: u64,
+ flags: ReadWriteFlags,
+) -> io::Result<usize> {
+ assert!(flags.is_empty());
+ pwritev(fd, bufs, offset)
+}
+
+// These functions are derived from Rust's library/std/src/sys/unix/fd.rs at
+// revision a77da2d454e6caa227a85b16410b95f93495e7e0.
+
+// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`, with the
+// man page quoting that if the count of bytes to read is greater than
+// `SSIZE_MAX` the result is "unspecified".
+//
+// On macOS, however, apparently the 64-bit libc is either buggy or
+// intentionally showing odd behavior by rejecting any read with a size larger
+// than or equal to `INT_MAX`. To handle both of these the read size is capped
+// on both platforms.
+#[cfg(target_os = "macos")]
+const READ_LIMIT: usize = c::c_int::MAX as usize - 1;
+#[cfg(not(target_os = "macos"))]
+const READ_LIMIT: usize = c::ssize_t::MAX as usize;
+
+#[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+))]
+const fn max_iov() -> usize {
+ c::IOV_MAX as usize
+}
+
+#[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
+const fn max_iov() -> usize {
+ c::UIO_MAXIOV as usize
+}
+
+#[cfg(not(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "emscripten",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+)))]
+const fn max_iov() -> usize {
+ 16 // The minimum value required by POSIX.
+}
+
+pub(crate) unsafe fn close(raw_fd: RawFd) {
+ let _ = c::close(raw_fd as c::c_int);
+}
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> {
+ unsafe { syscall_ret_owned_fd(c::syscall(c::SYS_eventfd2, initval, flags.bits())) }
+}
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+#[inline]
+pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result<u32> {
+ let mut result = MaybeUninit::<c::c_uint>::uninit();
+ unsafe {
+ ret(c::ioctl(borrowed_fd(fd), c::BLKSSZGET, result.as_mut_ptr()))?;
+ Ok(result.assume_init() as u32)
+ }
+}
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+#[inline]
+pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> {
+ let mut result = MaybeUninit::<c::c_uint>::uninit();
+ unsafe {
+ ret(c::ioctl(
+ borrowed_fd(fd),
+ c::BLKPBSZGET,
+ result.as_mut_ptr(),
+ ))?;
+ Ok(result.assume_init() as u32)
+ }
+}
+
+#[cfg(not(target_os = "redox"))]
+pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> {
+ let mut nread = MaybeUninit::<c::c_int>::uninit();
+ unsafe {
+ ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?;
+ // `FIONREAD` returns the number of bytes silently casted to a `c_int`,
+ // even when this is lossy. The best we can do is convert it back to a
+ // `u64` without sign-extending it back first.
+ Ok(u64::from(nread.assume_init() as c::c_uint))
+ }
+}
+
+pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> {
+ unsafe {
+ let data = value as c::c_int;
+ ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &data))
+ }
+}
+
+#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
+#[cfg(feature = "net")]
+pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
+ let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?;
+ let mut not_socket = false;
+ if read {
+ // Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates
+ // the read side is shut down; an `EWOULDBLOCK` indicates the read
+ // side is still open.
+ match unsafe {
+ c::recv(
+ borrowed_fd(fd),
+ MaybeUninit::<[u8; 1]>::uninit()
+ .as_mut_ptr()
+ .cast::<c::c_void>(),
+ 1,
+ c::MSG_PEEK | c::MSG_DONTWAIT,
+ )
+ } {
+ 0 => read = false,
+ -1 => {
+ #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK`
+ match errno().0 {
+ c::EAGAIN | c::EWOULDBLOCK => (),
+ c::ENOTSOCK => not_socket = true,
+ err => return Err(io::Errno(err)),
+ }
+ }
+ _ => (),
+ }
+ }
+ if write && !not_socket {
+ // Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates
+ // the write side is shut down.
+ if unsafe { c::send(borrowed_fd(fd), [].as_ptr(), 0, c::MSG_DONTWAIT) } == -1 {
+ #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK`
+ match errno().0 {
+ c::EAGAIN | c::EWOULDBLOCK => (),
+ c::ENOTSOCK => (),
+ c::EPIPE => write = false,
+ err => return Err(io::Errno(err)),
+ }
+ }
+ }
+ Ok((read, write))
+}
+
+#[cfg(target_os = "wasi")]
+#[cfg(feature = "net")]
+pub(crate) fn is_read_write(_fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> {
+ todo!("Implement is_read_write for WASI in terms of fd_fdstat_get");
+}
+
+#[cfg(not(target_os = "wasi"))]
+pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> {
+ unsafe { ret_owned_fd(c::dup(borrowed_fd(fd))) }
+}
+
+#[cfg(not(target_os = "wasi"))]
+pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> {
+ unsafe { ret_discarded_fd(c::dup2(borrowed_fd(fd), borrowed_fd(new.as_fd()))) }
+}
+
+#[cfg(not(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+ target_os = "wasi",
+)))]
+pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> {
+ unsafe {
+ ret_discarded_fd(c::dup3(
+ borrowed_fd(fd),
+ borrowed_fd(new.as_fd()),
+ flags.bits(),
+ ))
+ }
+}
+
+#[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+))]
+pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, _flags: DupFlags) -> io::Result<()> {
+ // Android 5.0 has `dup3`, but libc doesn't have bindings. Emulate it
+ // using `dup2`. We don't need to worry about the difference between
+ // `dup2` and `dup3` when the file descriptors are equal because we
+ // have an `&mut OwnedFd` which means `fd` doesn't alias it.
+ dup2(fd, new)
+}
+
+#[cfg(any(target_os = "ios", target_os = "macos"))]
+pub(crate) fn ioctl_fioclex(fd: BorrowedFd<'_>) -> io::Result<()> {
+ unsafe { ret(c::ioctl(borrowed_fd(fd), c::FIOCLEX)) }
+}
+
+#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
+pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd) -> io::Result<()> {
+ unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCEXCL as _)) }
+}
+
+#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
+pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd) -> io::Result<()> {
+ unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCNXCL as _)) }
+}
+
+#[cfg(not(target_os = "wasi"))]
+pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> {
+ unsafe {
+ let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
+ ret(c::pipe(result.as_mut_ptr().cast::<i32>()))?;
+ let [p0, p1] = result.assume_init();
+ Ok((p0, p1))
+ }
+}
+
+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))]
+pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> {
+ unsafe {
+ let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
+ ret(c::pipe2(result.as_mut_ptr().cast::<i32>(), flags.bits()))?;
+ let [p0, p1] = result.assume_init();
+ Ok((p0, p1))
+ }
+}
+
+#[inline]
+pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> {
+ let nfds = fds
+ .len()
+ .try_into()
+ .map_err(|_convert_err| io::Errno::INVAL)?;
+
+ ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) })
+ .map(|nready| nready as usize)
+}
diff --git a/vendor/rustix/src/imp/libc/io/types.rs b/vendor/rustix/src/imp/libc/io/types.rs
new file mode 100644
index 000000000..483f3a6af
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/types.rs
@@ -0,0 +1,89 @@
+use super::super::c;
+#[cfg(not(target_os = "wasi"))]
+use bitflags::bitflags;
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+bitflags! {
+ /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`].
+ ///
+ /// [`preadv2`]: crate::io::preadv2
+ /// [`pwritev2`]: crate::io::pwritev
+ pub struct ReadWriteFlags: c::c_int {
+ /// `RWF_DSYNC` (since Linux 4.7)
+ #[cfg(all(target_os = "linux", target_env = "gnu"))]
+ const DSYNC = c::RWF_DSYNC;
+ /// `RWF_HIPRI` (since Linux 4.6)
+ #[cfg(all(target_os = "linux", target_env = "gnu"))]
+ const HIPRI = c::RWF_HIPRI;
+ /// `RWF_SYNC` (since Linux 4.7)
+ #[cfg(all(target_os = "linux", target_env = "gnu"))]
+ const SYNC = c::RWF_SYNC;
+ /// `RWF_NOWAIT` (since Linux 4.14)
+ #[cfg(all(target_os = "linux", target_env = "gnu"))]
+ const NOWAIT = c::RWF_NOWAIT;
+ /// `RWF_APPEND` (since Linux 4.16)
+ #[cfg(all(target_os = "linux", target_env = "gnu"))]
+ const APPEND = c::RWF_APPEND;
+ }
+}
+
+#[cfg(not(target_os = "wasi"))]
+bitflags! {
+ /// `O_*` constants for use with [`dup2`].
+ ///
+ /// [`dup2`]: crate::io::dup2
+ pub struct DupFlags: c::c_int {
+ /// `O_CLOEXEC`
+ #[cfg(not(any(
+ target_os = "android",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+ )))] // Android 5.0 has dup3, but libc doesn't have bindings
+ const CLOEXEC = c::O_CLOEXEC;
+ }
+}
+
+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))]
+bitflags! {
+ /// `O_*` constants for use with [`pipe_with`].
+ ///
+ /// [`pipe_with`]: crate::io::pipe_with
+ pub struct PipeFlags: c::c_int {
+ /// `O_CLOEXEC`
+ const CLOEXEC = c::O_CLOEXEC;
+ /// `O_DIRECT`
+ #[cfg(not(any(target_os = "illumos", target_os = "openbsd", target_os = "redox")))]
+ const DIRECT = c::O_DIRECT;
+ /// `O_NONBLOCK`
+ const NONBLOCK = c::O_NONBLOCK;
+ }
+}
+
+#[cfg(any(target_os = "android", target_os = "linux"))]
+bitflags! {
+ /// `EFD_*` flags for use with [`eventfd`].
+ ///
+ /// [`eventfd`]: crate::io::eventfd
+ pub struct EventfdFlags: c::c_int {
+ /// `EFD_CLOEXEC`
+ const CLOEXEC = c::EFD_CLOEXEC;
+ /// `EFD_NONBLOCK`
+ const NONBLOCK = c::EFD_NONBLOCK;
+ /// `EFD_SEMAPHORE`
+ const SEMAPHORE = c::EFD_SEMAPHORE;
+ }
+}
+
+/// `PIPE_BUF`—The maximum size of a write to a pipe guaranteed to be atomic.
+#[cfg(not(any(target_os = "illumos", target_os = "redox", target_os = "wasi")))]
+pub const PIPE_BUF: usize = c::PIPE_BUF;
+
+#[cfg(not(any(windows, target_os = "redox")))]
+pub(crate) const AT_FDCWD: c::c_int = c::AT_FDCWD;
+#[cfg(not(windows))]
+pub(crate) const STDIN_FILENO: c::c_int = c::STDIN_FILENO;
+#[cfg(not(windows))]
+pub(crate) const STDOUT_FILENO: c::c_int = c::STDOUT_FILENO;
+#[cfg(not(windows))]
+pub(crate) const STDERR_FILENO: c::c_int = c::STDERR_FILENO;
diff --git a/vendor/rustix/src/imp/libc/io/windows_syscalls.rs b/vendor/rustix/src/imp/libc/io/windows_syscalls.rs
new file mode 100644
index 000000000..4c6e86f94
--- /dev/null
+++ b/vendor/rustix/src/imp/libc/io/windows_syscalls.rs
@@ -0,0 +1,39 @@
+//! Windows system calls in the `io` module.
+
+use super::super::c;
+use super::super::conv::{borrowed_fd, ret, ret_c_int};
+use super::super::fd::LibcFd;
+use crate::fd::{BorrowedFd, RawFd};
+use crate::io;
+use crate::io::PollFd;
+use core::convert::TryInto;
+use core::mem::MaybeUninit;
+
+pub(crate) unsafe fn close(raw_fd: RawFd) {
+ let _ = c::close(raw_fd as LibcFd);
+}
+
+pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> {
+ let mut nread = MaybeUninit::<c::c_ulong>::uninit();
+ unsafe {
+ ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?;
+ Ok(u64::from(nread.assume_init()))
+ }
+}
+
+pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> {
+ unsafe {
+ let mut data = value as c::c_uint;
+ ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &mut data))
+ }
+}
+
+pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> {
+ let nfds = fds
+ .len()
+ .try_into()
+ .map_err(|_convert_err| io::Errno::INVAL)?;
+
+ ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) })
+ .map(|nready| nready as usize)
+}