summaryrefslogtreecommitdiff
path: root/vendor/rustix/src/backend/linux_raw/io
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2024-01-08 00:21:28 +0300
committerValentin Popov <valentin@popov.link>2024-01-08 00:21:28 +0300
commit1b6a04ca5504955c571d1c97504fb45ea0befee4 (patch)
tree7579f518b23313e8a9748a88ab6173d5e030b227 /vendor/rustix/src/backend/linux_raw/io
parent5ecd8cf2cba827454317368b68571df0d13d7842 (diff)
downloadfparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.tar.xz
fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.zip
Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/io')
-rw-r--r--vendor/rustix/src/backend/linux_raw/io/errno.rs553
-rw-r--r--vendor/rustix/src/backend/linux_raw/io/mod.rs3
-rw-r--r--vendor/rustix/src/backend/linux_raw/io/syscalls.rs379
-rw-r--r--vendor/rustix/src/backend/linux_raw/io/types.rs57
4 files changed, 992 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs
new file mode 100644
index 0000000..bc40e9a
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/io/errno.rs
@@ -0,0 +1,553 @@
+//! The `rustix` `Errno` type.
+//!
+//! This type holds an OS error code, which conceptually corresponds to an
+//! `errno` value.
+//!
+//! # Safety
+//!
+//! Linux uses error codes in `-4095..0`; we use rustc attributes to describe
+//! this restricted range of values.
+#![allow(unsafe_code)]
+#![cfg_attr(not(rustc_attrs), allow(unused_unsafe))]
+
+use crate::backend::c;
+use crate::backend::fd::RawFd;
+use crate::backend::reg::{RetNumber, RetReg};
+use crate::io;
+use linux_raw_sys::errno;
+
+/// `errno`—An error code.
+///
+/// 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.
+///
+/// # References
+/// - [POSIX]
+/// - [Linux]
+/// - [Winsock]
+/// - [FreeBSD]
+/// - [NetBSD]
+/// - [OpenBSD]
+/// - [DragonFly BSD]
+/// - [illumos]
+/// - [glibc]
+///
+/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html
+/// [Linux]: https://man7.org/linux/man-pages/man3/errno.3.html
+/// [Winsock]: https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
+/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?errno
+/// [NetBSD]: https://man.netbsd.org/errno.2
+/// [OpenBSD]: https://man.openbsd.org/errno.2
+/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=errno&section=2
+/// [illumos]: https://illumos.org/man/3C/errno
+/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html
+/// [`std::io::Error`]: Result
+#[repr(transparent)]
+#[doc(alias = "errno")]
+#[derive(Eq, PartialEq, Hash, Copy, Clone)]
+// Linux returns negated error codes, and we leave them in negated form, so
+// error codes are in `-4095..0`.
+#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0xf001))]
+#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xffff))]
+pub struct Errno(u16);
+
+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| {
+ // `std::io::Error` could theoretically have arbitrary OS error
+ // values, so check that they're in Linux's range.
+ if (1..4096).contains(&raw) {
+ Some(Self::from_errno(raw as u32))
+ } else {
+ None
+ }
+ })
+ }
+
+ /// Extract the raw OS error number from this error.
+ #[inline]
+ pub const fn raw_os_error(self) -> i32 {
+ (self.0 as i16 as i32).wrapping_neg()
+ }
+
+ /// Construct an `Errno` from a raw OS error number.
+ #[inline]
+ pub const fn from_raw_os_error(raw: i32) -> Self {
+ Self::from_errno(raw as u32)
+ }
+
+ /// Convert from a C `errno` value (which is positive) to an `Errno`.
+ const fn from_errno(raw: u32) -> Self {
+ // We store error values in negated form, so that we don't have to
+ // negate them after every syscall.
+ let encoded = raw.wrapping_neg() as u16;
+
+ // TODO: Use Range::contains, once that's `const`.
+ assert!(encoded >= 0xf001);
+
+ // SAFETY: Linux syscalls return negated error values in the range
+ // `-4095..0`, which we just asserted.
+ unsafe { Self(encoded) }
+ }
+}
+
+/// Check for an error from the result of a syscall which encodes a
+/// `c::c_int` on success.
+#[inline]
+pub(in crate::backend) fn try_decode_c_int<Num: RetNumber>(
+ raw: RetReg<Num>,
+) -> io::Result<c::c_int> {
+ if raw.is_in_range(-4095..0) {
+ // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
+ // in that range.
+ return Err(unsafe { Errno(raw.decode_error_code()) });
+ }
+
+ Ok(raw.decode_c_int())
+}
+
+/// Check for an error from the result of a syscall which encodes a
+/// `c::c_uint` on success.
+#[inline]
+pub(in crate::backend) fn try_decode_c_uint<Num: RetNumber>(
+ raw: RetReg<Num>,
+) -> io::Result<c::c_uint> {
+ if raw.is_in_range(-4095..0) {
+ // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
+ // in that range.
+ return Err(unsafe { Errno(raw.decode_error_code()) });
+ }
+
+ Ok(raw.decode_c_uint())
+}
+
+/// Check for an error from the result of a syscall which encodes a `usize` on
+/// success.
+#[inline]
+pub(in crate::backend) fn try_decode_usize<Num: RetNumber>(raw: RetReg<Num>) -> io::Result<usize> {
+ if raw.is_in_range(-4095..0) {
+ // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
+ // in that range.
+ return Err(unsafe { Errno(raw.decode_error_code()) });
+ }
+
+ Ok(raw.decode_usize())
+}
+
+/// Check for an error from the result of a syscall which encodes a
+/// `*mut c_void` on success.
+#[inline]
+pub(in crate::backend) fn try_decode_void_star<Num: RetNumber>(
+ raw: RetReg<Num>,
+) -> io::Result<*mut c::c_void> {
+ if raw.is_in_range(-4095..0) {
+ // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
+ // in that range.
+ return Err(unsafe { Errno(raw.decode_error_code()) });
+ }
+
+ Ok(raw.decode_void_star())
+}
+
+/// Check for an error from the result of a syscall which encodes a
+/// `u64` on success.
+#[cfg(target_pointer_width = "64")]
+#[inline]
+pub(in crate::backend) fn try_decode_u64<Num: RetNumber>(raw: RetReg<Num>) -> io::Result<u64> {
+ if raw.is_in_range(-4095..0) {
+ // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
+ // in that range.
+ return Err(unsafe { Errno(raw.decode_error_code()) });
+ }
+
+ Ok(raw.decode_u64())
+}
+
+/// Check for an error from the result of a syscall which encodes a file
+/// descriptor on success.
+///
+/// # Safety
+///
+/// This must only be used with syscalls which return file descriptors on
+/// success.
+#[inline]
+pub(in crate::backend) unsafe fn try_decode_raw_fd<Num: RetNumber>(
+ raw: RetReg<Num>,
+) -> io::Result<RawFd> {
+ // Instead of using `check_result` here, we just check for negative, since
+ // this function is only used for system calls which return file
+ // descriptors, and this produces smaller code.
+ if raw.is_negative() {
+ debug_assert!(raw.is_in_range(-4095..0));
+
+ // Tell the optimizer that we know the value is in the error range.
+ // This helps it avoid unnecessary integer conversions.
+ #[cfg(core_intrinsics)]
+ {
+ core::intrinsics::assume(raw.is_in_range(-4095..0));
+ }
+
+ return Err(Errno(raw.decode_error_code()));
+ }
+
+ Ok(raw.decode_raw_fd())
+}
+
+/// Check for an error from the result of a syscall which encodes no value on
+/// success. On success, return the unconsumed `raw` value.
+///
+/// # Safety
+///
+/// This must only be used with syscalls which return no value on success.
+#[inline]
+pub(in crate::backend) unsafe fn try_decode_void<Num: RetNumber>(
+ raw: RetReg<Num>,
+) -> io::Result<()> {
+ // Instead of using `check_result` here, we just check for zero, since this
+ // function is only used for system calls which have no other return value,
+ // and this produces smaller code.
+ if raw.is_nonzero() {
+ debug_assert!(raw.is_in_range(-4095..0));
+
+ // Tell the optimizer that we know the value is in the error range.
+ // This helps it avoid unnecessary integer conversions.
+ #[cfg(core_intrinsics)]
+ {
+ core::intrinsics::assume(raw.is_in_range(-4095..0));
+ }
+
+ return Err(Errno(raw.decode_error_code()));
+ }
+
+ raw.decode_void();
+
+ Ok(())
+}
+
+/// Check for an error from the result of a syscall which does not return on
+/// success. On success, return the unconsumed `raw` value.
+///
+/// # Safety
+///
+/// This must only be used with syscalls which do not return on success.
+#[cfg(any(feature = "event", feature = "runtime"))]
+#[inline]
+pub(in crate::backend) unsafe fn try_decode_error<Num: RetNumber>(raw: RetReg<Num>) -> io::Errno {
+ debug_assert!(raw.is_in_range(-4095..0));
+
+ // Tell the optimizer that we know the value is in the error range.
+ // This helps it avoid unnecessary integer conversions.
+ #[cfg(core_intrinsics)]
+ {
+ core::intrinsics::assume(raw.is_in_range(-4095..0));
+ }
+
+ Errno(raw.decode_error_code())
+}
+
+/// Return the contained `usize` value.
+#[cfg(not(debug_assertions))]
+#[inline]
+pub(in crate::backend) fn decode_usize_infallible<Num: RetNumber>(raw: RetReg<Num>) -> usize {
+ raw.decode_usize()
+}
+
+/// Return the contained `c_int` value.
+#[cfg(not(debug_assertions))]
+#[inline]
+pub(in crate::backend) fn decode_c_int_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_int {
+ raw.decode_c_int()
+}
+
+/// Return the contained `c_uint` value.
+#[cfg(not(debug_assertions))]
+#[inline]
+pub(in crate::backend) fn decode_c_uint_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_uint {
+ raw.decode_c_uint()
+}
+
+impl Errno {
+ /// `EACCES`
+ #[doc(alias = "ACCES")]
+ pub const ACCESS: Self = Self::from_errno(errno::EACCES);
+ /// `EADDRINUSE`
+ pub const ADDRINUSE: Self = Self::from_errno(errno::EADDRINUSE);
+ /// `EADDRNOTAVAIL`
+ pub const ADDRNOTAVAIL: Self = Self::from_errno(errno::EADDRNOTAVAIL);
+ /// `EADV`
+ pub const ADV: Self = Self::from_errno(errno::EADV);
+ /// `EAFNOSUPPORT`
+ pub const AFNOSUPPORT: Self = Self::from_errno(errno::EAFNOSUPPORT);
+ /// `EAGAIN`
+ pub const AGAIN: Self = Self::from_errno(errno::EAGAIN);
+ /// `EALREADY`
+ pub const ALREADY: Self = Self::from_errno(errno::EALREADY);
+ /// `EBADE`
+ pub const BADE: Self = Self::from_errno(errno::EBADE);
+ /// `EBADF`
+ pub const BADF: Self = Self::from_errno(errno::EBADF);
+ /// `EBADFD`
+ pub const BADFD: Self = Self::from_errno(errno::EBADFD);
+ /// `EBADMSG`
+ pub const BADMSG: Self = Self::from_errno(errno::EBADMSG);
+ /// `EBADR`
+ pub const BADR: Self = Self::from_errno(errno::EBADR);
+ /// `EBADRQC`
+ pub const BADRQC: Self = Self::from_errno(errno::EBADRQC);
+ /// `EBADSLT`
+ pub const BADSLT: Self = Self::from_errno(errno::EBADSLT);
+ /// `EBFONT`
+ pub const BFONT: Self = Self::from_errno(errno::EBFONT);
+ /// `EBUSY`
+ pub const BUSY: Self = Self::from_errno(errno::EBUSY);
+ /// `ECANCELED`
+ pub const CANCELED: Self = Self::from_errno(errno::ECANCELED);
+ /// `ECHILD`
+ pub const CHILD: Self = Self::from_errno(errno::ECHILD);
+ /// `ECHRNG`
+ pub const CHRNG: Self = Self::from_errno(errno::ECHRNG);
+ /// `ECOMM`
+ pub const COMM: Self = Self::from_errno(errno::ECOMM);
+ /// `ECONNABORTED`
+ pub const CONNABORTED: Self = Self::from_errno(errno::ECONNABORTED);
+ /// `ECONNREFUSED`
+ pub const CONNREFUSED: Self = Self::from_errno(errno::ECONNREFUSED);
+ /// `ECONNRESET`
+ pub const CONNRESET: Self = Self::from_errno(errno::ECONNRESET);
+ /// `EDEADLK`
+ pub const DEADLK: Self = Self::from_errno(errno::EDEADLK);
+ /// `EDEADLOCK`
+ pub const DEADLOCK: Self = Self::from_errno(errno::EDEADLOCK);
+ /// `EDESTADDRREQ`
+ pub const DESTADDRREQ: Self = Self::from_errno(errno::EDESTADDRREQ);
+ /// `EDOM`
+ pub const DOM: Self = Self::from_errno(errno::EDOM);
+ /// `EDOTDOT`
+ pub const DOTDOT: Self = Self::from_errno(errno::EDOTDOT);
+ /// `EDQUOT`
+ pub const DQUOT: Self = Self::from_errno(errno::EDQUOT);
+ /// `EEXIST`
+ pub const EXIST: Self = Self::from_errno(errno::EEXIST);
+ /// `EFAULT`
+ pub const FAULT: Self = Self::from_errno(errno::EFAULT);
+ /// `EFBIG`
+ pub const FBIG: Self = Self::from_errno(errno::EFBIG);
+ /// `EHOSTDOWN`
+ pub const HOSTDOWN: Self = Self::from_errno(errno::EHOSTDOWN);
+ /// `EHOSTUNREACH`
+ pub const HOSTUNREACH: Self = Self::from_errno(errno::EHOSTUNREACH);
+ /// `EHWPOISON`
+ pub const HWPOISON: Self = Self::from_errno(errno::EHWPOISON);
+ /// `EIDRM`
+ pub const IDRM: Self = Self::from_errno(errno::EIDRM);
+ /// `EILSEQ`
+ pub const ILSEQ: Self = Self::from_errno(errno::EILSEQ);
+ /// `EINPROGRESS`
+ pub const INPROGRESS: Self = Self::from_errno(errno::EINPROGRESS);
+ /// `EINTR`.
+ ///
+ /// For a convenient way to retry system calls that exit with `INTR`, use
+ /// [`retry_on_intr`].
+ ///
+ /// [`retry_on_intr`]: io::retry_on_intr
+ pub const INTR: Self = Self::from_errno(errno::EINTR);
+ /// `EINVAL`
+ pub const INVAL: Self = Self::from_errno(errno::EINVAL);
+ /// `EIO`
+ pub const IO: Self = Self::from_errno(errno::EIO);
+ /// `EISCONN`
+ pub const ISCONN: Self = Self::from_errno(errno::EISCONN);
+ /// `EISDIR`
+ pub const ISDIR: Self = Self::from_errno(errno::EISDIR);
+ /// `EISNAM`
+ pub const ISNAM: Self = Self::from_errno(errno::EISNAM);
+ /// `EKEYEXPIRED`
+ pub const KEYEXPIRED: Self = Self::from_errno(errno::EKEYEXPIRED);
+ /// `EKEYREJECTED`
+ pub const KEYREJECTED: Self = Self::from_errno(errno::EKEYREJECTED);
+ /// `EKEYREVOKED`
+ pub const KEYREVOKED: Self = Self::from_errno(errno::EKEYREVOKED);
+ /// `EL2HLT`
+ pub const L2HLT: Self = Self::from_errno(errno::EL2HLT);
+ /// `EL2NSYNC`
+ pub const L2NSYNC: Self = Self::from_errno(errno::EL2NSYNC);
+ /// `EL3HLT`
+ pub const L3HLT: Self = Self::from_errno(errno::EL3HLT);
+ /// `EL3RST`
+ pub const L3RST: Self = Self::from_errno(errno::EL3RST);
+ /// `ELIBACC`
+ pub const LIBACC: Self = Self::from_errno(errno::ELIBACC);
+ /// `ELIBBAD`
+ pub const LIBBAD: Self = Self::from_errno(errno::ELIBBAD);
+ /// `ELIBEXEC`
+ pub const LIBEXEC: Self = Self::from_errno(errno::ELIBEXEC);
+ /// `ELIBMAX`
+ pub const LIBMAX: Self = Self::from_errno(errno::ELIBMAX);
+ /// `ELIBSCN`
+ pub const LIBSCN: Self = Self::from_errno(errno::ELIBSCN);
+ /// `ELNRNG`
+ pub const LNRNG: Self = Self::from_errno(errno::ELNRNG);
+ /// `ELOOP`
+ pub const LOOP: Self = Self::from_errno(errno::ELOOP);
+ /// `EMEDIUMTYPE`
+ pub const MEDIUMTYPE: Self = Self::from_errno(errno::EMEDIUMTYPE);
+ /// `EMFILE`
+ pub const MFILE: Self = Self::from_errno(errno::EMFILE);
+ /// `EMLINK`
+ pub const MLINK: Self = Self::from_errno(errno::EMLINK);
+ /// `EMSGSIZE`
+ pub const MSGSIZE: Self = Self::from_errno(errno::EMSGSIZE);
+ /// `EMULTIHOP`
+ pub const MULTIHOP: Self = Self::from_errno(errno::EMULTIHOP);
+ /// `ENAMETOOLONG`
+ pub const NAMETOOLONG: Self = Self::from_errno(errno::ENAMETOOLONG);
+ /// `ENAVAIL`
+ pub const NAVAIL: Self = Self::from_errno(errno::ENAVAIL);
+ /// `ENETDOWN`
+ pub const NETDOWN: Self = Self::from_errno(errno::ENETDOWN);
+ /// `ENETRESET`
+ pub const NETRESET: Self = Self::from_errno(errno::ENETRESET);
+ /// `ENETUNREACH`
+ pub const NETUNREACH: Self = Self::from_errno(errno::ENETUNREACH);
+ /// `ENFILE`
+ pub const NFILE: Self = Self::from_errno(errno::ENFILE);
+ /// `ENOANO`
+ pub const NOANO: Self = Self::from_errno(errno::ENOANO);
+ /// `ENOBUFS`
+ pub const NOBUFS: Self = Self::from_errno(errno::ENOBUFS);
+ /// `ENOCSI`
+ pub const NOCSI: Self = Self::from_errno(errno::ENOCSI);
+ /// `ENODATA`
+ #[doc(alias = "NOATTR")]
+ pub const NODATA: Self = Self::from_errno(errno::ENODATA);
+ /// `ENODEV`
+ pub const NODEV: Self = Self::from_errno(errno::ENODEV);
+ /// `ENOENT`
+ pub const NOENT: Self = Self::from_errno(errno::ENOENT);
+ /// `ENOEXEC`
+ pub const NOEXEC: Self = Self::from_errno(errno::ENOEXEC);
+ /// `ENOKEY`
+ pub const NOKEY: Self = Self::from_errno(errno::ENOKEY);
+ /// `ENOLCK`
+ pub const NOLCK: Self = Self::from_errno(errno::ENOLCK);
+ /// `ENOLINK`
+ pub const NOLINK: Self = Self::from_errno(errno::ENOLINK);
+ /// `ENOMEDIUM`
+ pub const NOMEDIUM: Self = Self::from_errno(errno::ENOMEDIUM);
+ /// `ENOMEM`
+ pub const NOMEM: Self = Self::from_errno(errno::ENOMEM);
+ /// `ENOMSG`
+ pub const NOMSG: Self = Self::from_errno(errno::ENOMSG);
+ /// `ENONET`
+ pub const NONET: Self = Self::from_errno(errno::ENONET);
+ /// `ENOPKG`
+ pub const NOPKG: Self = Self::from_errno(errno::ENOPKG);
+ /// `ENOPROTOOPT`
+ pub const NOPROTOOPT: Self = Self::from_errno(errno::ENOPROTOOPT);
+ /// `ENOSPC`
+ pub const NOSPC: Self = Self::from_errno(errno::ENOSPC);
+ /// `ENOSR`
+ pub const NOSR: Self = Self::from_errno(errno::ENOSR);
+ /// `ENOSTR`
+ pub const NOSTR: Self = Self::from_errno(errno::ENOSTR);
+ /// `ENOSYS`
+ pub const NOSYS: Self = Self::from_errno(errno::ENOSYS);
+ /// `ENOTBLK`
+ pub const NOTBLK: Self = Self::from_errno(errno::ENOTBLK);
+ /// `ENOTCONN`
+ pub const NOTCONN: Self = Self::from_errno(errno::ENOTCONN);
+ /// `ENOTDIR`
+ pub const NOTDIR: Self = Self::from_errno(errno::ENOTDIR);
+ /// `ENOTEMPTY`
+ pub const NOTEMPTY: Self = Self::from_errno(errno::ENOTEMPTY);
+ /// `ENOTNAM`
+ pub const NOTNAM: Self = Self::from_errno(errno::ENOTNAM);
+ /// `ENOTRECOVERABLE`
+ pub const NOTRECOVERABLE: Self = Self::from_errno(errno::ENOTRECOVERABLE);
+ /// `ENOTSOCK`
+ pub const NOTSOCK: Self = Self::from_errno(errno::ENOTSOCK);
+ /// `ENOTSUP`
+ // On Linux, `ENOTSUP` has the same value as `EOPNOTSUPP`.
+ pub const NOTSUP: Self = Self::from_errno(errno::EOPNOTSUPP);
+ /// `ENOTTY`
+ pub const NOTTY: Self = Self::from_errno(errno::ENOTTY);
+ /// `ENOTUNIQ`
+ pub const NOTUNIQ: Self = Self::from_errno(errno::ENOTUNIQ);
+ /// `ENXIO`
+ pub const NXIO: Self = Self::from_errno(errno::ENXIO);
+ /// `EOPNOTSUPP`
+ pub const OPNOTSUPP: Self = Self::from_errno(errno::EOPNOTSUPP);
+ /// `EOVERFLOW`
+ pub const OVERFLOW: Self = Self::from_errno(errno::EOVERFLOW);
+ /// `EOWNERDEAD`
+ pub const OWNERDEAD: Self = Self::from_errno(errno::EOWNERDEAD);
+ /// `EPERM`
+ pub const PERM: Self = Self::from_errno(errno::EPERM);
+ /// `EPFNOSUPPORT`
+ pub const PFNOSUPPORT: Self = Self::from_errno(errno::EPFNOSUPPORT);
+ /// `EPIPE`
+ pub const PIPE: Self = Self::from_errno(errno::EPIPE);
+ /// `EPROTO`
+ pub const PROTO: Self = Self::from_errno(errno::EPROTO);
+ /// `EPROTONOSUPPORT`
+ pub const PROTONOSUPPORT: Self = Self::from_errno(errno::EPROTONOSUPPORT);
+ /// `EPROTOTYPE`
+ pub const PROTOTYPE: Self = Self::from_errno(errno::EPROTOTYPE);
+ /// `ERANGE`
+ pub const RANGE: Self = Self::from_errno(errno::ERANGE);
+ /// `EREMCHG`
+ pub const REMCHG: Self = Self::from_errno(errno::EREMCHG);
+ /// `EREMOTE`
+ pub const REMOTE: Self = Self::from_errno(errno::EREMOTE);
+ /// `EREMOTEIO`
+ pub const REMOTEIO: Self = Self::from_errno(errno::EREMOTEIO);
+ /// `ERESTART`
+ pub const RESTART: Self = Self::from_errno(errno::ERESTART);
+ /// `ERFKILL`
+ pub const RFKILL: Self = Self::from_errno(errno::ERFKILL);
+ /// `EROFS`
+ pub const ROFS: Self = Self::from_errno(errno::EROFS);
+ /// `ESHUTDOWN`
+ pub const SHUTDOWN: Self = Self::from_errno(errno::ESHUTDOWN);
+ /// `ESOCKTNOSUPPORT`
+ pub const SOCKTNOSUPPORT: Self = Self::from_errno(errno::ESOCKTNOSUPPORT);
+ /// `ESPIPE`
+ pub const SPIPE: Self = Self::from_errno(errno::ESPIPE);
+ /// `ESRCH`
+ pub const SRCH: Self = Self::from_errno(errno::ESRCH);
+ /// `ESRMNT`
+ pub const SRMNT: Self = Self::from_errno(errno::ESRMNT);
+ /// `ESTALE`
+ pub const STALE: Self = Self::from_errno(errno::ESTALE);
+ /// `ESTRPIPE`
+ pub const STRPIPE: Self = Self::from_errno(errno::ESTRPIPE);
+ /// `ETIME`
+ pub const TIME: Self = Self::from_errno(errno::ETIME);
+ /// `ETIMEDOUT`
+ pub const TIMEDOUT: Self = Self::from_errno(errno::ETIMEDOUT);
+ /// `E2BIG`
+ #[doc(alias = "2BIG")]
+ pub const TOOBIG: Self = Self::from_errno(errno::E2BIG);
+ /// `ETOOMANYREFS`
+ pub const TOOMANYREFS: Self = Self::from_errno(errno::ETOOMANYREFS);
+ /// `ETXTBSY`
+ pub const TXTBSY: Self = Self::from_errno(errno::ETXTBSY);
+ /// `EUCLEAN`
+ pub const UCLEAN: Self = Self::from_errno(errno::EUCLEAN);
+ /// `EUNATCH`
+ pub const UNATCH: Self = Self::from_errno(errno::EUNATCH);
+ /// `EUSERS`
+ pub const USERS: Self = Self::from_errno(errno::EUSERS);
+ /// `EWOULDBLOCK`
+ pub const WOULDBLOCK: Self = Self::from_errno(errno::EWOULDBLOCK);
+ /// `EXDEV`
+ pub const XDEV: Self = Self::from_errno(errno::EXDEV);
+ /// `EXFULL`
+ pub const XFULL: Self = Self::from_errno(errno::EXFULL);
+}
diff --git a/vendor/rustix/src/backend/linux_raw/io/mod.rs b/vendor/rustix/src/backend/linux_raw/io/mod.rs
new file mode 100644
index 0000000..9477b9b
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/io/mod.rs
@@ -0,0 +1,3 @@
+pub(crate) mod errno;
+pub(crate) mod syscalls;
+pub(crate) mod types;
diff --git a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs
new file mode 100644
index 0000000..c38f28f
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs
@@ -0,0 +1,379 @@
+//! linux_raw syscalls supporting `rustix::io`.
+//!
+//! # Safety
+//!
+//! See the `rustix::backend` module documentation for details.
+#![allow(unsafe_code)]
+#![allow(clippy::undocumented_unsafe_blocks)]
+
+#[cfg(target_pointer_width = "64")]
+use crate::backend::conv::loff_t_from_u64;
+#[cfg(all(
+ target_pointer_width = "32",
+ any(target_arch = "arm", target_arch = "mips", target_arch = "mips32r6"),
+))]
+use crate::backend::conv::zero;
+use crate::backend::conv::{
+ c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd,
+ ret_usize, slice,
+};
+#[cfg(target_pointer_width = "32")]
+use crate::backend::conv::{hi, lo};
+use crate::backend::{c, MAX_IOV};
+use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd};
+use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags};
+use crate::ioctl::{IoctlOutput, RawOpcode};
+#[cfg(all(feature = "fs", feature = "net"))]
+use crate::net::{RecvFlags, SendFlags};
+use core::cmp;
+use linux_raw_sys::general::{F_DUPFD_CLOEXEC, F_GETFD, F_SETFD};
+
+#[inline]
+pub(crate) unsafe fn read(fd: BorrowedFd<'_>, buf: *mut u8, len: usize) -> io::Result<usize> {
+ ret_usize(syscall!(__NR_read, fd, buf, pass_usize(len)))
+}
+
+#[inline]
+pub(crate) unsafe fn pread(
+ fd: BorrowedFd<'_>,
+ buf: *mut u8,
+ len: usize,
+ pos: u64,
+) -> io::Result<usize> {
+ // <https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/arch/arm64/kernel/sys32.c#L75>
+ #[cfg(all(
+ target_pointer_width = "32",
+ any(target_arch = "arm", target_arch = "mips", target_arch = "mips32r6"),
+ ))]
+ {
+ ret_usize(syscall!(
+ __NR_pread64,
+ fd,
+ buf,
+ pass_usize(len),
+ zero(),
+ hi(pos),
+ lo(pos)
+ ))
+ }
+ #[cfg(all(
+ target_pointer_width = "32",
+ not(any(target_arch = "arm", target_arch = "mips", target_arch = "mips32r6")),
+ ))]
+ {
+ ret_usize(syscall!(
+ __NR_pread64,
+ fd,
+ buf,
+ pass_usize(len),
+ hi(pos),
+ lo(pos)
+ ))
+ }
+ #[cfg(target_pointer_width = "64")]
+ ret_usize(syscall!(
+ __NR_pread64,
+ fd,
+ buf,
+ pass_usize(len),
+ loff_t_from_u64(pos)
+ ))
+}
+
+#[inline]
+pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+
+ unsafe { ret_usize(syscall!(__NR_readv, fd, bufs_addr, bufs_len)) }
+}
+
+#[inline]
+pub(crate) fn preadv(
+ fd: BorrowedFd<'_>,
+ bufs: &mut [IoSliceMut<'_>],
+ pos: u64,
+) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+
+ // Unlike the plain "p" functions, the "pv" functions pass their offset in
+ // an endian-independent way, and always in two registers.
+ unsafe {
+ ret_usize(syscall!(
+ __NR_preadv,
+ fd,
+ bufs_addr,
+ bufs_len,
+ pass_usize(pos as usize),
+ pass_usize((pos >> 32) as usize)
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn preadv2(
+ fd: BorrowedFd<'_>,
+ bufs: &mut [IoSliceMut<'_>],
+ pos: u64,
+ flags: ReadWriteFlags,
+) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+
+ // Unlike the plain "p" functions, the "pv" functions pass their offset in
+ // an endian-independent way, and always in two registers.
+ unsafe {
+ ret_usize(syscall!(
+ __NR_preadv2,
+ fd,
+ bufs_addr,
+ bufs_len,
+ pass_usize(pos as usize),
+ pass_usize((pos >> 32) as usize),
+ flags
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result<usize> {
+ let (buf_addr, buf_len) = slice(buf);
+
+ unsafe { ret_usize(syscall_readonly!(__NR_write, fd, buf_addr, buf_len)) }
+}
+
+#[inline]
+pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], pos: u64) -> io::Result<usize> {
+ let (buf_addr, buf_len) = slice(buf);
+
+ // <https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/arch/arm64/kernel/sys32.c#L81-L83>
+ #[cfg(all(
+ target_pointer_width = "32",
+ any(target_arch = "arm", target_arch = "mips", target_arch = "mips32r6"),
+ ))]
+ unsafe {
+ ret_usize(syscall_readonly!(
+ __NR_pwrite64,
+ fd,
+ buf_addr,
+ buf_len,
+ zero(),
+ hi(pos),
+ lo(pos)
+ ))
+ }
+ #[cfg(all(
+ target_pointer_width = "32",
+ not(any(target_arch = "arm", target_arch = "mips", target_arch = "mips32r6")),
+ ))]
+ unsafe {
+ ret_usize(syscall_readonly!(
+ __NR_pwrite64,
+ fd,
+ buf_addr,
+ buf_len,
+ hi(pos),
+ lo(pos)
+ ))
+ }
+ #[cfg(target_pointer_width = "64")]
+ unsafe {
+ ret_usize(syscall_readonly!(
+ __NR_pwrite64,
+ fd,
+ buf_addr,
+ buf_len,
+ loff_t_from_u64(pos)
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+
+ unsafe { ret_usize(syscall_readonly!(__NR_writev, fd, bufs_addr, bufs_len)) }
+}
+
+#[inline]
+pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>], pos: u64) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+
+ // Unlike the plain "p" functions, the "pv" functions pass their offset in
+ // an endian-independent way, and always in two registers.
+ unsafe {
+ ret_usize(syscall_readonly!(
+ __NR_pwritev,
+ fd,
+ bufs_addr,
+ bufs_len,
+ pass_usize(pos as usize),
+ pass_usize((pos >> 32) as usize)
+ ))
+ }
+}
+
+#[inline]
+pub(crate) fn pwritev2(
+ fd: BorrowedFd<'_>,
+ bufs: &[IoSlice<'_>],
+ pos: u64,
+ flags: ReadWriteFlags,
+) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+
+ // Unlike the plain "p" functions, the "pv" functions pass their offset in
+ // an endian-independent way, and always in two registers.
+ unsafe {
+ ret_usize(syscall_readonly!(
+ __NR_pwritev2,
+ fd,
+ bufs_addr,
+ bufs_len,
+ pass_usize(pos as usize),
+ pass_usize((pos >> 32) as usize),
+ flags
+ ))
+ }
+}
+
+#[inline]
+pub(crate) unsafe fn close(fd: RawFd) {
+ // See the documentation for [`io::close`] for why errors are ignored.
+ syscall_readonly!(__NR_close, raw_fd(fd)).decode_void();
+}
+
+#[inline]
+pub(crate) unsafe fn ioctl(
+ fd: BorrowedFd<'_>,
+ request: RawOpcode,
+ arg: *mut c::c_void,
+) -> io::Result<IoctlOutput> {
+ ret_c_int(syscall!(__NR_ioctl, fd, c_uint(request), arg))
+}
+
+#[inline]
+pub(crate) unsafe fn ioctl_readonly(
+ fd: BorrowedFd<'_>,
+ request: RawOpcode,
+ arg: *mut c::c_void,
+) -> io::Result<IoctlOutput> {
+ ret_c_int(syscall_readonly!(__NR_ioctl, fd, c_uint(request), arg))
+}
+
+#[cfg(all(feature = "fs", 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.
+ let mut buf = [core::mem::MaybeUninit::<u8>::uninit()];
+ match unsafe {
+ crate::backend::net::syscalls::recv(
+ fd,
+ buf.as_mut_ptr() as *mut u8,
+ 1,
+ RecvFlags::PEEK | RecvFlags::DONTWAIT,
+ )
+ } {
+ Ok(0) => read = false,
+ Err(err) => {
+ #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK`
+ match err {
+ io::Errno::AGAIN | io::Errno::WOULDBLOCK => (),
+ io::Errno::NOTSOCK => not_socket = true,
+ _ => return Err(err),
+ }
+ }
+ Ok(_) => (),
+ }
+ }
+ if write && !not_socket {
+ // Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates
+ // the write side is shut down.
+ #[allow(unreachable_patterns)] // `EAGAIN` equals `EWOULDBLOCK`
+ match crate::backend::net::syscalls::send(fd, &[], SendFlags::DONTWAIT) {
+ Err(io::Errno::AGAIN | io::Errno::WOULDBLOCK | io::Errno::NOTSOCK) => (),
+ Err(io::Errno::PIPE) => write = false,
+ Err(err) => return Err(err),
+ Ok(_) => (),
+ }
+ }
+ Ok((read, write))
+}
+
+#[inline]
+pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> {
+ unsafe { ret_owned_fd(syscall_readonly!(__NR_dup, fd)) }
+}
+
+#[allow(clippy::needless_pass_by_ref_mut)]
+#[inline]
+pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> {
+ #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
+ {
+ // 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.
+ dup3(fd, new, DupFlags::empty())
+ }
+
+ #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))]
+ unsafe {
+ ret_discarded_fd(syscall_readonly!(__NR_dup2, fd, new.as_fd()))
+ }
+}
+
+#[allow(clippy::needless_pass_by_ref_mut)]
+#[inline]
+pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> {
+ unsafe { ret_discarded_fd(syscall_readonly!(__NR_dup3, fd, new.as_fd(), flags)) }
+}
+
+#[inline]
+pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result<FdFlags> {
+ #[cfg(target_pointer_width = "32")]
+ unsafe {
+ ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFD)))
+ .map(FdFlags::from_bits_retain)
+ }
+ #[cfg(target_pointer_width = "64")]
+ unsafe {
+ ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFD)))
+ .map(FdFlags::from_bits_retain)
+ }
+}
+
+#[inline]
+pub(crate) fn fcntl_setfd(fd: BorrowedFd<'_>, flags: FdFlags) -> io::Result<()> {
+ #[cfg(target_pointer_width = "32")]
+ unsafe {
+ ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFD), flags))
+ }
+ #[cfg(target_pointer_width = "64")]
+ unsafe {
+ ret(syscall_readonly!(__NR_fcntl, fd, c_uint(F_SETFD), flags))
+ }
+}
+
+#[inline]
+pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result<OwnedFd> {
+ #[cfg(target_pointer_width = "32")]
+ unsafe {
+ ret_owned_fd(syscall_readonly!(
+ __NR_fcntl64,
+ fd,
+ c_uint(F_DUPFD_CLOEXEC),
+ raw_fd(min)
+ ))
+ }
+ #[cfg(target_pointer_width = "64")]
+ unsafe {
+ ret_owned_fd(syscall_readonly!(
+ __NR_fcntl,
+ fd,
+ c_uint(F_DUPFD_CLOEXEC),
+ raw_fd(min)
+ ))
+ }
+}
diff --git a/vendor/rustix/src/backend/linux_raw/io/types.rs b/vendor/rustix/src/backend/linux_raw/io/types.rs
new file mode 100644
index 0000000..4b3dfc6
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/io/types.rs
@@ -0,0 +1,57 @@
+use crate::backend::c;
+use bitflags::bitflags;
+
+bitflags! {
+ /// `FD_*` constants for use with [`fcntl_getfd`] and [`fcntl_setfd`].
+ ///
+ /// [`fcntl_getfd`]: crate::io::fcntl_getfd
+ /// [`fcntl_setfd`]: crate::io::fcntl_setfd
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct FdFlags: c::c_uint {
+ /// `FD_CLOEXEC`
+ const CLOEXEC = linux_raw_sys::general::FD_CLOEXEC;
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+bitflags! {
+ /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`].
+ ///
+ /// [`preadv2`]: crate::io::preadv2
+ /// [`pwritev2`]: crate::io::pwritev
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct ReadWriteFlags: c::c_uint {
+ /// `RWF_DSYNC` (since Linux 4.7)
+ const DSYNC = linux_raw_sys::general::RWF_DSYNC;
+ /// `RWF_HIPRI` (since Linux 4.6)
+ const HIPRI = linux_raw_sys::general::RWF_HIPRI;
+ /// `RWF_SYNC` (since Linux 4.7)
+ const SYNC = linux_raw_sys::general::RWF_SYNC;
+ /// `RWF_NOWAIT` (since Linux 4.14)
+ const NOWAIT = linux_raw_sys::general::RWF_NOWAIT;
+ /// `RWF_APPEND` (since Linux 4.16)
+ const APPEND = linux_raw_sys::general::RWF_APPEND;
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+bitflags! {
+ /// `O_*` constants for use with [`dup2`].
+ ///
+ /// [`dup2`]: crate::io::dup2
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct DupFlags: c::c_uint {
+ /// `O_CLOEXEC`
+ const CLOEXEC = linux_raw_sys::general::O_CLOEXEC;
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}