diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/rustix/src | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/rustix/src')
315 files changed, 0 insertions, 70119 deletions
diff --git a/vendor/rustix/src/backend/libc/c.rs b/vendor/rustix/src/backend/libc/c.rs deleted file mode 100644 index 2f737c21..00000000 --- a/vendor/rustix/src/backend/libc/c.rs +++ /dev/null @@ -1,533 +0,0 @@ -//! Libc and supplemental types and constants. - -#![allow(unused_imports)] - -// Import everything from libc, but we'll add some stuff and override some -// things below. -pub(crate) use libc::*; - -/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. -#[cfg(all(linux_kernel, target_env = "musl"))] -pub(crate) const PROC_SUPER_MAGIC: u32 = 0x0000_9fa0; - -/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. -#[cfg(all(linux_kernel, target_env = "musl"))] -pub(crate) const NFS_SUPER_MAGIC: u32 = 0x0000_6969; - -#[cfg(feature = "process")] -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) const EXIT_SIGNALED_SIGABRT: c_int = 128 + SIGABRT as c_int; - -// TODO: Upstream these. -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_TSN: c_int = linux_raw_sys::if_ether::ETH_P_TSN as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_ERSPAN2: c_int = linux_raw_sys::if_ether::ETH_P_ERSPAN2 as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_ERSPAN: c_int = linux_raw_sys::if_ether::ETH_P_ERSPAN as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_PROFINET: c_int = linux_raw_sys::if_ether::ETH_P_PROFINET as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_REALTEK: c_int = linux_raw_sys::if_ether::ETH_P_REALTEK as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_ETHERCAT: c_int = linux_raw_sys::if_ether::ETH_P_ETHERCAT as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_PREAUTH: c_int = linux_raw_sys::if_ether::ETH_P_PREAUTH as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_LLDP: c_int = linux_raw_sys::if_ether::ETH_P_LLDP as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_MRP: c_int = linux_raw_sys::if_ether::ETH_P_MRP as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_NCSI: c_int = linux_raw_sys::if_ether::ETH_P_NCSI as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_CFM: c_int = linux_raw_sys::if_ether::ETH_P_CFM as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_IBOE: c_int = linux_raw_sys::if_ether::ETH_P_IBOE as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_HSR: c_int = linux_raw_sys::if_ether::ETH_P_HSR as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_NSH: c_int = linux_raw_sys::if_ether::ETH_P_NSH as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_DSA_8021Q: c_int = linux_raw_sys::if_ether::ETH_P_DSA_8021Q as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_DSA_A5PSW: c_int = linux_raw_sys::if_ether::ETH_P_DSA_A5PSW as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_IFE: c_int = linux_raw_sys::if_ether::ETH_P_IFE as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_CAN: c_int = linux_raw_sys::if_ether::ETH_P_CAN as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_CANXL: c_int = linux_raw_sys::if_ether::ETH_P_CANXL as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_XDSA: c_int = linux_raw_sys::if_ether::ETH_P_XDSA as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_MAP: c_int = linux_raw_sys::if_ether::ETH_P_MAP as _; -#[cfg(all(linux_kernel, feature = "net"))] -pub(crate) const ETH_P_MCTP: c_int = linux_raw_sys::if_ether::ETH_P_MCTP as _; - -#[cfg(all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ) -))] -pub(crate) const SIGEMT: c_int = linux_raw_sys::general::SIGEMT as _; - -// TODO: Upstream these. -#[cfg(all(linux_kernel, feature = "termios"))] -pub(crate) const IUCLC: tcflag_t = linux_raw_sys::general::IUCLC as _; -#[cfg(all(linux_kernel, feature = "termios"))] -pub(crate) const XCASE: tcflag_t = linux_raw_sys::general::XCASE as _; - -#[cfg(target_os = "aix")] -pub(crate) const MSG_DONTWAIT: c_int = MSG_NONBLOCK; - -// `O_LARGEFILE` can be automatically set by the kernel on Linux: -// <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/open.c?h=v6.13#n1423> -// so libc implementations may leave it undefined or defined to zero. -#[cfg(linux_kernel)] -pub(crate) const O_LARGEFILE: c_int = linux_raw_sys::general::O_LARGEFILE as _; - -// Gated under `_LARGEFILE_SOURCE` but automatically set by the kernel. -// <https://github.com/illumos/illumos-gate/blob/fb2cb638e5604b214d8ea8d4f01ad2e77b437c17/usr/src/ucbhead/sys/fcntl.h#L64> -#[cfg(solarish)] -pub(crate) const O_LARGEFILE: c_int = 0x2000; - -// On PowerPC, the regular `termios` has the `termios2` fields and there is no -// `termios2`, so we define aliases. -#[cfg(all( - linux_kernel, - feature = "termios", - any(target_arch = "powerpc", target_arch = "powerpc64") -))] -pub(crate) use { - termios as termios2, TCGETS as TCGETS2, TCSETS as TCSETS2, TCSETSF as TCSETSF2, - TCSETSW as TCSETSW2, -}; - -// And PowerPC doesn't define `CIBAUD`, but it does define `IBSHIFT`, so we can -// compute `CIBAUD` ourselves. -#[cfg(all( - linux_kernel, - feature = "termios", - any(target_arch = "powerpc", target_arch = "powerpc64") -))] -pub(crate) const CIBAUD: u32 = CBAUD << IBSHIFT; - -// Automatically enable “large file” support (LFS) features. - -#[cfg(target_os = "vxworks")] -pub(super) use _Vx_ticks64_t as _Vx_ticks_t; -#[cfg(linux_kernel)] -pub(super) use fallocate64 as fallocate; -#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] -#[cfg(any(linux_like, target_os = "aix"))] -pub(super) use open64 as open; -#[cfg(any( - linux_kernel, - target_os = "aix", - target_os = "hurd", - target_os = "l4re" -))] -pub(super) use posix_fallocate64 as posix_fallocate; -#[cfg(any(all(linux_like, not(target_os = "android")), target_os = "aix"))] -pub(super) use {blkcnt64_t as blkcnt_t, rlim64_t as rlim_t}; -// TODO: AIX has `stat64x`, `fstat64x`, `lstat64x`, and `stat64xat`; add them -// to the upstream libc crate and implement rustix's `statat` etc. with them. -#[cfg(target_os = "aix")] -pub(super) use { - blksize64_t as blksize_t, fstat64 as fstat, fstatfs64 as fstatfs, fstatvfs64 as fstatvfs, - ftruncate64 as ftruncate, getrlimit64 as getrlimit, ino_t, lseek64 as lseek, mmap, - off64_t as off_t, openat, posix_fadvise64 as posix_fadvise, preadv, pwritev, - rlimit64 as rlimit, setrlimit64 as setrlimit, stat64at as fstatat, statfs64 as statfs, - statvfs64 as statvfs, RLIM_INFINITY, -}; -#[cfg(any(linux_like, target_os = "hurd"))] -pub(super) use { - fstat64 as fstat, fstatat64 as fstatat, fstatfs64 as fstatfs, fstatvfs64 as fstatvfs, - ftruncate64 as ftruncate, getrlimit64 as getrlimit, ino64_t as ino_t, lseek64 as lseek, - mmap64 as mmap, off64_t as off_t, openat64 as openat, posix_fadvise64 as posix_fadvise, - rlimit64 as rlimit, setrlimit64 as setrlimit, statfs64 as statfs, statvfs64 as statvfs, - RLIM64_INFINITY as RLIM_INFINITY, -}; -#[cfg(apple)] -pub(super) use { - host_info64_t as host_info_t, host_statistics64 as host_statistics, - vm_statistics64_t as vm_statistics_t, -}; -#[cfg(not(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) -)))] -#[cfg(any(linux_like, target_os = "aix", target_os = "hurd"))] -pub(super) use {lstat64 as lstat, stat64 as stat}; -#[cfg(any( - linux_kernel, - target_os = "aix", - target_os = "hurd", - target_os = "emscripten" -))] -pub(super) use {pread64 as pread, pwrite64 as pwrite}; -#[cfg(any(target_os = "linux", target_os = "hurd", target_os = "emscripten"))] -pub(super) use {preadv64 as preadv, pwritev64 as pwritev}; - -#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))] -pub(super) unsafe fn prlimit( - pid: pid_t, - resource: __rlimit_resource_t, - new_limit: *const rlimit64, - old_limit: *mut rlimit64, -) -> c_int { - // `prlimit64` wasn't supported in glibc until 2.13. - weak_or_syscall! { - fn prlimit64( - pid: pid_t, - resource: __rlimit_resource_t, - new_limit: *const rlimit64, - old_limit: *mut rlimit64 - ) via SYS_prlimit64 -> c_int - } - - prlimit64(pid, resource, new_limit, old_limit) -} - -#[cfg(all(target_os = "linux", target_env = "musl"))] -pub(super) unsafe fn prlimit( - pid: pid_t, - resource: c_int, - new_limit: *const rlimit64, - old_limit: *mut rlimit64, -) -> c_int { - weak_or_syscall! { - fn prlimit64( - pid: pid_t, - resource: c_int, - new_limit: *const rlimit64, - old_limit: *mut rlimit64 - ) via SYS_prlimit64 -> c_int - } - - prlimit64(pid, resource, new_limit, old_limit) -} - -#[cfg(target_os = "android")] -pub(super) unsafe fn prlimit( - pid: pid_t, - resource: c_int, - new_limit: *const rlimit64, - old_limit: *mut rlimit64, -) -> c_int { - weak_or_syscall! { - fn prlimit64( - pid: pid_t, - resource: c_int, - new_limit: *const rlimit64, - old_limit: *mut rlimit64 - ) via SYS_prlimit64 -> c_int - } - - prlimit64(pid, resource, new_limit, old_limit) -} - -#[cfg(target_os = "android")] -mod readwrite_pv64 { - use super::*; - - pub(in super::super) unsafe fn preadv64( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off64_t, - ) -> ssize_t { - // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to - // test for it, and call back to `syscall`. We don't use - // `weak_or_syscall` here because we need to pass the 64-bit offset - // specially. - weak! { - fn preadv64(c_int, *const iovec, c_int, off64_t) -> ssize_t - } - if let Some(fun) = preadv64.get() { - fun(fd, iov, iovcnt, offset) - } else { - // Unlike the plain "p" functions, the "pv" functions pass their - // offset in an endian-independent way, and always in two - // registers. - syscall! { - fn preadv( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset_lo: usize, - offset_hi: usize - ) via SYS_preadv -> ssize_t - } - preadv(fd, iov, iovcnt, offset as usize, (offset >> 32) as usize) - } - } - pub(in super::super) unsafe fn pwritev64( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off64_t, - ) -> ssize_t { - // See the comments in `preadv64`. - weak! { - fn pwritev64(c_int, *const iovec, c_int, off64_t) -> ssize_t - } - if let Some(fun) = pwritev64.get() { - fun(fd, iov, iovcnt, offset) - } else { - // Unlike the plain "p" functions, the "pv" functions pass their - // offset in an endian-independent way, and always in two - // registers. - syscall! { - fn pwritev( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset_lo: usize, - offset_hi: usize - ) via SYS_pwritev -> ssize_t - } - pwritev(fd, iov, iovcnt, offset as usize, (offset >> 32) as usize) - } - } -} -#[cfg(target_os = "android")] -pub(super) use readwrite_pv64::{preadv64 as preadv, pwritev64 as pwritev}; - -// macOS added `preadv` and `pwritev` in version 11.0. -#[cfg(apple)] -mod readwrite_pv { - use super::*; - weakcall! { - pub(in super::super) fn preadv( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off_t - ) -> ssize_t - } - weakcall! { - pub(in super::super) fn pwritev( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, offset: off_t - ) -> ssize_t - } -} -#[cfg(apple)] -pub(super) use readwrite_pv::{preadv, pwritev}; - -// glibc added `preadv64v2` and `pwritev64v2` in version 2.26. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -mod readwrite_pv64v2 { - use super::*; - - pub(in super::super) unsafe fn preadv64v2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off64_t, - flags: c_int, - ) -> ssize_t { - // Older glibc lacks `preadv64v2`, so use the `weak!` mechanism to - // test for it, and call back to `syscall`. We don't use - // `weak_or_syscall` here because we need to pass the 64-bit offset - // specially. - weak! { - fn preadv64v2(c_int, *const iovec, c_int, off64_t, c_int) -> ssize_t - } - if let Some(fun) = preadv64v2.get() { - fun(fd, iov, iovcnt, offset, flags) - } else { - // Unlike the plain "p" functions, the "pv" functions pass their - // offset in an endian-independent way, and always in two - // registers. - syscall! { - fn preadv2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset_lo: usize, - offset_hi: usize, - flags: c_int - ) via SYS_preadv2 -> ssize_t - } - preadv2( - fd, - iov, - iovcnt, - offset as usize, - (offset >> 32) as usize, - flags, - ) - } - } - pub(in super::super) unsafe fn pwritev64v2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off64_t, - flags: c_int, - ) -> ssize_t { - // See the comments in `preadv64v2`. - weak! { - fn pwritev64v2(c_int, *const iovec, c_int, off64_t, c_int) -> ssize_t - } - if let Some(fun) = pwritev64v2.get() { - fun(fd, iov, iovcnt, offset, flags) - } else { - // Unlike the plain "p" functions, the "pv" functions pass their - // offset in an endian-independent way, and always in two - // registers. - syscall! { - fn pwritev2( - fd: c_int, - iov: *const iovec, - iovec: c_int, - offset_lo: usize, - offset_hi: usize, - flags: c_int - ) via SYS_pwritev2 -> ssize_t - } - pwritev2( - fd, - iov, - iovcnt, - offset as usize, - (offset >> 32) as usize, - flags, - ) - } - } -} -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2}; - -// On non-glibc, assume we don't have `pwritev2`/`preadv2` in libc and use -// `c::syscall` instead. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -mod readwrite_pv64v2 { - use super::*; - - pub(in super::super) unsafe fn preadv64v2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off64_t, - flags: c_int, - ) -> ssize_t { - // Unlike the plain "p" functions, the "pv" functions pass their offset - // in an endian-independent way, and always in two registers. - syscall! { - fn preadv2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset_lo: usize, - offset_hi: usize, - flags: c_int - ) via SYS_preadv2 -> ssize_t - } - preadv2( - fd, - iov, - iovcnt, - offset as usize, - (offset >> 32) as usize, - flags, - ) - } - pub(in super::super) unsafe fn pwritev64v2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off64_t, - flags: c_int, - ) -> ssize_t { - // Unlike the plain "p" functions, the "pv" functions pass their offset - // in an endian-independent way, and always in two registers. - syscall! { - fn pwritev2( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset_lo: usize, - offset_hi: usize, - flags: c_int - ) via SYS_pwritev2 -> ssize_t - } - pwritev2( - fd, - iov, - iovcnt, - offset as usize, - (offset >> 32) as usize, - flags, - ) - } -} -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2}; - -// Rust's libc crate lacks statx for Non-glibc targets. -#[cfg(feature = "fs")] -#[cfg(all( - linux_like, - not(any(target_os = "android", target_os = "emscripten", target_env = "gnu")) -))] -mod statx_flags { - pub(crate) use linux_raw_sys::general::{ - STATX_ALL, STATX_ATIME, STATX_BASIC_STATS, STATX_BLOCKS, STATX_BTIME, STATX_CTIME, - STATX_DIOALIGN, STATX_GID, STATX_INO, STATX_MNT_ID, STATX_MODE, STATX_MTIME, STATX_NLINK, - STATX_SIZE, STATX_TYPE, STATX_UID, - }; - - pub(crate) use linux_raw_sys::general::{ - STATX_ATTR_APPEND, STATX_ATTR_AUTOMOUNT, STATX_ATTR_COMPRESSED, STATX_ATTR_DAX, - STATX_ATTR_ENCRYPTED, STATX_ATTR_IMMUTABLE, STATX_ATTR_MOUNT_ROOT, STATX_ATTR_NODUMP, - STATX_ATTR_VERITY, - }; -} -#[cfg(feature = "fs")] -#[cfg(all( - linux_like, - not(any(target_os = "android", target_os = "emscripten", target_env = "gnu")) -))] -pub(crate) use statx_flags::*; - -#[cfg(feature = "fs")] -#[cfg(target_os = "android")] -pub(crate) use __fsid_t as fsid_t; - -#[cfg(feature = "mm")] -#[cfg(target_os = "android")] -pub(crate) const MAP_DROPPABLE: c_int = bitcast!(linux_raw_sys::general::MAP_DROPPABLE); - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[cfg(linux_kernel)] - fn test_flags() { - // libc may publicly define `O_LARGEFILE` to 0, but we want the real - // non-zero value. - assert_ne!(O_LARGEFILE, 0); - } -} diff --git a/vendor/rustix/src/backend/libc/conv.rs b/vendor/rustix/src/backend/libc/conv.rs deleted file mode 100644 index 1cb1fc93..00000000 --- a/vendor/rustix/src/backend/libc/conv.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! Libc call arguments and return values are often things like `c_int`, -//! `c_uint`, or libc-specific pointer types. This module provides functions -//! for converting between rustix's types and libc types. - -use super::c; -#[cfg(all(feature = "alloc", not(any(windows, target_os = "espidf"))))] -use super::fd::IntoRawFd as _; -use super::fd::{AsRawFd as _, BorrowedFd, FromRawFd as _, LibcFd, OwnedFd, RawFd}; -#[cfg(not(windows))] -use crate::ffi::CStr; -use crate::io; - -#[cfg(not(windows))] -#[inline] -pub(super) fn c_str(c: &CStr) -> *const c::c_char { - c.as_ptr().cast() -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(super) fn no_fd() -> LibcFd { - -1 -} - -#[inline] -pub(super) fn borrowed_fd(fd: BorrowedFd<'_>) -> LibcFd { - fd.as_raw_fd() as LibcFd -} - -#[cfg(all( - feature = "alloc", - not(any(windows, target_os = "espidf", target_os = "redox")) -))] -#[inline] -pub(super) fn owned_fd(fd: OwnedFd) -> LibcFd { - fd.into_raw_fd() as LibcFd -} - -#[inline] -pub(super) fn ret(raw: c::c_int) -> io::Result<()> { - if raw == 0 { - Ok(()) - } else { - Err(io::Errno::last_os_error()) - } -} - -#[cfg(apple)] -#[inline] -pub(super) fn nonnegative_ret(raw: c::c_int) -> io::Result<()> { - if raw >= 0 { - Ok(()) - } else { - Err(io::Errno::last_os_error()) - } -} - -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub(super) unsafe fn ret_infallible(raw: c::c_int) { - debug_assert_eq!(raw, 0, "unexpected error: {:?}", io::Errno::last_os_error()); -} - -#[inline] -pub(super) fn ret_c_int(raw: c::c_int) -> io::Result<c::c_int> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -#[cfg(any( - linux_kernel, - all(target_os = "illumos", feature = "event"), - all(target_os = "redox", feature = "event") -))] -#[inline] -pub(super) fn ret_u32(raw: c::c_int) -> io::Result<u32> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw as u32) - } -} - -#[inline] -pub(super) fn ret_usize(raw: c::ssize_t) -> io::Result<usize> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - debug_assert!(raw >= 0); - Ok(raw as usize) - } -} - -#[cfg(not(windows))] -#[cfg(feature = "fs")] -#[inline] -pub(super) fn ret_off_t(raw: c::off_t) -> io::Result<c::off_t> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub(super) fn ret_pid_t(raw: c::pid_t) -> io::Result<c::pid_t> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -/// Convert a `c_int` returned from a libc function to an `OwnedFd`, if valid. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a libc function -/// which returns an owned file descriptor. -#[inline] -pub(super) unsafe fn ret_owned_fd(raw: LibcFd) -> io::Result<OwnedFd> { - if raw == !0 { - Err(io::Errno::last_os_error()) - } else { - Ok(OwnedFd::from_raw_fd(raw as RawFd)) - } -} - -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub(super) fn ret_discarded_fd(raw: LibcFd) -> io::Result<()> { - if raw == !0 { - Err(io::Errno::last_os_error()) - } else { - Ok(()) - } -} - -#[cfg(all(feature = "alloc", not(any(windows, target_os = "wasi"))))] -#[inline] -pub(super) fn ret_discarded_char_ptr(raw: *mut c::c_char) -> io::Result<()> { - if raw.is_null() { - Err(io::Errno::last_os_error()) - } else { - Ok(()) - } -} - -/// Convert the buffer-length argument value of a `send` or `recv` call. -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub(super) fn send_recv_len(len: usize) -> usize { - len -} - -/// Convert the buffer-length argument value of a `send` or `recv` call. -#[cfg(windows)] -#[inline] -pub(super) fn send_recv_len(len: usize) -> i32 { - // On Windows, the length argument has type `i32`; saturate the length, - // since `send` and `recv` are allowed to send and recv less data than - // requested. - len.try_into().unwrap_or(i32::MAX) -} - -/// Convert the return value of a `send` or `recv` call. -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub(super) fn ret_send_recv(len: isize) -> io::Result<usize> { - ret_usize(len) -} - -/// Convert the return value of a `send` or `recv` call. -#[cfg(windows)] -#[inline] -pub(super) fn ret_send_recv(len: i32) -> io::Result<usize> { - ret_usize(len as isize) -} diff --git a/vendor/rustix/src/backend/libc/event/epoll.rs b/vendor/rustix/src/backend/libc/event/epoll.rs deleted file mode 100644 index 08f4bacc..00000000 --- a/vendor/rustix/src/backend/libc/event/epoll.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `EPOLL_*` for use with [`epoll::create`]. - /// - /// [`epoll::create`]: crate::event::epoll::create - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CreateFlags: u32 { - /// `EPOLL_CLOEXEC` - const CLOEXEC = bitcast!(c::EPOLL_CLOEXEC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `EPOLL*` for use with [`epoll::add`]. - /// - /// [`epoll::add`]: crate::event::epoll::add - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct EventFlags: u32 { - /// `EPOLLIN` - const IN = bitcast!(c::EPOLLIN); - - /// `EPOLLOUT` - const OUT = bitcast!(c::EPOLLOUT); - - /// `EPOLLPRI` - const PRI = bitcast!(c::EPOLLPRI); - - /// `EPOLLERR` - const ERR = bitcast!(c::EPOLLERR); - - /// `EPOLLHUP` - const HUP = bitcast!(c::EPOLLHUP); - - /// `EPOLLRDNORM` - const RDNORM = bitcast!(c::EPOLLRDNORM); - - /// `EPOLLRDBAND` - const RDBAND = bitcast!(c::EPOLLRDBAND); - - /// `EPOLLWRNORM` - const WRNORM = bitcast!(c::EPOLLWRNORM); - - /// `EPOLLWRBAND` - const WRBAND = bitcast!(c::EPOLLWRBAND); - - /// `EPOLLMSG` - const MSG = bitcast!(c::EPOLLMSG); - - /// `EPOLLRDHUP` - const RDHUP = bitcast!(c::EPOLLRDHUP); - - /// `EPOLLET` - const ET = bitcast!(c::EPOLLET); - - /// `EPOLLONESHOT` - const ONESHOT = bitcast!(c::EPOLLONESHOT); - - /// `EPOLLWAKEUP` - const WAKEUP = bitcast!(c::EPOLLWAKEUP); - - /// `EPOLLEXCLUSIVE` - const EXCLUSIVE = bitcast!(c::EPOLLEXCLUSIVE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/event/mod.rs b/vendor/rustix/src/backend/libc/event/mod.rs deleted file mode 100644 index ff826fc4..00000000 --- a/vendor/rustix/src/backend/libc/event/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -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(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub mod epoll; diff --git a/vendor/rustix/src/backend/libc/event/poll_fd.rs b/vendor/rustix/src/backend/libc/event/poll_fd.rs deleted file mode 100644 index fdaa6c68..00000000 --- a/vendor/rustix/src/backend/libc/event/poll_fd.rs +++ /dev/null @@ -1,143 +0,0 @@ -use crate::backend::c; -use crate::backend::conv::borrowed_fd; -use crate::backend::fd::{AsFd, AsRawFd as _, BorrowedFd, LibcFd}; -#[cfg(windows)] -use crate::backend::fd::{AsSocket, RawFd}; -use crate::ffi; -use bitflags::bitflags; -use core::fmt; -use core::marker::PhantomData; - -bitflags! { - /// `POLL*` flags for use with [`poll`]. - /// - /// [`poll`]: crate::event::poll - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PollFlags: ffi::c_short { - /// `POLLIN` - const IN = c::POLLIN; - /// `POLLPRI` - #[cfg(not(target_os = "wasi"))] - const PRI = c::POLLPRI; - /// `POLLOUT` - const OUT = c::POLLOUT; - /// `POLLRDNORM` - const RDNORM = c::POLLRDNORM; - /// `POLLWRNORM` - #[cfg(not(target_os = "l4re"))] - const WRNORM = c::POLLWRNORM; - /// `POLLRDBAND` - #[cfg(not(any(target_os = "l4re", target_os = "wasi")))] - const RDBAND = c::POLLRDBAND; - /// `POLLWRBAND` - #[cfg(not(any(target_os = "l4re", target_os = "wasi")))] - const WRBAND = c::POLLWRBAND; - /// `POLLERR` - const ERR = c::POLLERR; - /// `POLLHUP` - const HUP = c::POLLHUP; - /// `POLLNVAL` - #[cfg(not(target_os = "espidf"))] - const NVAL = c::POLLNVAL; - /// `POLLRDHUP` - #[cfg(any( - target_os = "freebsd", - target_os = "illumos", - all( - linux_kernel, - not(any(target_arch = "sparc", target_arch = "sparc64")) - ), - ))] - const RDHUP = c::POLLRDHUP; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `struct pollfd`—File descriptor and flags for use with [`poll`]. -/// -/// [`poll`]: crate::event::poll -#[doc(alias = "pollfd")] -#[derive(Clone)] -#[repr(transparent)] -pub struct PollFd<'fd> { - pollfd: c::pollfd, - _phantom: PhantomData<BorrowedFd<'fd>>, -} - -impl<'fd> fmt::Debug for PollFd<'fd> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.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> 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/backend/libc/event/syscalls.rs b/vendor/rustix/src/backend/libc/event/syscalls.rs deleted file mode 100644 index 3827a2f9..00000000 --- a/vendor/rustix/src/backend/libc/event/syscalls.rs +++ /dev/null @@ -1,631 +0,0 @@ -//! libc syscalls supporting `rustix::event`. - -use crate::backend::c; -#[cfg(any(linux_kernel, solarish, target_os = "redox"))] -use crate::backend::conv::ret; -use crate::backend::conv::ret_c_int; -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -use crate::backend::conv::ret_u32; -#[cfg(bsd)] -use crate::event::kqueue::Event; -#[cfg(solarish)] -use crate::event::port::Event; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf" -))] -use crate::event::EventfdFlags; -#[cfg(any(bsd, linux_kernel, target_os = "wasi"))] -use crate::event::FdSetElement; -use crate::event::{PollFd, Timespec}; -use crate::io; -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -use crate::utils::as_ptr; -#[cfg(solarish)] -use core::mem::MaybeUninit; -#[cfg(any( - bsd, - linux_kernel, - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "netbsd", - target_os = "wasi" -))] -use core::ptr::null; -#[cfg(any(bsd, linux_kernel, solarish, target_os = "redox", target_os = "wasi"))] -use core::ptr::null_mut; -#[cfg(any(bsd, linux_kernel, solarish, target_os = "redox"))] -use {crate::backend::conv::borrowed_fd, crate::fd::BorrowedFd}; -#[cfg(any( - bsd, - linux_kernel, - solarish, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf", - target_os = "redox" -))] -use {crate::backend::conv::ret_owned_fd, crate::fd::OwnedFd}; - -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf" -))] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { - #[cfg(linux_kernel)] - unsafe { - syscall! { - fn eventfd2( - initval: c::c_uint, - flags: c::c_int - ) via SYS_eventfd2 -> c::c_int - } - ret_owned_fd(eventfd2(initval, bitflags_bits!(flags))) - } - - // `eventfd` was added in FreeBSD 13, so it isn't available on FreeBSD 12. - #[cfg(target_os = "freebsd")] - unsafe { - weakcall! { - fn eventfd( - initval: c::c_uint, - flags: c::c_int - ) -> c::c_int - } - ret_owned_fd(eventfd(initval, bitflags_bits!(flags))) - } - - #[cfg(any(target_os = "illumos", target_os = "espidf"))] - unsafe { - ret_owned_fd(c::eventfd(initval, bitflags_bits!(flags))) - } -} - -#[cfg(bsd)] -pub(crate) fn kqueue() -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::kqueue()) } -} - -#[cfg(bsd)] -pub(crate) unsafe fn kevent( - kq: BorrowedFd<'_>, - changelist: &[Event], - eventlist: (*mut Event, usize), - timeout: Option<&Timespec>, -) -> io::Result<c::c_int> { - // If we don't have to fix y2038 on this platform, `Timespec` is the same - // as `c::timespec` and it's easy. - #[cfg(not(fix_y2038))] - let timeout = crate::timespec::option_as_libc_timespec_ptr(timeout); - - // If we do have to fix y2038 on this platform, convert to `c::timespec`. - #[cfg(fix_y2038)] - let converted_timeout; - #[cfg(fix_y2038)] - let timeout = match timeout { - None => null(), - Some(timeout) => { - converted_timeout = c::timespec { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: timeout.tv_nsec as _, - }; - &converted_timeout - } - }; - - ret_c_int(c::kevent( - borrowed_fd(kq), - changelist.as_ptr().cast(), - changelist - .len() - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - eventlist.0.cast(), - eventlist.1.try_into().map_err(|_| io::Errno::OVERFLOW)?, - timeout, - )) -} - -#[inline] -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: Option<&Timespec>) -> io::Result<usize> { - let nfds = fds - .len() - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - - // If we have `ppoll`, it supports a `timespec` timeout, so use it. - #[cfg(any( - linux_kernel, - freebsdlike, - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "netbsd" - ))] - { - // If we don't have to fix y2038 on this platform, `Timespec` is - // the same as `c::timespec` and it's easy. - #[cfg(not(fix_y2038))] - let timeout = crate::timespec::option_as_libc_timespec_ptr(timeout); - - // If we do have to fix y2038 on this platform, convert to - // `c::timespec`. - #[cfg(fix_y2038)] - let converted_timeout; - #[cfg(fix_y2038)] - let timeout = match timeout { - None => null(), - Some(timeout) => { - converted_timeout = c::timespec { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: timeout.tv_nsec as _, - }; - &converted_timeout - } - }; - - #[cfg(not(target_os = "netbsd"))] - { - ret_c_int(unsafe { c::ppoll(fds.as_mut_ptr().cast(), nfds, timeout, null()) }) - .map(|nready| nready as usize) - } - - // NetBSD 9.x lacks `ppoll`, so use a weak symbol and fall back to - // plain `poll` if needed. - #[cfg(target_os = "netbsd")] - { - weak! { - fn ppoll( - *mut c::pollfd, - c::nfds_t, - *const c::timespec, - *const c::sigset_t - ) -> c::c_int - } - if let Some(func) = ppoll.get() { - return ret_c_int(unsafe { func(fds.as_mut_ptr().cast(), nfds, timeout, null()) }) - .map(|nready| nready as usize); - } - } - } - - // If we don't have `ppoll`, convert the timeout to `c_int` and use `poll`. - #[cfg(not(any( - linux_kernel, - freebsdlike, - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd" - )))] - { - let timeout = match timeout { - None => -1, - Some(timeout) => timeout.as_c_int_millis().ok_or(io::Errno::INVAL)?, - }; - ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) - .map(|nready| nready as usize) - } -} - -#[cfg(any(bsd, linux_kernel))] -pub(crate) unsafe fn select( - nfds: i32, - readfds: Option<&mut [FdSetElement]>, - writefds: Option<&mut [FdSetElement]>, - exceptfds: Option<&mut [FdSetElement]>, - timeout: Option<&Timespec>, -) -> io::Result<i32> { - let len = crate::event::fd_set_num_elements_for_bitvector(nfds); - - let readfds = match readfds { - Some(readfds) => { - assert!(readfds.len() >= len); - readfds.as_mut_ptr() - } - None => null_mut(), - }; - let writefds = match writefds { - Some(writefds) => { - assert!(writefds.len() >= len); - writefds.as_mut_ptr() - } - None => null_mut(), - }; - let exceptfds = match exceptfds { - Some(exceptfds) => { - assert!(exceptfds.len() >= len); - exceptfds.as_mut_ptr() - } - None => null_mut(), - }; - - let timeout_data; - let timeout_ptr = match timeout { - Some(timeout) => { - // Convert from `Timespec` to `c::timeval`. - timeout_data = c::timeval { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_usec: ((timeout.tv_nsec + 999) / 1000) as _, - }; - &timeout_data - } - None => null(), - }; - - // On Apple platforms, use the specially mangled `select` which doesn't - // have an `FD_SETSIZE` limitation. - #[cfg(apple)] - { - extern "C" { - #[link_name = "select$DARWIN_EXTSN$NOCANCEL"] - fn select( - nfds: c::c_int, - readfds: *mut FdSetElement, - writefds: *mut FdSetElement, - errorfds: *mut FdSetElement, - timeout: *const c::timeval, - ) -> c::c_int; - } - - ret_c_int(select(nfds, readfds, writefds, exceptfds, timeout_ptr)) - } - - // Otherwise just use the normal `select`. - #[cfg(not(apple))] - { - ret_c_int(c::select( - nfds, - readfds.cast(), - writefds.cast(), - exceptfds.cast(), - timeout_ptr as *mut c::timeval, - )) - } -} - -// WASI uses a count + array instead of a bitvector. -#[cfg(target_os = "wasi")] -pub(crate) unsafe fn select( - nfds: i32, - readfds: Option<&mut [FdSetElement]>, - writefds: Option<&mut [FdSetElement]>, - exceptfds: Option<&mut [FdSetElement]>, - timeout: Option<&Timespec>, -) -> io::Result<i32> { - let len = crate::event::fd_set_num_elements_for_fd_array(nfds as usize); - - let readfds = match readfds { - Some(readfds) => { - assert!(readfds.len() >= len); - readfds.as_mut_ptr() - } - None => null_mut(), - }; - let writefds = match writefds { - Some(writefds) => { - assert!(writefds.len() >= len); - writefds.as_mut_ptr() - } - None => null_mut(), - }; - let exceptfds = match exceptfds { - Some(exceptfds) => { - assert!(exceptfds.len() >= len); - exceptfds.as_mut_ptr() - } - None => null_mut(), - }; - - let timeout_data; - let timeout_ptr = match timeout { - Some(timeout) => { - // Convert from `Timespec` to `c::timeval`. - timeout_data = c::timeval { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_usec: ((timeout.tv_nsec + 999) / 1000) as _, - }; - &timeout_data - } - None => null(), - }; - - ret_c_int(c::select( - nfds, - readfds.cast(), - writefds.cast(), - exceptfds.cast(), - timeout_ptr as *mut c::timeval, - )) -} - -#[cfg(solarish)] -pub(crate) fn port_create() -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::port_create()) } -} - -#[cfg(solarish)] -pub(crate) unsafe fn port_associate( - port: BorrowedFd<'_>, - source: c::c_int, - object: c::uintptr_t, - events: c::c_int, - user: *mut c::c_void, -) -> io::Result<()> { - ret(c::port_associate( - borrowed_fd(port), - source, - object, - events, - user, - )) -} - -#[cfg(solarish)] -pub(crate) unsafe fn port_dissociate( - port: BorrowedFd<'_>, - source: c::c_int, - object: c::uintptr_t, -) -> io::Result<()> { - ret(c::port_dissociate(borrowed_fd(port), source, object)) -} - -#[cfg(solarish)] -pub(crate) fn port_get(port: BorrowedFd<'_>, timeout: Option<&Timespec>) -> io::Result<Event> { - // If we don't have to fix y2038 on this platform, `Timespec` is - // the same as `c::timespec` and it's easy. - #[cfg(not(fix_y2038))] - let timeout = crate::timespec::option_as_libc_timespec_ptr(timeout); - - // If we do have to fix y2038 on this platform, convert to - // `c::timespec`. - #[cfg(fix_y2038)] - let converted_timeout; - #[cfg(fix_y2038)] - let timeout = match timeout { - None => null(), - Some(timeout) => { - converted_timeout = c::timespec { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: timeout.tv_nsec as _, - }; - &converted_timeout - } - }; - - let mut event = MaybeUninit::<c::port_event>::uninit(); - - // In Rust ≥ 1.65, the `as _` can be `.cast_mut()`. - unsafe { - ret(c::port_get( - borrowed_fd(port), - event.as_mut_ptr(), - timeout as _, - ))?; - } - - // If we're done, initialize the event and return it. - Ok(Event(unsafe { event.assume_init() })) -} - -#[cfg(solarish)] -pub(crate) unsafe fn port_getn( - port: BorrowedFd<'_>, - events: (*mut Event, usize), - mut nget: u32, - timeout: Option<&Timespec>, -) -> io::Result<usize> { - // If we don't have to fix y2038 on this platform, `Timespec` is - // the same as `c::timespec` and it's easy. - #[cfg(not(fix_y2038))] - let timeout = crate::timespec::option_as_libc_timespec_ptr(timeout); - - // If we do have to fix y2038 on this platform, convert to - // `c::timespec`. - #[cfg(fix_y2038)] - let converted_timeout; - #[cfg(fix_y2038)] - let timeout = match timeout { - None => null(), - Some(timeout) => { - converted_timeout = c::timespec { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: timeout.tv_nsec as _, - }; - &converted_timeout - } - }; - - // `port_getn` special-cases a max value of 0 to be a query that returns - // the number of events, so bail out early if needed. - if events.1 == 0 { - return Ok(0); - } - - // In Rust ≥ 1.65, the `as _` can be `.cast_mut()`. - ret(c::port_getn( - borrowed_fd(port), - events.0.cast(), - events.1.try_into().unwrap_or(u32::MAX), - &mut nget, - timeout as _, - ))?; - - Ok(nget as usize) -} - -#[cfg(solarish)] -pub(crate) fn port_getn_query(port: BorrowedFd<'_>) -> io::Result<u32> { - let mut nget: u32 = 0; - - // Pass a `max` of 0 to query the number of available events. - unsafe { - ret(c::port_getn( - borrowed_fd(port), - null_mut(), - 0, - &mut nget, - null_mut(), - ))?; - } - - Ok(nget) -} - -#[cfg(solarish)] -pub(crate) fn port_send( - port: BorrowedFd<'_>, - events: c::c_int, - userdata: *mut c::c_void, -) -> io::Result<()> { - unsafe { ret(c::port_send(borrowed_fd(port), events, userdata)) } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn pause() { - let r = unsafe { c::pause() }; - let errno = libc_errno::errno().0; - debug_assert_eq!(r, -1); - debug_assert_eq!(errno, c::EINTR); -} - -#[inline] -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub(crate) fn epoll_create(flags: super::epoll::CreateFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::epoll_create1(bitflags_bits!(flags))) } -} - -#[inline] -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub(crate) fn epoll_add( - epoll: BorrowedFd<'_>, - source: BorrowedFd<'_>, - event: &crate::event::epoll::Event, -) -> io::Result<()> { - // We use our own `Event` struct instead of libc's because - // ours preserves pointer provenance instead of just using a `u64`, - // and we have tests elsewhere for layout equivalence. - unsafe { - ret(c::epoll_ctl( - borrowed_fd(epoll), - c::EPOLL_CTL_ADD, - borrowed_fd(source), - // The event is read-only even though libc has a non-const pointer. - as_ptr(event) as *mut c::epoll_event, - )) - } -} - -#[inline] -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub(crate) fn epoll_mod( - epoll: BorrowedFd<'_>, - source: BorrowedFd<'_>, - event: &crate::event::epoll::Event, -) -> io::Result<()> { - unsafe { - ret(c::epoll_ctl( - borrowed_fd(epoll), - c::EPOLL_CTL_MOD, - borrowed_fd(source), - // The event is read-only even though libc has a non-const pointer. - as_ptr(event) as *mut c::epoll_event, - )) - } -} - -#[inline] -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub(crate) fn epoll_del(epoll: BorrowedFd<'_>, source: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(c::epoll_ctl( - borrowed_fd(epoll), - c::EPOLL_CTL_DEL, - borrowed_fd(source), - null_mut(), - )) - } -} - -#[inline] -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub(crate) unsafe fn epoll_wait( - epoll: BorrowedFd<'_>, - events: (*mut crate::event::epoll::Event, usize), - timeout: Option<&Timespec>, -) -> io::Result<usize> { - // If we're on Linux ≥ 5.11 and a libc that has an `epoll_pwait2` - // function, and it's y2038-safe, use it. - #[cfg(all( - linux_kernel, - feature = "linux_5_11", - target_env = "gnu", - not(fix_y2038) - ))] - { - weak! { - fn epoll_pwait2( - c::c_int, - *mut c::epoll_event, - c::c_int, - *const c::timespec, - *const c::sigset_t - ) -> c::c_int - } - - if let Some(epoll_pwait2_func) = epoll_pwait2.get() { - return ret_u32(epoll_pwait2_func( - borrowed_fd(epoll), - events.0.cast::<c::epoll_event>(), - events.1.try_into().unwrap_or(i32::MAX), - crate::utils::option_as_ptr(timeout).cast(), - null(), - )) - .map(|i| i as usize); - } - } - - // If we're on Linux ≥ 5.11, use `epoll_pwait2` via `libc::syscall`. - #[cfg(all(linux_kernel, feature = "linux_5_11"))] - { - syscall! { - fn epoll_pwait2( - epfd: c::c_int, - events: *mut c::epoll_event, - maxevents: c::c_int, - timeout: *const Timespec, - sigmask: *const c::sigset_t - ) via SYS_epoll_pwait2 -> c::c_int - } - - ret_u32(epoll_pwait2( - borrowed_fd(epoll), - events.0.cast::<c::epoll_event>(), - events.1.try_into().unwrap_or(i32::MAX), - crate::utils::option_as_ptr(timeout).cast(), - null(), - )) - .map(|i| i as usize) - } - - // Otherwise just use `epoll_wait`. - #[cfg(not(all(linux_kernel, feature = "linux_5_11")))] - { - let timeout = match timeout { - None => -1, - Some(timeout) => timeout.as_c_int_millis().ok_or(io::Errno::INVAL)?, - }; - - ret_u32(c::epoll_wait( - borrowed_fd(epoll), - events.0.cast::<c::epoll_event>(), - events.1.try_into().unwrap_or(i32::MAX), - timeout, - )) - .map(|i| i as usize) - } -} diff --git a/vendor/rustix/src/backend/libc/event/types.rs b/vendor/rustix/src/backend/libc/event/types.rs deleted file mode 100644 index a04d7e6c..00000000 --- a/vendor/rustix/src/backend/libc/event/types.rs +++ /dev/null @@ -1,37 +0,0 @@ -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "illumos"))] -use crate::backend::c; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf" -))] -use bitflags::bitflags; - -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf" -))] -bitflags! { - /// `EFD_*` flags for use with [`eventfd`]. - /// - /// [`eventfd`]: crate::event::eventfd - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct EventfdFlags: u32 { - /// `EFD_CLOEXEC` - #[cfg(not(target_os = "espidf"))] - const CLOEXEC = bitcast!(c::EFD_CLOEXEC); - /// `EFD_NONBLOCK` - #[cfg(not(target_os = "espidf"))] - const NONBLOCK = bitcast!(c::EFD_NONBLOCK); - /// `EFD_SEMAPHORE` - #[cfg(not(target_os = "espidf"))] - const SEMAPHORE = bitcast!(c::EFD_SEMAPHORE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/event/windows_syscalls.rs b/vendor/rustix/src/backend/libc/event/windows_syscalls.rs deleted file mode 100644 index 05394f55..00000000 --- a/vendor/rustix/src/backend/libc/event/windows_syscalls.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Windows system calls in the `event` module. - -use crate::backend::c; -use crate::backend::conv::ret_c_int; -use crate::event::{FdSetElement, PollFd, Timespec}; -use crate::io; - -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: Option<&Timespec>) -> io::Result<usize> { - let nfds = fds - .len() - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - - let timeout = match timeout { - None => -1, - Some(timeout) => timeout.as_c_int_millis().ok_or(io::Errno::INVAL)?, - }; - - ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) - .map(|nready| nready as usize) -} - -pub(crate) fn select( - nfds: i32, - readfds: Option<&mut [FdSetElement]>, - writefds: Option<&mut [FdSetElement]>, - exceptfds: Option<&mut [FdSetElement]>, - timeout: Option<&crate::timespec::Timespec>, -) -> io::Result<i32> { - use core::ptr::{null, null_mut}; - - let readfds = match readfds { - Some(readfds) => { - assert!(readfds.len() >= readfds[0].0 as usize); - readfds.as_mut_ptr() - } - None => null_mut(), - }; - let writefds = match writefds { - Some(writefds) => { - assert!(writefds.len() >= writefds[0].0 as usize); - writefds.as_mut_ptr() - } - None => null_mut(), - }; - let exceptfds = match exceptfds { - Some(exceptfds) => { - assert!(exceptfds.len() >= exceptfds[0].0 as usize); - exceptfds.as_mut_ptr() - } - None => null_mut(), - }; - - let timeout_data; - let timeout_ptr = match timeout { - Some(timeout) => { - // Convert from `Timespec` to `TIMEVAL`. - timeout_data = c::TIMEVAL { - tv_sec: timeout - .tv_sec - .try_into() - .map_err(|_| io::Errno::OPNOTSUPP)?, - tv_usec: ((timeout.tv_nsec + 999) / 1000) as _, - }; - &timeout_data - } - None => null(), - }; - - unsafe { - ret_c_int(c::select( - nfds, - readfds.cast(), - writefds.cast(), - exceptfds.cast(), - timeout_ptr, - )) - } -} diff --git a/vendor/rustix/src/backend/libc/fs/dir.rs b/vendor/rustix/src/backend/libc/fs/dir.rs deleted file mode 100644 index cd7f232d..00000000 --- a/vendor/rustix/src/backend/libc/fs/dir.rs +++ /dev/null @@ -1,497 +0,0 @@ -#[cfg(not(any( - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "vita" -)))] -use super::types::FileType; -use crate::backend::c; -use crate::backend::conv::owned_fd; -use crate::fd::{AsFd, BorrowedFd, OwnedFd}; -use crate::ffi::{CStr, CString}; -use crate::fs::{fcntl_getfl, openat, Mode, OFlags}; -#[cfg(not(target_os = "vita"))] -use crate::fs::{fstat, Stat}; -#[cfg(not(any( - solarish, - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use crate::fs::{fstatfs, StatFs}; -#[cfg(not(any( - solarish, - target_os = "haiku", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::fs::{fstatvfs, StatVfs}; -use crate::io; -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -#[cfg(feature = "process")] -use crate::process::fchdir; -use alloc::borrow::ToOwned as _; -#[cfg(not(any(linux_like, target_os = "hurd")))] -use c::readdir as libc_readdir; -#[cfg(any(linux_like, target_os = "hurd"))] -use c::readdir64 as libc_readdir; -use core::fmt; -use core::ptr::NonNull; -use libc_errno::{errno, set_errno, Errno}; - -/// `DIR*` -pub struct Dir { - /// The `libc` `DIR` pointer. - libc_dir: NonNull<c::DIR>, - - /// Have we seen any errors in this iteration? - any_errors: bool, -} - -impl Dir { - /// Take ownership of `fd` and construct a `Dir` that reads entries from - /// the given directory file descriptor. - #[inline] - pub fn new<Fd: Into<OwnedFd>>(fd: Fd) -> io::Result<Self> { - Self::_new(fd.into()) - } - - #[inline] - fn _new(fd: OwnedFd) -> io::Result<Self> { - let raw = owned_fd(fd); - unsafe { - let libc_dir = c::fdopendir(raw); - - if let Some(libc_dir) = NonNull::new(libc_dir) { - Ok(Self { - libc_dir, - any_errors: false, - }) - } else { - let err = io::Errno::last_os_error(); - let _ = c::close(raw); - Err(err) - } - } - } - - /// Borrow `fd` and construct a `Dir` that reads entries from the given - /// directory file descriptor. - #[inline] - pub fn read_from<Fd: AsFd>(fd: Fd) -> io::Result<Self> { - Self::_read_from(fd.as_fd()) - } - - #[inline] - #[allow(unused_mut)] - fn _read_from(fd: BorrowedFd<'_>) -> io::Result<Self> { - let mut any_errors = false; - - // Given an arbitrary `OwnedFd`, it's impossible to know whether the - // user holds a `dup`'d copy which could continue to modify the - // file description state, which would cause Undefined Behavior after - // our call to `fdopendir`. To prevent this, we obtain an independent - // `OwnedFd`. - let flags = fcntl_getfl(fd)?; - let fd_for_dir = match openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty()) { - Ok(fd) => fd, - #[cfg(not(target_os = "wasi"))] - Err(io::Errno::NOENT) => { - // If "." doesn't exist, it means the directory was removed. - // We treat that as iterating through a directory with no - // entries. - any_errors = true; - crate::io::dup(fd)? - } - Err(err) => return Err(err), - }; - - let raw = owned_fd(fd_for_dir); - unsafe { - let libc_dir = c::fdopendir(raw); - - if let Some(libc_dir) = NonNull::new(libc_dir) { - Ok(Self { - libc_dir, - any_errors, - }) - } else { - let err = io::Errno::last_os_error(); - let _ = c::close(raw); - Err(err) - } - } - } - - /// `rewinddir(self)` - #[inline] - pub fn rewind(&mut self) { - self.any_errors = false; - unsafe { c::rewinddir(self.libc_dir.as_ptr()) } - } - - /// `seekdir(self, offset)` - /// - /// This function is only available on 64-bit platforms because it's - /// implemented using [`libc::seekdir`] which only supports offsets that - /// fit in a `c_long`. - /// - /// [`libc::seekdir`]: https://docs.rs/libc/*/arm-unknown-linux-gnueabihf/libc/fn.seekdir.html - #[cfg(target_pointer_width = "64")] - #[cfg_attr(docsrs, doc(cfg(target_pointer_width = "64")))] - #[doc(alias = "seekdir")] - #[inline] - pub fn seek(&mut self, offset: i64) -> io::Result<()> { - self.any_errors = false; - unsafe { c::seekdir(self.libc_dir.as_ptr(), offset) } - Ok(()) - } - - /// `readdir(self)`, where `None` means the end of the directory. - pub fn read(&mut self) -> Option<io::Result<DirEntry>> { - // If we've seen errors, don't continue to try to read anything - // further. - if self.any_errors { - return None; - } - - set_errno(Errno(0)); - let dirent_ptr = unsafe { libc_readdir(self.libc_dir.as_ptr()) }; - if dirent_ptr.is_null() { - let curr_errno = errno().0; - if curr_errno == 0 { - // We successfully reached the end of the stream. - None - } else { - // `errno` is unknown or non-zero, so an error occurred. - self.any_errors = true; - Some(Err(io::Errno(curr_errno))) - } - } else { - // We successfully read an entry. - unsafe { - let dirent = &*dirent_ptr; - - // We have our own copy of OpenBSD's dirent; check that the - // layout minimally matches libc's. - #[cfg(target_os = "openbsd")] - check_dirent_layout(dirent); - - let result = DirEntry { - #[cfg(not(any( - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - )))] - d_type: dirent.d_type, - - #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] - d_ino: dirent.d_ino, - - #[cfg(any( - linux_like, - solarish, - target_os = "fuchsia", - target_os = "hermit", - target_os = "openbsd", - target_os = "redox" - ))] - d_off: dirent.d_off, - - #[cfg(any(freebsdlike, netbsdlike))] - d_fileno: dirent.d_fileno, - - name: CStr::from_ptr(dirent.d_name.as_ptr().cast()).to_owned(), - }; - - Some(Ok(result)) - } - } - } - - /// `fstat(self)` - #[cfg(not(any(target_os = "horizon", target_os = "vita")))] - #[inline] - pub fn stat(&self) -> io::Result<Stat> { - fstat(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) - } - - /// `fstatfs(self)` - #[cfg(not(any( - solarish, - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", - )))] - #[inline] - pub fn statfs(&self) -> io::Result<StatFs> { - fstatfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) - } - - /// `fstatvfs(self)` - #[cfg(not(any( - solarish, - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" - )))] - #[inline] - pub fn statvfs(&self) -> io::Result<StatVfs> { - fstatvfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) - } - - /// `fchdir(self)` - #[cfg(feature = "process")] - #[cfg(not(any( - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" - )))] - #[cfg_attr(docsrs, doc(cfg(feature = "process")))] - #[inline] - pub fn chdir(&self) -> io::Result<()> { - fchdir(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) - } -} - -/// `Dir` is `Send` and `Sync`, because even though it contains internal -/// state, all methods that modify the state require a `mut &self` and -/// can therefore not be called concurrently. Calling them from different -/// threads sequentially is fine. -unsafe impl Send for Dir {} -unsafe impl Sync for Dir {} - -impl Drop for Dir { - #[inline] - fn drop(&mut self) { - unsafe { c::closedir(self.libc_dir.as_ptr()) }; - } -} - -impl Iterator for Dir { - type Item = io::Result<DirEntry>; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - Self::read(self) - } -} - -impl fmt::Debug for Dir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("Dir"); - #[cfg(not(any(target_os = "horizon", target_os = "vita")))] - s.field("fd", unsafe { &c::dirfd(self.libc_dir.as_ptr()) }); - s.finish() - } -} - -/// `struct dirent` -#[derive(Debug)] -pub struct DirEntry { - #[cfg(not(any( - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - )))] - d_type: u8, - - #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] - d_ino: c::ino_t, - - #[cfg(any(freebsdlike, netbsdlike))] - d_fileno: c::ino_t, - - name: CString, - - #[cfg(any( - linux_like, - solarish, - target_os = "fuchsia", - target_os = "hermit", - target_os = "openbsd", - target_os = "redox" - ))] - d_off: c::off_t, -} - -impl DirEntry { - /// Returns the file name of this directory entry. - #[inline] - pub fn file_name(&self) -> &CStr { - &self.name - } - - /// Returns the “offset” of this directory entry. This is not a true - /// numerical offset but an opaque cookie that identifies a position in the - /// given stream. - #[cfg(any( - linux_like, - solarish, - target_os = "fuchsia", - target_os = "hermit", - target_os = "openbsd", - target_os = "redox" - ))] - #[inline] - pub fn offset(&self) -> i64 { - self.d_off as i64 - } - - /// Returns the type of this directory entry. - #[cfg(not(any( - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - )))] - #[inline] - pub fn file_type(&self) -> FileType { - FileType::from_dirent_d_type(self.d_type) - } - - /// Return the inode number of this directory entry. - #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] - #[inline] - pub fn ino(&self) -> u64 { - self.d_ino as u64 - } - - /// Return the inode number of this directory entry. - #[cfg(any(freebsdlike, netbsdlike))] - #[inline] - pub fn ino(&self) -> u64 { - #[allow(clippy::useless_conversion)] - self.d_fileno.into() - } -} - -/// libc's OpenBSD `dirent` has a private field so we can't construct it -/// directly, so we declare it ourselves to make all fields accessible. -#[cfg(target_os = "openbsd")] -#[repr(C)] -#[derive(Debug)] -struct libc_dirent { - d_fileno: c::ino_t, - d_off: c::off_t, - d_reclen: u16, - d_type: u8, - d_namlen: u8, - __d_padding: [u8; 4], - d_name: [c::c_char; 256], -} - -/// We have our own copy of OpenBSD's dirent; check that the layout -/// minimally matches libc's. -#[cfg(target_os = "openbsd")] -fn check_dirent_layout(dirent: &c::dirent) { - use crate::utils::as_ptr; - - // Check that the basic layouts match. - #[cfg(test)] - { - assert_eq_size!(libc_dirent, c::dirent); - assert_eq_size!(libc_dirent, c::dirent); - } - - // Check that the field offsets match. - assert_eq!( - { - let z = libc_dirent { - d_fileno: 0_u64, - d_off: 0_i64, - d_reclen: 0_u16, - d_type: 0_u8, - d_namlen: 0_u8, - __d_padding: [0_u8; 4], - d_name: [0 as c::c_char; 256], - }; - let base = as_ptr(&z) as usize; - ( - (as_ptr(&z.d_fileno) as usize) - base, - (as_ptr(&z.d_off) as usize) - base, - (as_ptr(&z.d_reclen) as usize) - base, - (as_ptr(&z.d_type) as usize) - base, - (as_ptr(&z.d_namlen) as usize) - base, - (as_ptr(&z.d_name) as usize) - base, - ) - }, - { - let z = dirent; - let base = as_ptr(z) as usize; - ( - (as_ptr(&z.d_fileno) as usize) - base, - (as_ptr(&z.d_off) as usize) - base, - (as_ptr(&z.d_reclen) as usize) - base, - (as_ptr(&z.d_type) as usize) - base, - (as_ptr(&z.d_namlen) as usize) - base, - (as_ptr(&z.d_name) as usize) - base, - ) - } - ); -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn dir_iterator_handles_io_errors() { - // create a dir, keep the FD, then delete the dir - let tmp = tempfile::tempdir().unwrap(); - let fd = crate::fs::openat( - crate::fs::CWD, - tmp.path(), - crate::fs::OFlags::RDONLY | crate::fs::OFlags::CLOEXEC, - crate::fs::Mode::empty(), - ) - .unwrap(); - - let file_fd = crate::fs::openat( - &fd, - tmp.path().join("test.txt"), - crate::fs::OFlags::WRONLY | crate::fs::OFlags::CREATE, - crate::fs::Mode::RWXU, - ) - .unwrap(); - - let mut dir = Dir::read_from(&fd).unwrap(); - - // Reach inside the `Dir` and replace its directory with a file, which - // will cause the subsequent `readdir` to fail. - unsafe { - let raw_fd = c::dirfd(dir.libc_dir.as_ptr()); - let mut owned_fd: crate::fd::OwnedFd = crate::fd::FromRawFd::from_raw_fd(raw_fd); - crate::io::dup2(&file_fd, &mut owned_fd).unwrap(); - core::mem::forget(owned_fd); - } - - // FreeBSD and macOS seem to read some directory entries before we call - // `.next()`. - #[cfg(any(apple, freebsdlike))] - { - dir.rewind(); - } - - assert!(matches!(dir.next(), Some(Err(_)))); - assert!(dir.next().is_none()); - } -} diff --git a/vendor/rustix/src/backend/libc/fs/inotify.rs b/vendor/rustix/src/backend/libc/fs/inotify.rs deleted file mode 100644 index 89745fb7..00000000 --- a/vendor/rustix/src/backend/libc/fs/inotify.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! inotify support for working with inotify objects. - -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `IN_*` for use with [`inotify::init`]. - /// - /// [`inotify::init`]: crate::fs::inotify::init - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CreateFlags: u32 { - /// `IN_CLOEXEC` - const CLOEXEC = bitcast!(c::IN_CLOEXEC); - /// `IN_NONBLOCK` - const NONBLOCK = bitcast!(c::IN_NONBLOCK); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `IN*` for use with [`inotify::add_watch`]. - /// - /// [`inotify::add_watch`]: crate::fs::inotify::add_watch - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WatchFlags: u32 { - /// `IN_ACCESS` - const ACCESS = c::IN_ACCESS; - /// `IN_ATTRIB` - const ATTRIB = c::IN_ATTRIB; - /// `IN_CLOSE_NOWRITE` - const CLOSE_NOWRITE = c::IN_CLOSE_NOWRITE; - /// `IN_CLOSE_WRITE` - const CLOSE_WRITE = c::IN_CLOSE_WRITE; - /// `IN_CREATE` - const CREATE = c::IN_CREATE; - /// `IN_DELETE` - const DELETE = c::IN_DELETE; - /// `IN_DELETE_SELF` - const DELETE_SELF = c::IN_DELETE_SELF; - /// `IN_MODIFY` - const MODIFY = c::IN_MODIFY; - /// `IN_MOVE_SELF` - const MOVE_SELF = c::IN_MOVE_SELF; - /// `IN_MOVED_FROM` - const MOVED_FROM = c::IN_MOVED_FROM; - /// `IN_MOVED_TO` - const MOVED_TO = c::IN_MOVED_TO; - /// `IN_OPEN` - const OPEN = c::IN_OPEN; - - /// `IN_CLOSE` - const CLOSE = c::IN_CLOSE; - /// `IN_MOVE` - const MOVE = c::IN_MOVE; - /// `IN_ALL_EVENTS` - const ALL_EVENTS = c::IN_ALL_EVENTS; - - /// `IN_DONT_FOLLOW` - const DONT_FOLLOW = c::IN_DONT_FOLLOW; - /// `IN_EXCL_UNLINK` - const EXCL_UNLINK = 1; - /// `IN_MASK_ADD` - const MASK_ADD = 1; - /// `IN_MASK_CREATE` - const MASK_CREATE = 1; - /// `IN_ONESHOT` - const ONESHOT = c::IN_ONESHOT; - /// `IN_ONLYDIR` - const ONLYDIR = c::IN_ONLYDIR; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `IN*` for use with [`inotify::Reader`]. - /// - /// [`inotify::Reader`]: crate::fs::inotify::Reader - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReadFlags: u32 { - /// `IN_ACCESS` - const ACCESS = c::IN_ACCESS; - /// `IN_ATTRIB` - const ATTRIB = c::IN_ATTRIB; - /// `IN_CLOSE_NOWRITE` - const CLOSE_NOWRITE = c::IN_CLOSE_NOWRITE; - /// `IN_CLOSE_WRITE` - const CLOSE_WRITE = c::IN_CLOSE_WRITE; - /// `IN_CREATE` - const CREATE = c::IN_CREATE; - /// `IN_DELETE` - const DELETE = c::IN_DELETE; - /// `IN_DELETE_SELF` - const DELETE_SELF = c::IN_DELETE_SELF; - /// `IN_MODIFY` - const MODIFY = c::IN_MODIFY; - /// `IN_MOVE_SELF` - const MOVE_SELF = c::IN_MOVE_SELF; - /// `IN_MOVED_FROM` - const MOVED_FROM = c::IN_MOVED_FROM; - /// `IN_MOVED_TO` - const MOVED_TO = c::IN_MOVED_TO; - /// `IN_OPEN` - const OPEN = c::IN_OPEN; - - /// `IN_IGNORED` - const IGNORED = c::IN_IGNORED; - /// `IN_ISDIR` - const ISDIR = c::IN_ISDIR; - /// `IN_Q_OVERFLOW` - const QUEUE_OVERFLOW = c::IN_Q_OVERFLOW; - /// `IN_UNMOUNT` - const UNMOUNT = c::IN_UNMOUNT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/fs/makedev.rs b/vendor/rustix/src/backend/libc/fs/makedev.rs deleted file mode 100644 index a5521184..00000000 --- a/vendor/rustix/src/backend/libc/fs/makedev.rs +++ /dev/null @@ -1,144 +0,0 @@ -// TODO: Remove the unsafe blocks. libc 0.2.171 removed `unsafe` from several -// of these functions. Eventually we should depend on that version and remove -// the `unsafe` blocks in the code, but for now, disable that warning so that -// we're compatible with older libc versions. -#![allow(unused_unsafe)] - -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -use crate::backend::c; -use crate::fs::Dev; - -#[cfg(not(any( - apple, - solarish, - target_os = "aix", - target_os = "android", - target_os = "emscripten", -)))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - c::makedev(maj, min) -} - -#[cfg(solarish)] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // SAFETY: Solarish's `makedev` is marked unsafe but it isn't doing - // anything unsafe. - unsafe { c::makedev(maj, min) } -} - -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - c::makedev(maj, min) -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, so we do - // it ourselves. - ((u64::from(maj) & 0xffff_f000_u64) << 32) - | ((u64::from(maj) & 0x0000_0fff_u64) << 8) - | ((u64::from(min) & 0xffff_ff00_u64) << 12) - | (u64::from(min) & 0x0000_00ff_u64) -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // Emscripten's `makedev` has a 32-bit return value. - Dev::from(c::makedev(maj, min)) -} - -#[cfg(apple)] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // Apple's `makedev` oddly has signed argument types and is `unsafe`. - unsafe { c::makedev(maj as i32, min as i32) } -} - -#[cfg(target_os = "aix")] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // AIX's `makedev` oddly is `unsafe`. - unsafe { c::makedev(maj, min) } -} - -#[cfg(not(any( - apple, - freebsdlike, - target_os = "android", - target_os = "emscripten", - target_os = "netbsd" -)))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - unsafe { c::major(dev) } -} - -#[cfg(any( - apple, - freebsdlike, - target_os = "netbsd", - all(target_os = "android", not(target_pointer_width = "32")), -))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - // On some platforms `major` oddly has signed return types. - (unsafe { c::major(dev) }) as u32 -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, so we do - // it ourselves. - (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - // Emscripten's `major` has a 32-bit argument value. - unsafe { c::major(dev as u32) } -} - -#[cfg(not(any( - apple, - freebsdlike, - target_os = "android", - target_os = "emscripten", - target_os = "netbsd" -)))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - unsafe { c::minor(dev) } -} - -#[cfg(any( - apple, - freebsdlike, - target_os = "netbsd", - all(target_os = "android", not(target_pointer_width = "32")) -))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - // On some platforms, `minor` oddly has signed return types. - (unsafe { c::minor(dev) }) as u32 -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, so we do - // it ourselves. - (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - // Emscripten's `minor` has a 32-bit argument value. - unsafe { c::minor(dev as u32) } -} diff --git a/vendor/rustix/src/backend/libc/fs/mod.rs b/vendor/rustix/src/backend/libc/fs/mod.rs deleted file mode 100644 index 264b955c..00000000 --- a/vendor/rustix/src/backend/libc/fs/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[cfg(all(feature = "alloc", not(any(target_os = "espidf", target_os = "redox"))))] -pub(crate) mod dir; -#[cfg(linux_kernel)] -pub mod inotify; -#[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub(crate) mod makedev; -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; - -// TODO: Fix linux-raw-sys to define ioctl codes for sparc. -#[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))] -pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::Opcode = 0x8008_6610; - -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] -pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::Opcode = - linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS as crate::ioctl::Opcode; diff --git a/vendor/rustix/src/backend/libc/fs/syscalls.rs b/vendor/rustix/src/backend/libc/fs/syscalls.rs deleted file mode 100644 index f2ac4f73..00000000 --- a/vendor/rustix/src/backend/libc/fs/syscalls.rs +++ /dev/null @@ -1,2721 +0,0 @@ -//! libc syscalls supporting `rustix::fs`. - -use crate::backend::c; -#[cfg(any(not(target_os = "redox"), feature = "alloc"))] -use crate::backend::conv::ret_usize; -use crate::backend::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd}; -use crate::fd::{BorrowedFd, OwnedFd}; -#[allow(unused_imports)] -use crate::ffi; -use crate::ffi::CStr; -#[cfg(all(apple, feature = "alloc"))] -use crate::ffi::CString; -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -use crate::fs::Access; -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -use crate::fs::AtFlags; -#[cfg(not(any( - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -use crate::fs::FallocateFlags; -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -use crate::fs::FlockOperation; -#[cfg(any(linux_kernel, target_os = "freebsd"))] -use crate::fs::MemfdFlags; -#[cfg(any(linux_kernel, apple))] -use crate::fs::RenameFlags; -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -use crate::fs::SealFlags; -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use crate::fs::StatFs; -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] -use crate::fs::Timestamps; -#[cfg(not(any( - apple, - target_os = "espidf", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::fs::{Dev, FileType}; -use crate::fs::{Mode, OFlags, SeekFrom, Stat}; -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -use crate::fs::{StatVfs, StatVfsMountFlags}; -use crate::io; -#[cfg(all(target_env = "gnu", fix_y2038))] -use crate::timespec::LibcTimespec; -#[cfg(not(target_os = "wasi"))] -use crate::ugid::{Gid, Uid}; -#[cfg(all(apple, feature = "alloc"))] -use alloc::vec; -use core::mem::MaybeUninit; -#[cfg(apple)] -use { - crate::backend::conv::nonnegative_ret, - crate::fs::{copyfile_state_t, CloneFlags, CopyfileFlags}, -}; -#[cfg(not(any( - apple, - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -use {crate::fs::Advice, core::num::NonZeroU64}; -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -use {crate::fs::XattrFlags, core::mem::size_of, core::ptr::null_mut}; -#[cfg(linux_kernel)] -use { - crate::fs::{ResolveFlags, Statx, StatxFlags, CWD}, - core::ptr::null, -}; - -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __utimensat64(c::c_int, *const ffi::c_char, *const LibcTimespec, c::c_int) -> c::c_int); -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __futimens64(c::c_int, *const LibcTimespec) -> c::c_int); - -/// Use a direct syscall (via libc) for `open`. -/// -/// This is only currently necessary as a workaround for old glibc; see below. -#[cfg(all(unix, target_env = "gnu"))] -fn open_via_syscall(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<OwnedFd> { - // Linux on aarch64, loongarch64 and riscv64 has no `open` syscall so use - // `openat`. - #[cfg(any( - target_arch = "aarch64", - target_arch = "riscv32", - target_arch = "riscv64", - target_arch = "csky", - target_arch = "loongarch64" - ))] - { - openat_via_syscall(CWD, path, oflags, mode) - } - - // Use the `open` syscall. - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "riscv32", - target_arch = "riscv64", - target_arch = "csky", - target_arch = "loongarch64" - )))] - unsafe { - syscall! { - fn open( - pathname: *const ffi::c_char, - oflags: c::c_int, - mode: c::mode_t - ) via SYS_open -> c::c_int - } - - ret_owned_fd(open( - c_str(path), - bitflags_bits!(oflags), - bitflags_bits!(mode), - )) - } -} - -pub(crate) fn open(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<OwnedFd> { - // Work around <https://sourceware.org/bugzilla/show_bug.cgi?id=17523>. - // glibc versions before 2.25 don't handle `O_TMPFILE` correctly. - #[cfg(all( - unix, - target_env = "gnu", - not(target_os = "hurd"), - not(target_os = "freebsd") - ))] - if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { - return open_via_syscall(path, oflags, mode); - } - - // On these platforms, `mode_t` is `u16` and can't be passed directly to a - // variadic function. - #[cfg(any( - apple, - freebsdlike, - all(target_os = "android", target_pointer_width = "32") - ))] - let mode: c::c_uint = mode.bits().into(); - - // Otherwise, cast to `mode_t` as that's what `open` is documented to take. - #[cfg(not(any( - apple, - freebsdlike, - all(target_os = "android", target_pointer_width = "32") - )))] - let mode: c::mode_t = mode.bits() as _; - - unsafe { ret_owned_fd(c::open(c_str(path), bitflags_bits!(oflags), mode)) } -} - -/// Use a direct syscall (via libc) for `openat`. -/// -/// This is only currently necessary as a workaround for old glibc; see below. -#[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] -fn openat_via_syscall( - dirfd: BorrowedFd<'_>, - path: &CStr, - oflags: OFlags, - mode: Mode, -) -> io::Result<OwnedFd> { - syscall! { - fn openat( - base_dirfd: c::c_int, - pathname: *const ffi::c_char, - oflags: c::c_int, - mode: c::mode_t - ) via SYS_openat -> c::c_int - } - - unsafe { - ret_owned_fd(openat( - borrowed_fd(dirfd), - c_str(path), - bitflags_bits!(oflags), - bitflags_bits!(mode), - )) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn openat( - dirfd: BorrowedFd<'_>, - path: &CStr, - oflags: OFlags, - mode: Mode, -) -> io::Result<OwnedFd> { - // Work around <https://sourceware.org/bugzilla/show_bug.cgi?id=17523>. - // glibc versions before 2.25 don't handle `O_TMPFILE` correctly. - #[cfg(all( - unix, - target_env = "gnu", - not(target_os = "hurd"), - not(target_os = "freebsd") - ))] - if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { - return openat_via_syscall(dirfd, path, oflags, mode); - } - - // On these platforms, `mode_t` is `u16` and can't be passed directly to a - // variadic function. - #[cfg(any( - apple, - freebsdlike, - all(target_os = "android", target_pointer_width = "32") - ))] - let mode: c::c_uint = mode.bits().into(); - - // Otherwise, cast to `mode_t` as that's what `open` is documented to take. - #[cfg(not(any( - apple, - freebsdlike, - all(target_os = "android", target_pointer_width = "32") - )))] - let mode: c::mode_t = mode.bits() as _; - - unsafe { - ret_owned_fd(c::openat( - borrowed_fd(dirfd), - c_str(path), - bitflags_bits!(oflags), - mode, - )) - } -} - -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn statfs(filename: &CStr) -> io::Result<StatFs> { - unsafe { - let mut result = MaybeUninit::<StatFs>::uninit(); - ret(c::statfs(c_str(filename), result.as_mut_ptr()))?; - Ok(result.assume_init()) - } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn statvfs(filename: &CStr) -> io::Result<StatVfs> { - unsafe { - let mut result = MaybeUninit::<c::statvfs>::uninit(); - ret(c::statvfs(c_str(filename), result.as_mut_ptr()))?; - Ok(libc_statvfs_to_statvfs(result.assume_init())) - } -} - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { - unsafe { ret_usize(c::readlink(c_str(path), buf.as_mut_ptr().cast(), buf.len()) as isize) } -} - -#[cfg(not(target_os = "redox"))] -#[inline] -pub(crate) unsafe fn readlinkat( - dirfd: BorrowedFd<'_>, - path: &CStr, - buf: (*mut u8, usize), -) -> io::Result<usize> { - ret_usize(c::readlinkat(borrowed_fd(dirfd), c_str(path), buf.0.cast(), buf.1) as isize) -} - -pub(crate) fn mkdir(path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(c::mkdir(c_str(path), mode.bits() as c::mode_t)) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { - ret(c::mkdirat( - borrowed_fd(dirfd), - c_str(path), - mode.bits() as c::mode_t, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn getdents_uninit( - fd: BorrowedFd<'_>, - buf: &mut [MaybeUninit<u8>], -) -> io::Result<usize> { - syscall! { - fn getdents64( - fd: c::c_int, - dirp: *mut c::c_void, - count: usize - ) via SYS_getdents64 -> c::ssize_t - } - unsafe { - ret_usize(getdents64( - borrowed_fd(fd), - buf.as_mut_ptr().cast::<c::c_void>(), - buf.len(), - )) - } -} - -pub(crate) fn link(old_path: &CStr, new_path: &CStr) -> io::Result<()> { - unsafe { ret(c::link(c_str(old_path), c_str(new_path))) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub(crate) fn linkat( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: AtFlags, -) -> io::Result<()> { - // macOS ≤ 10.9 lacks `linkat`. - #[cfg(target_os = "macos")] - unsafe { - weak! { - fn linkat( - c::c_int, - *const ffi::c_char, - c::c_int, - *const ffi::c_char, - c::c_int - ) -> c::c_int - } - // If we have `linkat`, use it. - if let Some(libc_linkat) = linkat.get() { - return ret(libc_linkat( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - bitflags_bits!(flags), - )); - } - // Otherwise, see if we can emulate the `AT_FDCWD` case. - if borrowed_fd(old_dirfd) != c::AT_FDCWD || borrowed_fd(new_dirfd) != c::AT_FDCWD { - return Err(io::Errno::NOSYS); - } - if flags.intersects(!AtFlags::SYMLINK_FOLLOW) { - return Err(io::Errno::INVAL); - } - if !flags.is_empty() { - return Err(io::Errno::OPNOTSUPP); - } - ret(c::link(c_str(old_path), c_str(new_path))) - } - - #[cfg(not(target_os = "macos"))] - unsafe { - ret(c::linkat( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - bitflags_bits!(flags), - )) - } -} - -pub(crate) fn rmdir(path: &CStr) -> io::Result<()> { - unsafe { ret(c::rmdir(c_str(path))) } -} - -pub(crate) fn unlink(path: &CStr) -> io::Result<()> { - unsafe { ret(c::unlink(c_str(path))) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { - // macOS ≤ 10.9 lacks `unlinkat`. - #[cfg(target_os = "macos")] - unsafe { - weak! { - fn unlinkat( - c::c_int, - *const ffi::c_char, - c::c_int - ) -> c::c_int - } - // If we have `unlinkat`, use it. - if let Some(libc_unlinkat) = unlinkat.get() { - return ret(libc_unlinkat( - borrowed_fd(dirfd), - c_str(path), - bitflags_bits!(flags), - )); - } - // Otherwise, see if we can emulate the `AT_FDCWD` case. - if borrowed_fd(dirfd) != c::AT_FDCWD { - return Err(io::Errno::NOSYS); - } - if flags.intersects(!AtFlags::REMOVEDIR) { - return Err(io::Errno::INVAL); - } - if flags.contains(AtFlags::REMOVEDIR) { - ret(c::rmdir(c_str(path))) - } else { - ret(c::unlink(c_str(path))) - } - } - - #[cfg(not(target_os = "macos"))] - unsafe { - ret(c::unlinkat( - borrowed_fd(dirfd), - c_str(path), - bitflags_bits!(flags), - )) - } -} - -pub(crate) fn rename(old_path: &CStr, new_path: &CStr) -> io::Result<()> { - unsafe { ret(c::rename(c_str(old_path), c_str(new_path))) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn renameat( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, -) -> io::Result<()> { - // macOS ≤ 10.9 lacks `renameat`. - #[cfg(target_os = "macos")] - unsafe { - weak! { - fn renameat( - c::c_int, - *const ffi::c_char, - c::c_int, - *const ffi::c_char - ) -> c::c_int - } - // If we have `renameat`, use it. - if let Some(libc_renameat) = renameat.get() { - return ret(libc_renameat( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - )); - } - // Otherwise, see if we can emulate the `AT_FDCWD` case. - if borrowed_fd(old_dirfd) != c::AT_FDCWD || borrowed_fd(new_dirfd) != c::AT_FDCWD { - return Err(io::Errno::NOSYS); - } - ret(c::rename(c_str(old_path), c_str(new_path))) - } - - #[cfg(not(target_os = "macos"))] - unsafe { - ret(c::renameat( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - )) - } -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - // `renameat2` wasn't supported in glibc until 2.28. - weak_or_syscall! { - fn renameat2( - olddirfd: c::c_int, - oldpath: *const ffi::c_char, - newdirfd: c::c_int, - newpath: *const ffi::c_char, - flags: c::c_uint - ) via SYS_renameat2 -> c::c_int - } - - unsafe { - ret(renameat2( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - flags.bits(), - )) - } -} - -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - // At present, `libc` only has `renameat2` defined for glibc. If we have - // no flags, we can use plain `renameat`, but otherwise we use `syscall!`. - // to call `renameat2` ourselves. - if flags.is_empty() { - renameat(old_dirfd, old_path, new_dirfd, new_path) - } else { - syscall! { - fn renameat2( - olddirfd: c::c_int, - oldpath: *const ffi::c_char, - newdirfd: c::c_int, - newpath: *const ffi::c_char, - flags: c::c_uint - ) via SYS_renameat2 -> c::c_int - } - - unsafe { - ret(renameat2( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - flags.bits(), - )) - } - } -} - -#[cfg(apple)] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - unsafe { - // macOS < 10.12 lacks `renameatx_np`. - weak! { - fn renameatx_np( - c::c_int, - *const ffi::c_char, - c::c_int, - *const ffi::c_char, - c::c_uint - ) -> c::c_int - } - // If we have `renameatx_np`, use it. - if let Some(libc_renameatx_np) = renameatx_np.get() { - return ret(libc_renameatx_np( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - flags.bits(), - )); - } - // Otherwise, see if we can use `rename`. There's no point in trying - // `renamex_np` because it was added in the same macOS release as - // `renameatx_np`. - if !flags.is_empty() - || borrowed_fd(old_dirfd) != c::AT_FDCWD - || borrowed_fd(new_dirfd) != c::AT_FDCWD - { - return Err(io::Errno::NOSYS); - } - ret(c::rename(c_str(old_path), c_str(new_path))) - } -} - -pub(crate) fn symlink(old_path: &CStr, new_path: &CStr) -> io::Result<()> { - unsafe { ret(c::symlink(c_str(old_path), c_str(new_path))) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn symlinkat( - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, -) -> io::Result<()> { - unsafe { - ret(c::symlinkat( - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - )) - } -} - -pub(crate) fn stat(path: &CStr) -> io::Result<Stat> { - // See the comments in `fstat` about using `crate::fs::statx` here. - #[cfg(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - ))] - { - match crate::fs::statx(CWD, path, AtFlags::empty(), StatxFlags::BASIC_STATS) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(CWD, path, AtFlags::empty()), - Err(err) => Err(err), - } - } - - // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and - // there's nothing practical we can do. - #[cfg(not(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - )))] - unsafe { - #[cfg(test)] - assert_eq_size!(Stat, c::stat); - - let mut stat = MaybeUninit::<Stat>::uninit(); - ret(c::stat(c_str(path), stat.as_mut_ptr().cast()))?; - let stat = stat.assume_init(); - #[cfg(apple)] - let stat = fix_negative_stat_nsecs(stat); - Ok(stat) - } -} - -pub(crate) fn lstat(path: &CStr) -> io::Result<Stat> { - // See the comments in `fstat` about using `crate::fs::statx` here. - #[cfg(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - ))] - { - match crate::fs::statx( - CWD, - path, - AtFlags::SYMLINK_NOFOLLOW, - StatxFlags::BASIC_STATS, - ) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(CWD, path, AtFlags::SYMLINK_NOFOLLOW), - Err(err) => Err(err), - } - } - - // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and - // there's nothing practical we can do. - #[cfg(not(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - )))] - unsafe { - #[cfg(test)] - assert_eq_size!(Stat, c::stat); - - let mut stat = MaybeUninit::<Stat>::uninit(); - ret(c::lstat(c_str(path), stat.as_mut_ptr().cast()))?; - let stat = stat.assume_init(); - #[cfg(apple)] - let stat = fix_negative_stat_nsecs(stat); - Ok(stat) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { - // See the comments in `fstat` about using `crate::fs::statx` here. - #[cfg(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - ))] - { - match crate::fs::statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(dirfd, path, flags), - Err(err) => Err(err), - } - } - - // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and - // there's nothing practical we can do. - #[cfg(not(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - )))] - unsafe { - #[cfg(test)] - assert_eq_size!(Stat, c::stat); - - let mut stat = MaybeUninit::<Stat>::uninit(); - ret(c::fstatat( - borrowed_fd(dirfd), - c_str(path), - stat.as_mut_ptr().cast(), - bitflags_bits!(flags), - ))?; - let stat = stat.assume_init(); - #[cfg(apple)] - let stat = fix_negative_stat_nsecs(stat); - Ok(stat) - } -} - -#[cfg(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) -))] -fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { - unsafe { - let mut result = MaybeUninit::<c::stat64>::uninit(); - ret(c::fstatat( - borrowed_fd(dirfd), - c_str(path), - result.as_mut_ptr(), - bitflags_bits!(flags), - ))?; - stat64_to_stat(result.assume_init()) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "emscripten", - target_os = "vita" -)))] -pub(crate) fn access(path: &CStr, access: Access) -> io::Result<()> { - unsafe { ret(c::access(c_str(path), access.bits())) } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn accessat( - dirfd: BorrowedFd<'_>, - path: &CStr, - access: Access, - flags: AtFlags, -) -> io::Result<()> { - // macOS ≤ 10.9 lacks `faccessat`. - #[cfg(target_os = "macos")] - unsafe { - weak! { - fn faccessat( - c::c_int, - *const ffi::c_char, - c::c_int, - c::c_int - ) -> c::c_int - } - // If we have `faccessat`, use it. - if let Some(libc_faccessat) = faccessat.get() { - return ret(libc_faccessat( - borrowed_fd(dirfd), - c_str(path), - bitflags_bits!(access), - bitflags_bits!(flags), - )); - } - // Otherwise, see if we can emulate the `AT_FDCWD` case. - if borrowed_fd(dirfd) != c::AT_FDCWD { - return Err(io::Errno::NOSYS); - } - if flags.intersects(!(AtFlags::EACCESS | AtFlags::SYMLINK_NOFOLLOW)) { - return Err(io::Errno::INVAL); - } - if !flags.is_empty() { - return Err(io::Errno::OPNOTSUPP); - } - ret(c::access(c_str(path), bitflags_bits!(access))) - } - - #[cfg(not(target_os = "macos"))] - unsafe { - ret(c::faccessat( - borrowed_fd(dirfd), - c_str(path), - bitflags_bits!(access), - bitflags_bits!(flags), - )) - } -} - -#[cfg(target_os = "emscripten")] -pub(crate) fn access(_path: &CStr, _access: Access) -> io::Result<()> { - Ok(()) -} - -#[cfg(target_os = "emscripten")] -pub(crate) fn accessat( - _dirfd: BorrowedFd<'_>, - _path: &CStr, - _access: Access, - _flags: AtFlags, -) -> io::Result<()> { - Ok(()) -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn utimensat( - dirfd: BorrowedFd<'_>, - path: &CStr, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - // Old 32-bit version: libc has `utimensat` but it is not y2038 safe by - // default. But there may be a `__utimensat64` we can use. - #[cfg(all(fix_y2038, not(apple)))] - { - #[cfg(target_env = "gnu")] - if let Some(libc_utimensat) = __utimensat64.get() { - let libc_times: [LibcTimespec; 2] = - [times.last_access.into(), times.last_modification.into()]; - - unsafe { - return ret(libc_utimensat( - borrowed_fd(dirfd), - c_str(path), - libc_times.as_ptr(), - bitflags_bits!(flags), - )); - } - } - - utimensat_old(dirfd, path, times, flags) - } - - // Main version: libc is y2038 safe and has `utimensat`. Or, the platform - // is not y2038 safe and there's nothing practical we can do. - #[cfg(not(any(apple, fix_y2038)))] - unsafe { - use crate::utils::as_ptr; - - ret(c::utimensat( - borrowed_fd(dirfd), - c_str(path), - as_ptr(times).cast(), - bitflags_bits!(flags), - )) - } - - // Apple version: `utimensat` was introduced in macOS 10.13. - #[cfg(apple)] - unsafe { - use crate::utils::as_ptr; - - // ABI details - weak! { - fn utimensat( - c::c_int, - *const ffi::c_char, - *const c::timespec, - c::c_int - ) -> c::c_int - } - extern "C" { - fn setattrlist( - path: *const ffi::c_char, - attr_list: *const Attrlist, - attr_buf: *const c::c_void, - attr_buf_size: c::size_t, - options: c::c_ulong, - ) -> c::c_int; - } - const FSOPT_NOFOLLOW: c::c_ulong = 0x0000_0001; - - // If we have `utimensat`, use it. - if let Some(have_utimensat) = utimensat.get() { - return ret(have_utimensat( - borrowed_fd(dirfd), - c_str(path), - as_ptr(times).cast(), - bitflags_bits!(flags), - )); - } - - // Convert `times`. We only need this in the child, but do it before - // calling `fork` because it might fail. - let (attrbuf_size, times, attrs) = times_to_attrlist(times)?; - - // `setattrlistat` was introduced in 10.13 along with `utimensat`, so - // if we don't have `utimensat`, we don't have `setattrlistat` either. - // Emulate it using `fork`, and `fchdir` and [`setattrlist`]. - // - // [`setattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setattrlist.2.html - match c::fork() { - -1 => Err(io::Errno::IO), - 0 => { - if c::fchdir(borrowed_fd(dirfd)) != 0 { - let code = match libc_errno::errno().0 { - c::EACCES => 2, - c::ENOTDIR => 3, - _ => 1, - }; - c::_exit(code); - } - - let mut flags_arg = 0; - if flags.contains(AtFlags::SYMLINK_NOFOLLOW) { - flags_arg |= FSOPT_NOFOLLOW; - } - - if setattrlist( - c_str(path), - &attrs, - as_ptr(×).cast(), - attrbuf_size, - flags_arg, - ) != 0 - { - // Translate expected `errno` codes into ad-hoc integer - // values suitable for exit statuses. - let code = match libc_errno::errno().0 { - c::EACCES => 2, - c::ENOTDIR => 3, - c::EPERM => 4, - c::EROFS => 5, - c::ELOOP => 6, - c::ENOENT => 7, - c::ENAMETOOLONG => 8, - c::EINVAL => 9, - c::ESRCH => 10, - c::ENOTSUP => 11, - _ => 1, - }; - c::_exit(code); - } - - c::_exit(0); - } - child_pid => { - let mut wstatus = 0; - let _ = ret_c_int(c::waitpid(child_pid, &mut wstatus, 0))?; - if c::WIFEXITED(wstatus) { - // Translate our ad-hoc exit statuses back to `errno` - // codes. - match c::WEXITSTATUS(wstatus) { - 0 => Ok(()), - 2 => Err(io::Errno::ACCESS), - 3 => Err(io::Errno::NOTDIR), - 4 => Err(io::Errno::PERM), - 5 => Err(io::Errno::ROFS), - 6 => Err(io::Errno::LOOP), - 7 => Err(io::Errno::NOENT), - 8 => Err(io::Errno::NAMETOOLONG), - 9 => Err(io::Errno::INVAL), - 10 => Err(io::Errno::SRCH), - 11 => Err(io::Errno::NOTSUP), - _ => Err(io::Errno::IO), - } - } else { - Err(io::Errno::IO) - } - } - } - } -} - -#[cfg(all(fix_y2038, not(apple)))] -fn utimensat_old( - dirfd: BorrowedFd<'_>, - path: &CStr, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - let old_times = [ - c::timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_access - .tv_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - }, - c::timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_modification - .tv_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - }, - ]; - unsafe { - ret(c::utimensat( - borrowed_fd(dirfd), - c_str(path), - old_times.as_ptr(), - bitflags_bits!(flags), - )) - } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn chmod(path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(c::chmod(c_str(path), mode.bits() as c::mode_t)) } -} - -#[cfg(not(any( - linux_kernel, - target_os = "espidf", - target_os = "redox", - target_os = "wasi" -)))] -pub(crate) fn chmodat( - dirfd: BorrowedFd<'_>, - path: &CStr, - mode: Mode, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - ret(c::fchmodat( - borrowed_fd(dirfd), - c_str(path), - mode.bits() as c::mode_t, - bitflags_bits!(flags), - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn chmodat( - dirfd: BorrowedFd<'_>, - path: &CStr, - mode: Mode, - flags: AtFlags, -) -> io::Result<()> { - // Linux's `fchmodat` does not have a flags argument. - // - // Use `c::syscall` rather than `c::fchmodat` because some libc - // implementations, such as musl, add extra logic to `fchmod` to emulate - // support for `AT_SYMLINK_NOFOLLOW`, which uses `/proc` outside our - // control. - syscall! { - fn fchmodat( - base_dirfd: c::c_int, - pathname: *const ffi::c_char, - mode: c::mode_t - ) via SYS_fchmodat -> c::c_int - } - if flags == AtFlags::SYMLINK_NOFOLLOW { - return Err(io::Errno::OPNOTSUPP); - } - if !flags.is_empty() { - return Err(io::Errno::INVAL); - } - unsafe { - ret(fchmodat( - borrowed_fd(dirfd), - c_str(path), - mode.bits() as c::mode_t, - )) - } -} - -#[cfg(apple)] -pub(crate) fn fclonefileat( - srcfd: BorrowedFd<'_>, - dst_dirfd: BorrowedFd<'_>, - dst: &CStr, - flags: CloneFlags, -) -> io::Result<()> { - syscall! { - fn fclonefileat( - srcfd: BorrowedFd<'_>, - dst_dirfd: BorrowedFd<'_>, - dst: *const ffi::c_char, - flags: c::c_int - ) via SYS_fclonefileat -> c::c_int - } - - unsafe { - ret(fclonefileat( - srcfd, - dst_dirfd, - c_str(dst), - bitflags_bits!(flags), - )) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))] -pub(crate) fn chownat( - dirfd: BorrowedFd<'_>, - path: &CStr, - owner: Option<Uid>, - group: Option<Gid>, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(c::fchownat( - borrowed_fd(dirfd), - c_str(path), - ow, - gr, - bitflags_bits!(flags), - )) - } -} - -#[cfg(not(any( - apple, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub(crate) fn mknodat( - dirfd: BorrowedFd<'_>, - path: &CStr, - file_type: FileType, - mode: Mode, - dev: Dev, -) -> io::Result<()> { - unsafe { - ret(c::mknodat( - borrowed_fd(dirfd), - c_str(path), - (mode.bits() | file_type.as_raw_mode()) as c::mode_t, - dev.try_into().map_err(|_e| io::Errno::PERM)?, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn copy_file_range( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: usize, -) -> io::Result<usize> { - syscall! { - fn copy_file_range( - fd_in: c::c_int, - off_in: *mut c::loff_t, - fd_out: c::c_int, - off_out: *mut c::loff_t, - len: usize, - flags: c::c_uint - ) via SYS_copy_file_range -> c::ssize_t - } - - let mut off_in_val: c::loff_t = 0; - let mut off_out_val: c::loff_t = 0; - // Silently cast; we'll get `EINVAL` if the value is negative. - let off_in_ptr = if let Some(off_in) = &off_in { - off_in_val = **off_in as i64; - &mut off_in_val - } else { - null_mut() - }; - let off_out_ptr = if let Some(off_out) = &off_out { - off_out_val = **off_out as i64; - &mut off_out_val - } else { - null_mut() - }; - let copied = unsafe { - ret_usize(copy_file_range( - borrowed_fd(fd_in), - off_in_ptr, - borrowed_fd(fd_out), - off_out_ptr, - len, - 0, // no flags are defined yet - ))? - }; - if let Some(off_in) = off_in { - *off_in = off_in_val as u64; - } - if let Some(off_out) = off_out { - *off_out = off_out_val as u64; - } - Ok(copied) -} - -#[cfg(not(any( - apple, - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -pub(crate) fn fadvise( - fd: BorrowedFd<'_>, - offset: u64, - len: Option<NonZeroU64>, - advice: Advice, -) -> io::Result<()> { - let offset = offset as i64; - let len = match len { - None => 0, - Some(len) => len.get() as i64, - }; - - // Our public API uses `u64` following the [Rust convention], but the - // underlying host APIs use a signed `off_t`. Converting these values may - // turn a very large value into a negative value. - // - // On FreeBSD, this could cause `posix_fadvise` to fail with - // `Errno::INVAL`. Because we don't expose the signed type in our API, we - // also avoid exposing this artifact of casting an unsigned value to the - // signed type. To do this, we use a no-op call in this case. - // - // [Rust convention]: std::io::SeekFrom::Start - #[cfg(target_os = "freebsd")] - if offset < 0 { - if len < 0 { - return Err(io::Errno::INVAL); - } - - return fadvise_noop(fd); - - #[cold] - fn fadvise_noop(fd: BorrowedFd<'_>) -> io::Result<()> { - // Use an `fcntl` to report `Errno::BADF` if needed, but otherwise - // do nothing. - fcntl_getfl(fd).map(|_| ()) - } - } - - // Similarly, on FreeBSD, if `offset + len` would overflow an `off_t` in a - // way that users using a `u64` interface wouldn't be aware of, reduce the - // length so that we only operate on the range that doesn't overflow. - #[cfg(target_os = "freebsd")] - let len = if len > 0 && offset.checked_add(len).is_none() { - i64::MAX - offset - } else { - len - }; - - let err = unsafe { c::posix_fadvise(borrowed_fd(fd), offset, len, advice as c::c_int) }; - - // `posix_fadvise` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } -} - -pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result<OFlags> { - let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFL))? }; - Ok(OFlags::from_bits_retain(bitcast!(flags))) -} - -pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFL, flags.bits())) } -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result<SealFlags> { - let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GET_SEALS))? }; - Ok(SealFlags::from_bits_retain(bitcast!(flags))) -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_ADD_SEALS, seals.bits())) } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { - use c::{flock, F_RDLCK, F_SETLK, F_SETLKW, F_UNLCK, F_WRLCK, SEEK_SET}; - - let (cmd, l_type) = match operation { - FlockOperation::LockShared => (F_SETLKW, F_RDLCK), - FlockOperation::LockExclusive => (F_SETLKW, F_WRLCK), - FlockOperation::Unlock => (F_SETLKW, F_UNLCK), - FlockOperation::NonBlockingLockShared => (F_SETLK, F_RDLCK), - FlockOperation::NonBlockingLockExclusive => (F_SETLK, F_WRLCK), - FlockOperation::NonBlockingUnlock => (F_SETLK, F_UNLCK), - }; - - unsafe { - let mut lock: flock = core::mem::zeroed(); - lock.l_type = l_type as _; - - // When `l_len` is zero, this locks all the bytes from - // `l_whence`/`l_start` to the end of the file, even as the - // file grows dynamically. - lock.l_whence = SEEK_SET as _; - lock.l_start = 0; - lock.l_len = 0; - - ret(c::fcntl(borrowed_fd(fd), cmd, &lock)) - } -} - -pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result<u64> { - let (whence, offset) = match pos { - SeekFrom::Start(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (c::SEEK_SET, pos as i64) - } - SeekFrom::End(offset) => (c::SEEK_END, offset), - SeekFrom::Current(offset) => (c::SEEK_CUR, offset), - #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - SeekFrom::Data(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (c::SEEK_DATA, pos as i64) - } - #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - SeekFrom::Hole(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (c::SEEK_HOLE, pos as i64) - } - }; - - // ESP-IDF and Vita don't support 64-bit offsets, for example. - let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), offset, whence))? }; - Ok(offset as u64) -} - -pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result<u64> { - let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), 0, c::SEEK_CUR))? }; - Ok(offset as u64) -} - -#[cfg(not(any(linux_kernel, target_os = "wasi")))] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { - unsafe { ret(c::fchmod(borrowed_fd(fd), bitflags_bits!(mode))) } -} - -#[cfg(linux_kernel)] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { - // Use `c::syscall` rather than `c::fchmod` because some libc - // implementations, such as musl, add extra logic to `fchmod` to emulate - // support for `O_PATH`, which uses `/proc` outside our control and - // interferes with our own use of `O_PATH`. - syscall! { - fn fchmod( - fd: c::c_int, - mode: c::mode_t - ) via SYS_fchmod -> c::c_int - } - unsafe { ret(fchmod(borrowed_fd(fd), mode.bits() as c::mode_t)) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn chown(path: &CStr, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(c::chown(c_str(path), ow, gr)) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - // Use `c::syscall` rather than `c::fchown` because some libc - // implementations, such as musl, add extra logic to `fchown` to emulate - // support for `O_PATH`, which uses `/proc` outside our control and - // interferes with our own use of `O_PATH`. - syscall! { - fn fchown( - fd: c::c_int, - owner: c::uid_t, - group: c::gid_t - ) via SYS_fchown -> c::c_int - } - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(fchown(borrowed_fd(fd), ow, gr)) - } -} - -#[cfg(not(any(linux_kernel, target_os = "wasi")))] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(c::fchown(borrowed_fd(fd), ow, gr)) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "solaris", - target_os = "vita", - target_os = "wasi" -)))] -pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { - unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) } -} - -#[cfg(linux_kernel)] -pub(crate) fn syncfs(fd: BorrowedFd<'_>) -> io::Result<()> { - // Some versions of Android libc lack a `syncfs` function. - #[cfg(target_os = "android")] - syscall! { - fn syncfs(fd: c::c_int) via SYS_syncfs -> c::c_int - } - - // `syncfs` was added to glibc in 2.20. - #[cfg(not(target_os = "android"))] - weak_or_syscall! { - fn syncfs(fd: c::c_int) via SYS_syncfs -> c::c_int - } - - unsafe { ret(syncfs(borrowed_fd(fd))) } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub(crate) fn sync() { - unsafe { c::sync() } -} - -pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> { - // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use - // `statx`. - // - // And, some old platforms don't support `statx`, and some fail with a - // confusing error code, so we call `crate::fs::statx` to handle that. If - // `statx` isn't available, fall back to the buggy system call. - #[cfg(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - ))] - { - match crate::fs::statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => fstat_old(fd), - Err(err) => Err(err), - } - } - - // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and - // there's nothing practical we can do. - #[cfg(not(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - )))] - unsafe { - #[cfg(test)] - assert_eq_size!(Stat, c::stat); - - let mut stat = MaybeUninit::<Stat>::uninit(); - ret(c::fstat(borrowed_fd(fd), stat.as_mut_ptr().cast()))?; - let stat = stat.assume_init(); - #[cfg(apple)] - let stat = fix_negative_stat_nsecs(stat); - Ok(stat) - } -} - -#[cfg(all( - linux_kernel, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) -))] -fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { - unsafe { - let mut result = MaybeUninit::<c::stat64>::uninit(); - ret(c::fstat(borrowed_fd(fd), result.as_mut_ptr()))?; - stat64_to_stat(result.assume_init()) - } -} - -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result<StatFs> { - let mut statfs = MaybeUninit::<StatFs>::uninit(); - unsafe { - ret(c::fstatfs(borrowed_fd(fd), statfs.as_mut_ptr()))?; - Ok(statfs.assume_init()) - } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -pub(crate) fn fstatvfs(fd: BorrowedFd<'_>) -> io::Result<StatVfs> { - let mut statvfs = MaybeUninit::<c::statvfs>::uninit(); - unsafe { - ret(c::fstatvfs(borrowed_fd(fd), statvfs.as_mut_ptr()))?; - Ok(libc_statvfs_to_statvfs(statvfs.assume_init())) - } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -fn libc_statvfs_to_statvfs(from: c::statvfs) -> StatVfs { - StatVfs { - f_bsize: from.f_bsize as u64, - f_frsize: from.f_frsize as u64, - f_blocks: from.f_blocks as u64, - f_bfree: from.f_bfree as u64, - f_bavail: from.f_bavail as u64, - f_files: from.f_files as u64, - f_ffree: from.f_ffree as u64, - f_favail: from.f_ffree as u64, - #[cfg(not(target_os = "aix"))] - f_fsid: from.f_fsid as u64, - #[cfg(target_os = "aix")] - f_fsid: ((from.f_fsid.val[0] as u64) << 32) | from.f_fsid.val[1], - f_flag: StatVfsMountFlags::from_bits_retain(from.f_flag as u64), - f_namemax: from.f_namemax as u64, - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { - // Old 32-bit version: libc has `futimens` but it is not y2038 safe by - // default. But there may be a `__futimens64` we can use. - #[cfg(all(fix_y2038, not(apple)))] - { - #[cfg(target_env = "gnu")] - if let Some(libc_futimens) = __futimens64.get() { - let libc_times: [LibcTimespec; 2] = - [times.last_access.into(), times.last_modification.into()]; - - unsafe { - return ret(libc_futimens(borrowed_fd(fd), libc_times.as_ptr())); - } - } - - futimens_old(fd, times) - } - - // Main version: libc is y2038 safe and has `futimens`. Or, the platform - // is not y2038 safe and there's nothing practical we can do. - #[cfg(not(any(apple, fix_y2038)))] - unsafe { - use crate::utils::as_ptr; - - ret(c::futimens(borrowed_fd(fd), as_ptr(times).cast())) - } - - // Apple version: `futimens` was introduced in macOS 10.13. - #[cfg(apple)] - unsafe { - use crate::utils::as_ptr; - - // ABI details. - weak! { - fn futimens(c::c_int, *const c::timespec) -> c::c_int - } - extern "C" { - fn fsetattrlist( - fd: c::c_int, - attr_list: *const Attrlist, - attr_buf: *const c::c_void, - attr_buf_size: c::size_t, - options: c::c_ulong, - ) -> c::c_int; - } - - // If we have `futimens`, use it. - if let Some(have_futimens) = futimens.get() { - return ret(have_futimens(borrowed_fd(fd), as_ptr(times).cast())); - } - - // Otherwise use `fsetattrlist`. - let (attrbuf_size, times, attrs) = times_to_attrlist(times)?; - - ret(fsetattrlist( - borrowed_fd(fd), - &attrs, - as_ptr(×).cast(), - attrbuf_size, - 0, - )) - } -} - -#[cfg(all(fix_y2038, not(apple)))] -fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { - let old_times = [ - c::timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_access - .tv_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - }, - c::timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_modification - .tv_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - }, - ]; - - unsafe { ret(c::futimens(borrowed_fd(fd), old_times.as_ptr())) } -} - -#[cfg(not(any( - apple, - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -pub(crate) fn fallocate( - fd: BorrowedFd<'_>, - mode: FallocateFlags, - offset: u64, - len: u64, -) -> io::Result<()> { - // Silently cast to `i64`; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - let len = len as i64; - - // ESP-IDF and Vita don't support 64-bit offsets, for example. - let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - let len = len.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - #[cfg(any(linux_kernel, target_os = "fuchsia"))] - unsafe { - ret(c::fallocate( - borrowed_fd(fd), - bitflags_bits!(mode), - offset, - len, - )) - } - - #[cfg(not(any(linux_kernel, target_os = "fuchsia")))] - { - assert!(mode.is_empty()); - let err = unsafe { c::posix_fallocate(borrowed_fd(fd), offset, len) }; - - // `posix_fallocate` returns its error status rather than using - // `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } - } -} - -#[cfg(apple)] -pub(crate) fn fallocate( - fd: BorrowedFd<'_>, - mode: FallocateFlags, - offset: u64, - len: u64, -) -> io::Result<()> { - let offset: i64 = offset.try_into().map_err(|_e| io::Errno::INVAL)?; - let len = len as i64; - - assert!(mode.is_empty()); - - let new_len = offset.checked_add(len).ok_or(io::Errno::FBIG)?; - let mut store = c::fstore_t { - fst_flags: c::F_ALLOCATECONTIG, - fst_posmode: c::F_PEOFPOSMODE, - fst_offset: 0, - fst_length: new_len, - fst_bytesalloc: 0, - }; - unsafe { - if c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store) == -1 { - // Unable to allocate contiguous disk space; attempt to allocate - // non-contiguously. - store.fst_flags = c::F_ALLOCATEALL; - let _ = ret_c_int(c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store))?; - } - ret(c::ftruncate(borrowed_fd(fd), new_len)) - } -} - -pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fsync(borrowed_fd(fd))) } -} - -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", -)))] -pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fdatasync(borrowed_fd(fd))) } -} - -pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { - let length = length.try_into().map_err(|_overflow_err| io::Errno::FBIG)?; - unsafe { ret(c::ftruncate(borrowed_fd(fd), length)) } -} - -#[cfg(any(linux_kernel, target_os = "freebsd"))] -pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd> { - #[cfg(target_os = "freebsd")] - weakcall! { - fn memfd_create( - name: *const ffi::c_char, - flags: c::c_uint - ) -> c::c_int - } - - #[cfg(linux_kernel)] - weak_or_syscall! { - fn memfd_create( - name: *const ffi::c_char, - flags: c::c_uint - ) via SYS_memfd_create -> c::c_int - } - - unsafe { ret_owned_fd(memfd_create(c_str(name), bitflags_bits!(flags))) } -} - -#[cfg(linux_kernel)] -pub(crate) fn openat2( - dirfd: BorrowedFd<'_>, - path: &CStr, - oflags: OFlags, - mode: Mode, - resolve: ResolveFlags, -) -> io::Result<OwnedFd> { - use linux_raw_sys::general::open_how; - - syscall! { - fn openat2( - base_dirfd: c::c_int, - pathname: *const ffi::c_char, - how: *mut open_how, - size: usize - ) via SYS_OPENAT2 -> c::c_int - } - - let oflags = oflags.bits(); - let mut open_how = open_how { - flags: u64::from(oflags), - mode: u64::from(mode.bits()), - resolve: resolve.bits(), - }; - - unsafe { - ret_owned_fd(openat2( - borrowed_fd(dirfd), - c_str(path), - &mut open_how, - size_of::<open_how>(), - )) - } -} -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -const SYS_OPENAT2: i32 = 437; -#[cfg(all(linux_kernel, target_pointer_width = "64"))] -const SYS_OPENAT2: i64 = 437; - -#[cfg(target_os = "linux")] -pub(crate) fn sendfile( - out_fd: BorrowedFd<'_>, - in_fd: BorrowedFd<'_>, - offset: Option<&mut u64>, - count: usize, -) -> io::Result<usize> { - unsafe { - ret_usize(c::sendfile64( - borrowed_fd(out_fd), - borrowed_fd(in_fd), - offset.map_or(null_mut(), crate::utils::as_mut_ptr).cast(), - count, - )) - } -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { - Ok(Stat { - st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor).into(), - st_mode: x.stx_mode.into(), - st_nlink: x.stx_nlink.into(), - st_uid: x.stx_uid.into(), - st_gid: x.stx_gid.into(), - st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor).into(), - st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: x.stx_blksize.into(), - st_blocks: x.stx_blocks.into(), - st_atime: bitcast!(i64::from(x.stx_atime.tv_sec)), - st_atime_nsec: x.stx_atime.tv_nsec as _, - st_mtime: bitcast!(i64::from(x.stx_mtime.tv_sec)), - st_mtime_nsec: x.stx_mtime.tv_nsec as _, - st_ctime: bitcast!(i64::from(x.stx_ctime.tv_sec)), - st_ctime_nsec: x.stx_ctime.tv_nsec as _, - st_ino: x.stx_ino.into(), - }) -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -/// -/// mips64' `struct stat64` in libc has private fields, and `stx_blocks` -#[cfg(all(linux_kernel, any(target_arch = "mips64", target_arch = "mips64r6")))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { - let mut result: Stat = unsafe { core::mem::zeroed() }; - - result.st_dev = crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor); - result.st_mode = x.stx_mode.into(); - result.st_nlink = x.stx_nlink.into(); - result.st_uid = x.stx_uid.into(); - result.st_gid = x.stx_gid.into(); - result.st_rdev = crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor); - result.st_size = x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_blksize = x.stx_blksize.into(); - result.st_blocks = x.stx_blocks.try_into().map_err(|_e| io::Errno::OVERFLOW)?; - result.st_atime = bitcast!(i64::from(x.stx_atime.tv_sec)); - result.st_atime_nsec = x.stx_atime.tv_nsec as _; - result.st_mtime = bitcast!(i64::from(x.stx_mtime.tv_sec)); - result.st_mtime_nsec = x.stx_mtime.tv_nsec as _; - result.st_ctime = bitcast!(i64::from(x.stx_ctime.tv_sec)); - result.st_ctime_nsec = x.stx_ctime.tv_nsec as _; - result.st_ino = x.stx_ino.into(); - - Ok(result) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { - Ok(Stat { - st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime: i64::from(s64.st_atime), - st_atime_nsec: s64 - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime: i64::from(s64.st_mtime), - st_mtime_nsec: s64 - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime: i64::from(s64.st_ctime), - st_ctime_nsec: s64 - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, - }) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -/// -/// mips64' `struct stat64` in libc has private fields, and `st_blocks` has -/// type `i64`. -#[cfg(all(linux_kernel, any(target_arch = "mips64", target_arch = "mips64r6")))] -fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { - let mut result: Stat = unsafe { core::mem::zeroed() }; - - result.st_dev = s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_mode = s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_nlink = s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_uid = s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_gid = s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_rdev = s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_size = s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_blksize = s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_blocks = s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_atime = i64::from(s64.st_atime) as _; - result.st_atime_nsec = s64 - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_mtime = i64::from(s64.st_mtime) as _; - result.st_mtime_nsec = s64 - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_ctime = i64::from(s64.st_ctime) as _; - result.st_ctime_nsec = s64 - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_ino = s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - Ok(result) -} - -#[cfg(linux_kernel)] -#[allow(non_upper_case_globals)] -mod sys { - use super::{c, ffi, BorrowedFd, Statx}; - - weak_or_syscall! { - pub(super) fn statx( - dirfd_: BorrowedFd<'_>, - path: *const ffi::c_char, - flags: c::c_int, - mask: c::c_uint, - buf: *mut Statx - ) via SYS_statx -> c::c_int - } -} - -#[cfg(linux_kernel)] -#[allow(non_upper_case_globals)] -pub(crate) fn statx( - dirfd: BorrowedFd<'_>, - path: &CStr, - flags: AtFlags, - mask: StatxFlags, -) -> io::Result<Statx> { - // If a future Linux kernel adds more fields to `struct statx` and users - // passing flags unknown to rustix in `StatxFlags`, we could end up - // writing outside of the buffer. To prevent this possibility, we mask off - // any flags that we don't know about. - // - // This includes `STATX__RESERVED`, which has a value that we know, but - // which could take on arbitrary new meaning in the future. Linux currently - // rejects this flag with `EINVAL`, so we do the same. - // - // This doesn't rely on `STATX_ALL` because [it's deprecated] and already - // doesn't represent all the known flags. - // - // [it's deprecated]: https://patchwork.kernel.org/project/linux-fsdevel/patch/20200505095915.11275-7-mszeredi@redhat.com/ - #[cfg(not(any(target_os = "android", target_env = "musl")))] - const STATX__RESERVED: u32 = c::STATX__RESERVED as u32; - #[cfg(any(target_os = "android", target_env = "musl"))] - const STATX__RESERVED: u32 = linux_raw_sys::general::STATX__RESERVED; - if (mask.bits() & STATX__RESERVED) == STATX__RESERVED { - return Err(io::Errno::INVAL); - } - let mask = mask & StatxFlags::all(); - - let mut statx_buf = MaybeUninit::<Statx>::uninit(); - unsafe { - ret(sys::statx( - dirfd, - c_str(path), - bitflags_bits!(flags), - mask.bits(), - statx_buf.as_mut_ptr(), - ))?; - Ok(statx_buf.assume_init()) - } -} - -#[cfg(all(linux_kernel, not(feature = "linux_4_11")))] -#[inline] -pub(crate) fn is_statx_available() -> bool { - unsafe { - // Call `statx` with null pointers so that if it fails for any reason - // other than `EFAULT`, we know it's not supported. - matches!( - ret(sys::statx(CWD, null(), 0, 0, null_mut())), - Err(io::Errno::FAULT) - ) - } -} - -#[cfg(apple)] -pub(crate) unsafe fn fcopyfile( - from: BorrowedFd<'_>, - to: BorrowedFd<'_>, - state: copyfile_state_t, - flags: CopyfileFlags, -) -> io::Result<()> { - extern "C" { - fn fcopyfile( - from: c::c_int, - to: c::c_int, - state: copyfile_state_t, - flags: c::c_uint, - ) -> c::c_int; - } - - nonnegative_ret(fcopyfile( - borrowed_fd(from), - borrowed_fd(to), - state, - bitflags_bits!(flags), - )) -} - -#[cfg(apple)] -pub(crate) fn copyfile_state_alloc() -> io::Result<copyfile_state_t> { - extern "C" { - fn copyfile_state_alloc() -> copyfile_state_t; - } - - let result = unsafe { copyfile_state_alloc() }; - if result.0.is_null() { - Err(io::Errno::last_os_error()) - } else { - Ok(result) - } -} - -#[cfg(apple)] -pub(crate) unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { - extern "C" { - fn copyfile_state_free(state: copyfile_state_t) -> c::c_int; - } - - nonnegative_ret(copyfile_state_free(state)) -} - -#[cfg(apple)] -const COPYFILE_STATE_COPIED: u32 = 8; - -#[cfg(apple)] -pub(crate) unsafe fn copyfile_state_get_copied(state: copyfile_state_t) -> io::Result<u64> { - let mut copied = MaybeUninit::<u64>::uninit(); - copyfile_state_get(state, COPYFILE_STATE_COPIED, copied.as_mut_ptr().cast())?; - Ok(copied.assume_init()) -} - -#[cfg(apple)] -pub(crate) unsafe fn copyfile_state_get( - state: copyfile_state_t, - flag: u32, - dst: *mut c::c_void, -) -> io::Result<()> { - extern "C" { - fn copyfile_state_get(state: copyfile_state_t, flag: u32, dst: *mut c::c_void) -> c::c_int; - } - - nonnegative_ret(copyfile_state_get(state, flag, dst)) -} - -#[cfg(all(apple, feature = "alloc"))] -pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result<CString> { - // The use of `PATH_MAX` is generally not encouraged, but it - // is inevitable in this case because macOS defines `fcntl` with - // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no - // alternatives. If a better method is invented, it should be used - // instead. - let mut buf = vec![0; c::PATH_MAX as usize]; - - // From the [macOS `fcntl` manual page]: - // `F_GETPATH` - Get the path of the file descriptor `Fildes`. The argument - // must be a buffer of size `MAXPATHLEN` or greater. - // - // [macOS `fcntl` manual page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html - unsafe { - ret(c::fcntl(borrowed_fd(fd), c::F_GETPATH, buf.as_mut_ptr()))?; - } - - let l = buf.iter().position(|&c| c == 0).unwrap(); - buf.truncate(l); - buf.shrink_to_fit(); - - Ok(CString::new(buf).unwrap()) -} - -#[cfg(apple)] -pub(crate) fn fcntl_rdadvise(fd: BorrowedFd<'_>, offset: u64, len: u64) -> io::Result<()> { - // From the [macOS `fcntl` manual page]: - // `F_RDADVISE` - Issue an advisory read async with no copy to user. - // - // The `F_RDADVISE` command operates on the following structure which holds - // information passed from the user to the system: - // - // ```c - // struct radvisory { - // off_t ra_offset; /* offset into the file */ - // int ra_count; /* size of the read */ - // }; - // ``` - // - // [macOS `fcntl` manual page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html - let ra_offset = match offset.try_into() { - Ok(len) => len, - // If this conversion fails, the user is providing an offset outside - // any possible file extent, so just ignore it. - Err(_) => return Ok(()), - }; - let ra_count = match len.try_into() { - Ok(len) => len, - // If this conversion fails, the user is providing a dubiously large - // hint which is unlikely to improve performance. - Err(_) => return Ok(()), - }; - unsafe { - let radvisory = c::radvisory { - ra_offset, - ra_count, - }; - ret(c::fcntl(borrowed_fd(fd), c::F_RDADVISE, &radvisory)) - } -} - -#[cfg(apple)] -pub(crate) fn fcntl_fullfsync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_FULLFSYNC)) } -} - -#[cfg(apple)] -pub(crate) fn fcntl_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_NOCACHE, value as c::c_int)) } -} - -#[cfg(apple)] -pub(crate) fn fcntl_global_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - unsafe { - ret(c::fcntl( - borrowed_fd(fd), - c::F_GLOBAL_NOCACHE, - value as c::c_int, - )) - } -} - -/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist` -/// arguments. -#[cfg(apple)] -fn times_to_attrlist(times: &Timestamps) -> io::Result<(c::size_t, [c::timespec; 2], Attrlist)> { - // ABI details. - const ATTR_CMN_MODTIME: u32 = 0x0000_0400; - const ATTR_CMN_ACCTIME: u32 = 0x0000_1000; - const ATTR_BIT_MAP_COUNT: u16 = 5; - - let mut times = times.clone(); - - // If we have any `UTIME_NOW` elements, replace them with the current time. - if times.last_access.tv_nsec == c::UTIME_NOW.into() - || times.last_modification.tv_nsec == c::UTIME_NOW.into() - { - let now = { - let mut tv = c::timeval { - tv_sec: 0, - tv_usec: 0, - }; - unsafe { - let r = c::gettimeofday(&mut tv, null_mut()); - assert_eq!(r, 0); - } - c::timespec { - tv_sec: tv.tv_sec, - tv_nsec: (tv.tv_usec * 1000) as _, - } - }; - if times.last_access.tv_nsec == c::UTIME_NOW.into() { - times.last_access = crate::timespec::Timespec { - tv_sec: now.tv_sec.into(), - tv_nsec: now.tv_nsec as _, - }; - } - if times.last_modification.tv_nsec == c::UTIME_NOW.into() { - times.last_modification = crate::timespec::Timespec { - tv_sec: now.tv_sec.into(), - tv_nsec: now.tv_nsec as _, - }; - } - } - - // Pack the return values following the rules for [`getattrlist`]. - // - // [`getattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getattrlist.2.html - let mut times_size = 0; - let mut attrs = Attrlist { - bitmapcount: ATTR_BIT_MAP_COUNT, - reserved: 0, - commonattr: 0, - volattr: 0, - dirattr: 0, - fileattr: 0, - forkattr: 0, - }; - let mut return_times = [c::timespec { - tv_sec: 0, - tv_nsec: 0, - }; 2]; - let mut times_index = 0; - if times.last_modification.tv_nsec != c::UTIME_OMIT.into() { - attrs.commonattr |= ATTR_CMN_MODTIME; - return_times[times_index] = c::timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_modification.tv_nsec as _, - }; - times_index += 1; - times_size += size_of::<c::timespec>(); - } - if times.last_access.tv_nsec != c::UTIME_OMIT.into() { - attrs.commonattr |= ATTR_CMN_ACCTIME; - return_times[times_index] = c::timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_access.tv_nsec as _, - }; - times_size += size_of::<c::timespec>(); - } - - Ok((times_size, return_times, attrs)) -} - -/// Support type for `Attrlist`. -#[cfg(apple)] -type Attrgroup = u32; - -/// Attribute list for use with [`setattrlist`]. -#[cfg(apple)] -#[repr(C)] -struct Attrlist { - bitmapcount: u16, - reserved: u16, - commonattr: Attrgroup, - volattr: Attrgroup, - dirattr: Attrgroup, - fileattr: Attrgroup, - forkattr: Attrgroup, -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) unsafe fn getxattr( - path: &CStr, - name: &CStr, - value: (*mut u8, usize), -) -> io::Result<usize> { - #[cfg(not(apple))] - { - ret_usize(c::getxattr( - path.as_ptr(), - name.as_ptr(), - value.0.cast::<c::c_void>(), - value.1, - )) - } - - #[cfg(apple)] - { - // Passing an empty to slice to `getxattr` leads to `ERANGE` on macOS. - // Pass null instead. - let ptr = if value.1 == 0 { - core::ptr::null_mut() - } else { - value.0.cast::<c::c_void>() - }; - ret_usize(c::getxattr( - path.as_ptr(), - name.as_ptr(), - ptr, - value.1, - 0, - 0, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) unsafe fn lgetxattr( - path: &CStr, - name: &CStr, - value: (*mut u8, usize), -) -> io::Result<usize> { - #[cfg(not(apple))] - { - ret_usize(c::lgetxattr( - path.as_ptr(), - name.as_ptr(), - value.0.cast::<c::c_void>(), - value.1, - )) - } - - #[cfg(apple)] - { - // Passing an empty to slice to `getxattr` leads to `ERANGE` on macOS. - // Pass null instead. - let ptr = if value.1 == 0 { - core::ptr::null_mut() - } else { - value.0.cast::<c::c_void>() - }; - - ret_usize(c::getxattr( - path.as_ptr(), - name.as_ptr(), - ptr, - value.1, - 0, - c::XATTR_NOFOLLOW, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) unsafe fn fgetxattr( - fd: BorrowedFd<'_>, - name: &CStr, - value: (*mut u8, usize), -) -> io::Result<usize> { - #[cfg(not(apple))] - { - ret_usize(c::fgetxattr( - borrowed_fd(fd), - name.as_ptr(), - value.0.cast::<c::c_void>(), - value.1, - )) - } - - #[cfg(apple)] - { - // Passing an empty to slice to `getxattr` leads to `ERANGE` on macOS. - // Pass null instead. - let ptr = if value.1 == 0 { - core::ptr::null_mut() - } else { - value.0.cast::<c::c_void>() - }; - ret_usize(c::fgetxattr( - borrowed_fd(fd), - name.as_ptr(), - ptr, - value.1, - 0, - 0, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) fn setxattr( - path: &CStr, - name: &CStr, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - #[cfg(not(apple))] - unsafe { - ret(c::setxattr( - path.as_ptr(), - name.as_ptr(), - value.as_ptr().cast::<c::c_void>(), - value.len(), - flags.bits() as i32, - )) - } - - #[cfg(apple)] - unsafe { - ret(c::setxattr( - path.as_ptr(), - name.as_ptr(), - value.as_ptr().cast::<c::c_void>(), - value.len(), - 0, - flags.bits() as i32, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) fn lsetxattr( - path: &CStr, - name: &CStr, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - #[cfg(not(apple))] - unsafe { - ret(c::lsetxattr( - path.as_ptr(), - name.as_ptr(), - value.as_ptr().cast::<c::c_void>(), - value.len(), - flags.bits() as i32, - )) - } - - #[cfg(apple)] - unsafe { - ret(c::setxattr( - path.as_ptr(), - name.as_ptr(), - value.as_ptr().cast::<c::c_void>(), - value.len(), - 0, - flags.bits() as i32 | c::XATTR_NOFOLLOW, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) fn fsetxattr( - fd: BorrowedFd<'_>, - name: &CStr, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - #[cfg(not(apple))] - unsafe { - ret(c::fsetxattr( - borrowed_fd(fd), - name.as_ptr(), - value.as_ptr().cast::<c::c_void>(), - value.len(), - flags.bits() as i32, - )) - } - - #[cfg(apple)] - unsafe { - ret(c::fsetxattr( - borrowed_fd(fd), - name.as_ptr(), - value.as_ptr().cast::<c::c_void>(), - value.len(), - 0, - flags.bits() as i32, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) unsafe fn listxattr(path: &CStr, list: (*mut u8, usize)) -> io::Result<usize> { - #[cfg(not(apple))] - { - ret_usize(c::listxattr( - path.as_ptr(), - list.0.cast::<ffi::c_char>(), - list.1, - )) - } - - #[cfg(apple)] - { - ret_usize(c::listxattr( - path.as_ptr(), - list.0.cast::<ffi::c_char>(), - list.1, - 0, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) unsafe fn llistxattr(path: &CStr, list: (*mut u8, usize)) -> io::Result<usize> { - #[cfg(not(apple))] - { - ret_usize(c::llistxattr( - path.as_ptr(), - list.0.cast::<ffi::c_char>(), - list.1, - )) - } - - #[cfg(apple)] - { - ret_usize(c::listxattr( - path.as_ptr(), - list.0.cast::<ffi::c_char>(), - list.1, - c::XATTR_NOFOLLOW, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) unsafe fn flistxattr(fd: BorrowedFd<'_>, list: (*mut u8, usize)) -> io::Result<usize> { - let fd = borrowed_fd(fd); - - #[cfg(not(apple))] - { - ret_usize(c::flistxattr(fd, list.0.cast::<ffi::c_char>(), list.1)) - } - - #[cfg(apple)] - { - ret_usize(c::flistxattr(fd, list.0.cast::<ffi::c_char>(), list.1, 0)) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> { - #[cfg(not(apple))] - unsafe { - ret(c::removexattr(path.as_ptr(), name.as_ptr())) - } - - #[cfg(apple)] - unsafe { - ret(c::removexattr(path.as_ptr(), name.as_ptr(), 0)) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> { - #[cfg(not(apple))] - unsafe { - ret(c::lremovexattr(path.as_ptr(), name.as_ptr())) - } - - #[cfg(apple)] - unsafe { - ret(c::removexattr( - path.as_ptr(), - name.as_ptr(), - c::XATTR_NOFOLLOW, - )) - } -} - -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> { - let fd = borrowed_fd(fd); - - #[cfg(not(apple))] - unsafe { - ret(c::fremovexattr(fd, name.as_ptr())) - } - - #[cfg(apple)] - unsafe { - ret(c::fremovexattr(fd, name.as_ptr(), 0)) - } -} - -/// See [`crate::timespec::fix_negative_nsec`] for details. -#[cfg(apple)] -fn fix_negative_stat_nsecs(mut stat: Stat) -> Stat { - (stat.st_atime, stat.st_atime_nsec) = - crate::timespec::fix_negative_nsecs(stat.st_atime, stat.st_atime_nsec); - (stat.st_mtime, stat.st_mtime_nsec) = - crate::timespec::fix_negative_nsecs(stat.st_mtime, stat.st_mtime_nsec); - (stat.st_ctime, stat.st_ctime_nsec) = - crate::timespec::fix_negative_nsecs(stat.st_ctime, stat.st_ctime_nsec); - stat -} - -#[inline] -#[cfg(linux_kernel)] -pub(crate) fn inotify_init1(flags: super::inotify::CreateFlags) -> io::Result<OwnedFd> { - // SAFETY: `inotify_init1` has no safety preconditions. - unsafe { ret_owned_fd(c::inotify_init1(bitflags_bits!(flags))) } -} - -#[inline] -#[cfg(linux_kernel)] -pub(crate) fn inotify_add_watch( - inot: BorrowedFd<'_>, - path: &CStr, - flags: super::inotify::WatchFlags, -) -> io::Result<i32> { - // SAFETY: The fd and path we are passing is guaranteed valid by the - // type system. - unsafe { - ret_c_int(c::inotify_add_watch( - borrowed_fd(inot), - c_str(path), - flags.bits(), - )) - } -} - -#[inline] -#[cfg(linux_kernel)] -pub(crate) fn inotify_rm_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> { - // Android's `inotify_rm_watch` takes `u32` despite that - // `inotify_add_watch` expects a `i32`. - #[cfg(target_os = "android")] - let wd = wd as u32; - // SAFETY: The fd is valid and closing an arbitrary wd is valid. - unsafe { ret(c::inotify_rm_watch(borrowed_fd(inot), wd)) } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - #[cfg(linux_kernel)] - assert_eq_size!(c::loff_t, u64); - - // Assert that `Timestamps` has the expected layout. If we're not fixing - // y2038, libc's type should match ours. If we are, it's smaller. - #[cfg(not(fix_y2038))] - assert_eq_size!([c::timespec; 2], Timestamps); - #[cfg(fix_y2038)] - assert!(core::mem::size_of::<[c::timespec; 2]>() < core::mem::size_of::<Timestamps>()); - } -} diff --git a/vendor/rustix/src/backend/libc/fs/types.rs b/vendor/rustix/src/backend/libc/fs/types.rs deleted file mode 100644 index 8f1f4792..00000000 --- a/vendor/rustix/src/backend/libc/fs/types.rs +++ /dev/null @@ -1,1150 +0,0 @@ -use crate::backend::c; -use crate::ffi; -use bitflags::bitflags; - -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -bitflags! { - /// `*_OK` constants for use with [`accessat`]. - /// - /// [`accessat`]: fn.accessat.html - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Access: ffi::c_int { - /// `R_OK` - const READ_OK = c::R_OK; - - /// `W_OK` - const WRITE_OK = c::W_OK; - - /// `X_OK` - const EXEC_OK = c::X_OK; - - /// `F_OK` - const EXISTS = c::F_OK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "redox")))] -bitflags! { - /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` - /// functions. - /// - /// [`openat`]: crate::fs::openat - /// [`statat`]: crate::fs::statat - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct AtFlags: u32 { - /// `AT_SYMLINK_NOFOLLOW` - const SYMLINK_NOFOLLOW = bitcast!(c::AT_SYMLINK_NOFOLLOW); - - /// `AT_EACCESS` - #[cfg(not(target_os = "android"))] - const EACCESS = bitcast!(c::AT_EACCESS); - - /// `AT_REMOVEDIR` - const REMOVEDIR = bitcast!(c::AT_REMOVEDIR); - - /// `AT_SYMLINK_FOLLOW` - const SYMLINK_FOLLOW = bitcast!(c::AT_SYMLINK_FOLLOW); - - /// `AT_NO_AUTOMOUNT` - #[cfg(any(linux_like, target_os = "fuchsia"))] - const NO_AUTOMOUNT = bitcast!(c::AT_NO_AUTOMOUNT); - - /// `AT_EMPTY_PATH` - #[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - ))] - const EMPTY_PATH = bitcast!(c::AT_EMPTY_PATH); - - /// `AT_RESOLVE_BENEATH` - #[cfg(target_os = "freebsd")] - const RESOLVE_BENEATH = bitcast!(c::AT_RESOLVE_BENEATH); - - /// `AT_STATX_SYNC_AS_STAT` - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const STATX_SYNC_AS_STAT = bitcast!(c::AT_STATX_SYNC_AS_STAT); - - /// `AT_STATX_FORCE_SYNC` - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const STATX_FORCE_SYNC = bitcast!(c::AT_STATX_FORCE_SYNC); - - /// `AT_STATX_DONT_SYNC` - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const STATX_DONT_SYNC = bitcast!(c::AT_STATX_DONT_SYNC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(target_os = "horizon")] -bitflags! { - /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` - /// functions. - /// - /// [`openat`]: crate::fs::openat - /// [`statat`]: crate::fs::statat - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct AtFlags: u32 { - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(target_os = "horizon"))] -bitflags! { - /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. - /// - /// [`openat`]: crate::fs::openat - /// [`chmodat`]: crate::fs::chmodat - /// [`fchmod`]: crate::fs::fchmod - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Mode: RawMode { - /// `S_IRWXU` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const RWXU = c::S_IRWXU as RawMode; - - /// `S_IRUSR` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const RUSR = c::S_IRUSR as RawMode; - - /// `S_IWUSR` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const WUSR = c::S_IWUSR as RawMode; - - /// `S_IXUSR` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const XUSR = c::S_IXUSR as RawMode; - - /// `S_IRWXG` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const RWXG = c::S_IRWXG as RawMode; - - /// `S_IRGRP` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const RGRP = c::S_IRGRP as RawMode; - - /// `S_IWGRP` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const WGRP = c::S_IWGRP as RawMode; - - /// `S_IXGRP` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const XGRP = c::S_IXGRP as RawMode; - - /// `S_IRWXO` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const RWXO = c::S_IRWXO as RawMode; - - /// `S_IROTH` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const ROTH = c::S_IROTH as RawMode; - - /// `S_IWOTH` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const WOTH = c::S_IWOTH as RawMode; - - /// `S_IXOTH` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const XOTH = c::S_IXOTH as RawMode; - - /// `S_ISUID` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const SUID = c::S_ISUID as RawMode; - - /// `S_ISGID` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const SGID = c::S_ISGID as RawMode; - - /// `S_ISVTX` - #[cfg(not(any(target_os = "espidf", target_os = "vita")))] - const SVTX = c::S_ISVTX as RawMode; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(target_os = "horizon")] -bitflags! { - /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. - /// - /// [`openat`]: crate::fs::openat - /// [`chmodat`]: crate::fs::chmodat - /// [`fchmod`]: crate::fs::fchmod - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Mode: RawMode { - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(target_os = "espidf"))] -impl Mode { - /// Construct a `Mode` from the mode bits of the `st_mode` field of a - /// `Mode`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - Self::from_bits_truncate(st_mode & !c::S_IFMT as RawMode) - } - - /// Construct an `st_mode` value from a `Mode`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - self.bits() - } -} - -#[cfg(not(target_os = "espidf"))] -impl From<RawMode> for Mode { - /// Support conversions from raw mode values to `Mode`. - /// - /// ``` - /// use rustix::fs::{Mode, RawMode}; - /// assert_eq!(Mode::from(0o700), Mode::RWXU); - /// ``` - #[inline] - fn from(st_mode: RawMode) -> Self { - Self::from_raw_mode(st_mode) - } -} - -#[cfg(not(target_os = "espidf"))] -impl From<Mode> for RawMode { - /// Support conversions from `Mode` to raw mode values. - /// - /// ``` - /// use rustix::fs::{Mode, RawMode}; - /// assert_eq!(RawMode::from(Mode::RWXU), 0o700); - /// ``` - #[inline] - fn from(mode: Mode) -> Self { - mode.as_raw_mode() - } -} - -bitflags! { - /// `O_*` constants for use with [`openat`]. - /// - /// [`openat`]: crate::fs::openat - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct OFlags: u32 { - /// `O_ACCMODE` - const ACCMODE = bitcast!(c::O_ACCMODE); - - /// Similar to `ACCMODE`, but just includes the read/write flags, and - /// no other flags. - /// - /// On some platforms, `PATH` may be included in `ACCMODE`, when - /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `PATH` may mean that the read/write - /// bits don't have their usual meaning. - const RWMODE = bitcast!(c::O_RDONLY | c::O_WRONLY | c::O_RDWR); - - /// `O_APPEND` - const APPEND = bitcast!(c::O_APPEND); - - /// `O_CREAT` - #[doc(alias = "CREAT")] - const CREATE = bitcast!(c::O_CREAT); - - /// `O_DIRECTORY` - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - const DIRECTORY = bitcast!(c::O_DIRECTORY); - - /// `O_DSYNC` - #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon", target_os = "l4re", target_os = "redox", target_os = "vita")))] - const DSYNC = bitcast!(c::O_DSYNC); - - /// `O_EXCL` - const EXCL = bitcast!(c::O_EXCL); - - /// `O_FSYNC` - #[cfg(any( - bsd, - all(target_os = "linux", not(target_env = "musl")), - ))] - const FSYNC = bitcast!(c::O_FSYNC); - - /// `O_NOFOLLOW` - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - const NOFOLLOW = bitcast!(c::O_NOFOLLOW); - - /// `O_NONBLOCK` - const NONBLOCK = bitcast!(c::O_NONBLOCK); - - /// `O_RDONLY` - const RDONLY = bitcast!(c::O_RDONLY); - - /// `O_WRONLY` - const WRONLY = bitcast!(c::O_WRONLY); - - /// `O_RDWR` - /// - /// This is not equal to `RDONLY | WRONLY`. It's a distinct flag. - const RDWR = bitcast!(c::O_RDWR); - - /// `O_NOCTTY` - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "l4re", target_os = "redox", target_os = "vita")))] - const NOCTTY = bitcast!(c::O_NOCTTY); - - /// `O_RSYNC` - #[cfg(any( - linux_kernel, - netbsdlike, - solarish, - target_os = "emscripten", - target_os = "wasi", - ))] - const RSYNC = bitcast!(c::O_RSYNC); - - /// `O_SYNC` - #[cfg(not(any(target_os = "l4re", target_os = "redox")))] - const SYNC = bitcast!(c::O_SYNC); - - /// `O_TRUNC` - const TRUNC = bitcast!(c::O_TRUNC); - - /// `O_PATH` - #[cfg(any( - linux_kernel, - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "redox", - ))] - const PATH = bitcast!(c::O_PATH); - - /// `O_CLOEXEC` - const CLOEXEC = bitcast!(c::O_CLOEXEC); - - /// `O_TMPFILE` - #[cfg(any( - linux_kernel, - target_os = "emscripten", - target_os = "fuchsia", - ))] - const TMPFILE = bitcast!(c::O_TMPFILE); - - /// `O_NOATIME` - #[cfg(any( - linux_kernel, - target_os = "fuchsia", - ))] - const NOATIME = bitcast!(c::O_NOATIME); - - /// `O_DIRECT` - #[cfg(any( - linux_kernel, - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "netbsd", - ))] - const DIRECT = bitcast!(c::O_DIRECT); - - /// `O_RESOLVE_BENEATH` - #[cfg(target_os = "freebsd")] - const RESOLVE_BENEATH = bitcast!(c::O_RESOLVE_BENEATH); - - /// `O_EMPTY_PATH` - #[cfg(target_os = "freebsd")] - const EMPTY_PATH = bitcast!(c::O_EMPTY_PATH); - - /// `O_LARGEFILE` - /// - /// Rustix and/or libc will automatically set this flag when - /// appropriate in the [`rustix::fs::open`] family of functions, so - /// typical users do not need to care about it. It may be reported in - /// the return of `fcntl_getfl`, though. - #[cfg(any(linux_kernel, solarish))] - const LARGEFILE = bitcast!(c::O_LARGEFILE); - - /// `O_ASYNC`, `FASYNC` - /// - /// This flag can't be used with the [`rustix::fs::open`] family of - /// functions, use [`rustix::fs::fcntl_setfl`] instead. - #[cfg(not(any( - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "wasi", - target_os = "vita", - solarish - )))] - const ASYNC = bitcast!(c::O_ASYNC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(apple)] -bitflags! { - /// `CLONE_*` constants for use with [`fclonefileat`]. - /// - /// [`fclonefileat`]: crate::fs::fclonefileat - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CloneFlags: u32 { - /// `CLONE_NOFOLLOW` - const NOFOLLOW = 1; - - /// `CLONE_NOOWNERCOPY` - const NOOWNERCOPY = 2; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(apple)] -mod copyfile { - pub(super) const ACL: u32 = 1 << 0; - pub(super) const STAT: u32 = 1 << 1; - pub(super) const XATTR: u32 = 1 << 2; - pub(super) const DATA: u32 = 1 << 3; - pub(super) const SECURITY: u32 = STAT | ACL; - pub(super) const METADATA: u32 = SECURITY | XATTR; - pub(super) const ALL: u32 = METADATA | DATA; -} - -#[cfg(apple)] -bitflags! { - /// `COPYFILE_*` constants for use with [`fcopyfile`]. - /// - /// [`fcopyfile`]: crate::fs::fcopyfile - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CopyfileFlags: ffi::c_uint { - /// `COPYFILE_ACL` - const ACL = copyfile::ACL; - - /// `COPYFILE_STAT` - const STAT = copyfile::STAT; - - /// `COPYFILE_XATTR` - const XATTR = copyfile::XATTR; - - /// `COPYFILE_DATA` - const DATA = copyfile::DATA; - - /// `COPYFILE_SECURITY` - const SECURITY = copyfile::SECURITY; - - /// `COPYFILE_METADATA` - const METADATA = copyfile::METADATA; - - /// `COPYFILE_ALL` - const ALL = copyfile::ALL; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `RESOLVE_*` constants for use with [`openat2`]. - /// - /// [`openat2`]: crate::fs::openat2 - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ResolveFlags: u64 { - /// `RESOLVE_NO_XDEV` - const NO_XDEV = 0x01; - - /// `RESOLVE_NO_MAGICLINKS` - const NO_MAGICLINKS = 0x02; - - /// `RESOLVE_NO_SYMLINKS` - const NO_SYMLINKS = 0x04; - - /// `RESOLVE_BENEATH` - const BENEATH = 0x08; - - /// `RESOLVE_IN_ROOT` - const IN_ROOT = 0x10; - - /// `RESOLVE_CACHED` (since Linux 5.12) - const CACHED = 0x20; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `RENAME_*` constants for use with [`renameat_with`]. - /// - /// [`renameat_with`]: crate::fs::renameat_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RenameFlags: ffi::c_uint { - /// `RENAME_EXCHANGE` - const EXCHANGE = bitcast!(c::RENAME_EXCHANGE); - - /// `RENAME_NOREPLACE` - const NOREPLACE = bitcast!(c::RENAME_NOREPLACE); - - /// `RENAME_WHITEOUT` - const WHITEOUT = bitcast!(c::RENAME_WHITEOUT); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(apple)] -bitflags! { - /// `RENAME_*` constants for use with [`renameat_with`]. - /// - /// [`renameat_with`]: crate::fs::renameat_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RenameFlags: ffi::c_uint { - /// `RENAME_SWAP` - const EXCHANGE = bitcast!(c::RENAME_SWAP); - - /// `RENAME_EXCL` - const NOREPLACE = bitcast!(c::RENAME_EXCL); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. -/// -/// [`mknodat`]: crate::fs::mknodat -/// [`Stat`]: crate::fs::Stat -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum FileType { - /// `S_IFREG` - RegularFile = c::S_IFREG as isize, - - /// `S_IFDIR` - Directory = c::S_IFDIR as isize, - - /// `S_IFLNK` - Symlink = c::S_IFLNK as isize, - - /// `S_IFIFO` - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. - #[doc(alias = "IFO")] - Fifo = c::S_IFIFO as isize, - - /// `S_IFSOCK` - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. - Socket = c::S_IFSOCK as isize, - - /// `S_IFCHR` - CharacterDevice = c::S_IFCHR as isize, - - /// `S_IFBLK` - BlockDevice = c::S_IFBLK as isize, - - /// An unknown filesystem object. - Unknown, -} - -impl FileType { - /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of - /// a `Stat`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - match (st_mode as c::mode_t) & c::S_IFMT { - c::S_IFREG => Self::RegularFile, - c::S_IFDIR => Self::Directory, - c::S_IFLNK => Self::Symlink, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. - c::S_IFIFO => Self::Fifo, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. - c::S_IFSOCK => Self::Socket, - c::S_IFCHR => Self::CharacterDevice, - c::S_IFBLK => Self::BlockDevice, - _ => Self::Unknown, - } - } - - /// Construct an `st_mode` value from a `FileType`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - match self { - Self::RegularFile => c::S_IFREG as RawMode, - Self::Directory => c::S_IFDIR as RawMode, - Self::Symlink => c::S_IFLNK as RawMode, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. - Self::Fifo => c::S_IFIFO as RawMode, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. - Self::Socket => c::S_IFSOCK as RawMode, - Self::CharacterDevice => c::S_IFCHR as RawMode, - Self::BlockDevice => c::S_IFBLK as RawMode, - Self::Unknown => c::S_IFMT as RawMode, - } - } - - /// Construct a `FileType` from the `d_type` field of a `c::dirent`. - #[cfg(not(any( - solarish, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "redox", - target_os = "vita" - )))] - #[inline] - pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { - match d_type { - c::DT_REG => Self::RegularFile, - c::DT_DIR => Self::Directory, - c::DT_LNK => Self::Symlink, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_SOCK`. - c::DT_SOCK => Self::Socket, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_FIFO`. - c::DT_FIFO => Self::Fifo, - c::DT_CHR => Self::CharacterDevice, - c::DT_BLK => Self::BlockDevice, - // c::DT_UNKNOWN | - _ => Self::Unknown, - } - } -} - -/// `POSIX_FADV_*` constants for use with [`fadvise`]. -/// -/// [`fadvise`]: crate::fs::fadvise -#[cfg(not(any( - apple, - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "horizon", - target_os = "haiku", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum Advice { - /// `POSIX_FADV_NORMAL` - Normal = c::POSIX_FADV_NORMAL as c::c_uint, - - /// `POSIX_FADV_SEQUENTIAL` - Sequential = c::POSIX_FADV_SEQUENTIAL as c::c_uint, - - /// `POSIX_FADV_RANDOM` - Random = c::POSIX_FADV_RANDOM as c::c_uint, - - /// `POSIX_FADV_NOREUSE` - NoReuse = c::POSIX_FADV_NOREUSE as c::c_uint, - - /// `POSIX_FADV_WILLNEED` - WillNeed = c::POSIX_FADV_WILLNEED as c::c_uint, - - /// `POSIX_FADV_DONTNEED` - DontNeed = c::POSIX_FADV_DONTNEED as c::c_uint, -} - -#[cfg(any(linux_kernel, target_os = "freebsd"))] -bitflags! { - /// `MFD_*` constants for use with [`memfd_create`]. - /// - /// [`memfd_create`]: crate::fs::memfd_create - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MemfdFlags: ffi::c_uint { - /// `MFD_CLOEXEC` - const CLOEXEC = c::MFD_CLOEXEC; - - /// `MFD_ALLOW_SEALING` - const ALLOW_SEALING = c::MFD_ALLOW_SEALING; - - /// `MFD_HUGETLB` (since Linux 4.14) - const HUGETLB = c::MFD_HUGETLB; - - /// `MFD_NOEXEC_SEAL` (since Linux 6.3) - #[cfg(linux_kernel)] - const NOEXEC_SEAL = c::MFD_NOEXEC_SEAL; - /// `MFD_EXEC` (since Linux 6.3) - #[cfg(linux_kernel)] - const EXEC = c::MFD_EXEC; - - /// `MFD_HUGE_64KB` - const HUGE_64KB = c::MFD_HUGE_64KB; - /// `MFD_HUGE_512JB` - const HUGE_512KB = c::MFD_HUGE_512KB; - /// `MFD_HUGE_1MB` - const HUGE_1MB = c::MFD_HUGE_1MB; - /// `MFD_HUGE_2MB` - const HUGE_2MB = c::MFD_HUGE_2MB; - /// `MFD_HUGE_8MB` - const HUGE_8MB = c::MFD_HUGE_8MB; - /// `MFD_HUGE_16MB` - const HUGE_16MB = c::MFD_HUGE_16MB; - /// `MFD_HUGE_32MB` - const HUGE_32MB = c::MFD_HUGE_32MB; - /// `MFD_HUGE_256MB` - const HUGE_256MB = c::MFD_HUGE_256MB; - /// `MFD_HUGE_512MB` - const HUGE_512MB = c::MFD_HUGE_512MB; - /// `MFD_HUGE_1GB` - const HUGE_1GB = c::MFD_HUGE_1GB; - /// `MFD_HUGE_2GB` - const HUGE_2GB = c::MFD_HUGE_2GB; - /// `MFD_HUGE_16GB` - const HUGE_16GB = c::MFD_HUGE_16GB; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -bitflags! { - /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and - /// [`fcntl_get_seals`]. - /// - /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals - /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SealFlags: u32 { - /// `F_SEAL_SEAL` - const SEAL = bitcast!(c::F_SEAL_SEAL); - /// `F_SEAL_SHRINK` - const SHRINK = bitcast!(c::F_SEAL_SHRINK); - /// `F_SEAL_GROW` - const GROW = bitcast!(c::F_SEAL_GROW); - /// `F_SEAL_WRITE` - const WRITE = bitcast!(c::F_SEAL_WRITE); - /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) - #[cfg(linux_kernel)] - const FUTURE_WRITE = bitcast!(c::F_SEAL_FUTURE_WRITE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(any( - netbsdlike, - target_os = "espidf", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita" -)))] -bitflags! { - /// `FALLOC_FL_*` constants for use with [`fallocate`]. - /// - /// [`fallocate`]: crate::fs::fallocate - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FallocateFlags: u32 { - /// `FALLOC_FL_KEEP_SIZE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "wasi", - )))] - const KEEP_SIZE = bitcast!(c::FALLOC_FL_KEEP_SIZE); - /// `FALLOC_FL_PUNCH_HOLE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "wasi", - )))] - const PUNCH_HOLE = bitcast!(c::FALLOC_FL_PUNCH_HOLE); - /// `FALLOC_FL_NO_HIDE_STALE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "l4re", - target_os = "linux", - target_os = "wasi", - )))] - const NO_HIDE_STALE = bitcast!(c::FALLOC_FL_NO_HIDE_STALE); - /// `FALLOC_FL_COLLAPSE_RANGE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "emscripten", - target_os = "wasi", - )))] - const COLLAPSE_RANGE = bitcast!(c::FALLOC_FL_COLLAPSE_RANGE); - /// `FALLOC_FL_ZERO_RANGE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "emscripten", - target_os = "wasi", - )))] - const ZERO_RANGE = bitcast!(c::FALLOC_FL_ZERO_RANGE); - /// `FALLOC_FL_INSERT_RANGE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "emscripten", - target_os = "wasi", - )))] - const INSERT_RANGE = bitcast!(c::FALLOC_FL_INSERT_RANGE); - /// `FALLOC_FL_UNSHARE_RANGE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "emscripten", - target_os = "wasi", - )))] - const UNSHARE_RANGE = bitcast!(c::FALLOC_FL_UNSHARE_RANGE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -bitflags! { - /// `ST_*` constants for use with [`StatVfs`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct StatVfsMountFlags: u64 { - /// `ST_MANDLOCK` - #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] - const MANDLOCK = c::ST_MANDLOCK as u64; - - /// `ST_NOATIME` - #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] - const NOATIME = c::ST_NOATIME as u64; - - /// `ST_NODEV` - #[cfg(any( - linux_kernel, - target_os = "aix", - target_os = "emscripten", - target_os = "fuchsia" - ))] - const NODEV = c::ST_NODEV as u64; - - /// `ST_NODIRATIME` - #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] - const NODIRATIME = c::ST_NODIRATIME as u64; - - /// `ST_NOEXEC` - #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] - const NOEXEC = c::ST_NOEXEC as u64; - - /// `ST_NOSUID` - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] - const NOSUID = c::ST_NOSUID as u64; - - /// `ST_RDONLY` - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] - const RDONLY = c::ST_RDONLY as u64; - - /// `ST_RELATIME` - #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] - const RELATIME = c::ST_RELATIME as u64; - - /// `ST_SYNCHRONOUS` - #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] - const SYNCHRONOUS = c::ST_SYNCHRONOUS as u64; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `LOCK_*` constants for use with [`flock`] and [`fcntl_lock`]. -/// -/// [`flock`]: crate::fs::flock -/// [`fcntl_lock`]: crate::fs::fcntl_lock -// Solaris doesn't support `flock` and doesn't define `LOCK_SH` etc., but we -// reuse this `FlockOperation` enum for `fcntl_lock`, so on Solaris we use -// our own made-up integer values. -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(u32)] -pub enum FlockOperation { - /// `LOCK_SH` - #[cfg(not(target_os = "solaris"))] - LockShared = bitcast!(c::LOCK_SH), - /// `LOCK_SH` - #[cfg(target_os = "solaris")] - LockShared = bitcast!(1), - /// `LOCK_EX` - #[cfg(not(target_os = "solaris"))] - LockExclusive = bitcast!(c::LOCK_EX), - /// `LOCK_EX` - #[cfg(target_os = "solaris")] - LockExclusive = bitcast!(2), - /// `LOCK_UN` - #[cfg(not(target_os = "solaris"))] - Unlock = bitcast!(c::LOCK_UN), - /// `LOCK_UN` - #[cfg(target_os = "solaris")] - Unlock = bitcast!(8), - /// `LOCK_SH | LOCK_NB` - #[cfg(not(target_os = "solaris"))] - NonBlockingLockShared = bitcast!(c::LOCK_SH | c::LOCK_NB), - /// `LOCK_SH | LOCK_NB` - #[cfg(target_os = "solaris")] - NonBlockingLockShared = bitcast!(1 | 4), - /// `LOCK_EX | LOCK_NB` - #[cfg(not(target_os = "solaris"))] - NonBlockingLockExclusive = bitcast!(c::LOCK_EX | c::LOCK_NB), - /// `LOCK_EX | LOCK_NB` - #[cfg(target_os = "solaris")] - NonBlockingLockExclusive = bitcast!(2 | 4), - /// `LOCK_UN | LOCK_NB` - #[cfg(not(target_os = "solaris"))] - NonBlockingUnlock = bitcast!(c::LOCK_UN | c::LOCK_NB), - /// `LOCK_UN | LOCK_NB` - #[cfg(target_os = "solaris")] - NonBlockingUnlock = bitcast!(8 | 4), -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(not(any(linux_like, target_os = "hurd", target_os = "netbsd")))] -pub type Stat = c::stat; - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(any( - all(linux_kernel, target_pointer_width = "64"), - target_os = "hurd", - target_os = "emscripten", - target_os = "l4re", -))] -pub type Stat = c::stat64; - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -// On 32-bit, Linux's `struct stat64` has a 32-bit `st_mtime` and friends, so -// we use our own struct, populated from `statx` where possible, to avoid the -// y2038 bug. -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -pub struct Stat { - pub st_dev: u64, - pub st_mode: u32, - pub st_nlink: u64, - pub st_uid: u32, - pub st_gid: u32, - pub st_rdev: u64, - pub st_size: i64, - pub st_blksize: u32, - pub st_blocks: u64, - pub st_atime: i64, - pub st_atime_nsec: u32, - pub st_mtime: i64, - pub st_mtime_nsec: u32, - pub st_ctime: i64, - pub st_ctime_nsec: u32, - pub st_ino: u64, -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -// NetBSD's `st_mtime_nsec` is named `st_mtimensec` so we declare our own -// `Stat` so that we can be consistent with other platforms. -#[cfg(target_os = "netbsd")] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[repr(C)] -pub struct Stat { - pub st_dev: c::dev_t, - pub st_mode: c::mode_t, - pub st_ino: c::ino_t, - pub st_nlink: c::nlink_t, - pub st_uid: c::uid_t, - pub st_gid: c::gid_t, - pub st_rdev: c::dev_t, - pub st_atime: c::time_t, - pub st_atime_nsec: c::c_long, - pub st_mtime: c::time_t, - pub st_mtime_nsec: c::c_long, - pub st_ctime: c::time_t, - pub st_ctime_nsec: c::c_long, - pub st_birthtime: c::time_t, - pub st_birthtime_nsec: c::c_long, - pub st_size: c::off_t, - pub st_blocks: c::blkcnt_t, - pub st_blksize: c::blksize_t, - pub st_flags: u32, - pub st_gen: u32, - pub st_spare: [u32; 2], -} - -/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. -/// -/// [`statfs`]: crate::fs::statfs -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(not(any( - linux_like, - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[allow(clippy::module_name_repetitions)] -pub type StatFs = c::statfs; - -/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. -/// -/// [`statfs`]: crate::fs::statfs -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(linux_like)] -pub type StatFs = c::statfs64; - -/// `fsid_t` for use with [`StatFs`]. -#[cfg(not(any( - solarish, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -pub type Fsid = c::fsid_t; - -/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`]. -/// -/// [`statvfs`]: crate::fs::statvfs -/// [`fstatvfs`]: crate::fs::fstatvfs -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -#[allow(missing_docs)] -pub struct StatVfs { - pub f_bsize: u64, - pub f_frsize: u64, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_favail: u64, - pub f_fsid: u64, - pub f_flag: StatVfsMountFlags, - pub f_namemax: u64, -} - -/// `mode_t` -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -pub type RawMode = c::mode_t; - -/// `mode_t` -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -pub type RawMode = ffi::c_uint; - -/// `dev_t` -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -pub type Dev = c::dev_t; - -/// `dev_t` -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -pub type Dev = ffi::c_ulonglong; - -/// `__fsword_t` -#[cfg(all( - target_os = "linux", - not(target_env = "musl"), - not(target_arch = "s390x"), -))] -pub type FsWord = c::__fsword_t; - -/// `__fsword_t` -#[cfg(all( - any(target_os = "android", all(target_os = "linux", target_env = "musl")), - target_pointer_width = "32", -))] -pub type FsWord = u32; - -/// `__fsword_t` -#[cfg(all( - any(target_os = "android", all(target_os = "linux", target_env = "musl")), - not(target_arch = "s390x"), - target_pointer_width = "64", -))] -pub type FsWord = u64; - -/// `__fsword_t` -// s390x uses `u32` for `statfs` entries on glibc, even though `__fsword_t` is -// `u64`. -#[cfg(all(target_os = "linux", target_arch = "s390x", target_env = "gnu"))] -pub type FsWord = u32; - -/// `__fsword_t` -// s390x uses `u64` for `statfs` entries on musl. -#[cfg(all(target_os = "linux", target_arch = "s390x", target_env = "musl"))] -pub type FsWord = u64; - -/// `copyfile_state_t`—State for use with [`fcopyfile`]. -/// -/// [`fcopyfile`]: crate::fs::fcopyfile -#[cfg(apple)] -#[allow(non_camel_case_types)] -#[repr(transparent)] -#[derive(Copy, Clone)] -pub struct copyfile_state_t(pub(crate) *mut c::c_void); diff --git a/vendor/rustix/src/backend/libc/io/errno.rs b/vendor/rustix/src/backend/libc/io/errno.rs deleted file mode 100644 index 81f0e489..00000000 --- a/vendor/rustix/src/backend/libc/io/errno.rs +++ /dev/null @@ -1,1114 +0,0 @@ -//! The `rustix` `Errno` type. -//! -//! This type holds an OS error code, which conceptually corresponds to an -//! `errno` value. - -use crate::backend::c; -use libc_errno::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/9799919799/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§ion=2 -/// [illumos]: https://illumos.org/man/3C/errno -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Error-Codes.html -#[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( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const ADV: Self = Self(c::EADV); - /// `EAFNOSUPPORT` - #[cfg(not(target_os = "l4re"))] - pub const AFNOSUPPORT: Self = Self(c::EAFNOSUPPORT); - /// `EAGAIN` - pub const AGAIN: Self = Self(c::EAGAIN); - /// `EALREADY` - #[cfg(not(target_os = "l4re"))] - pub const ALREADY: Self = Self(c::EALREADY); - /// `EAUTH` - #[cfg(bsd)] - pub const AUTH: Self = Self(c::EAUTH); - /// `EBADE` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const BADE: Self = Self(c::EBADE); - /// `EBADF` - pub const BADF: Self = Self(c::EBADF); - /// `EBADFD` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const BADFD: Self = Self(c::EBADFD); - /// `EBADMSG` - #[cfg(not(any(windows, target_os = "l4re")))] - pub const BADMSG: Self = Self(c::EBADMSG); - /// `EBADR` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const BADR: Self = Self(c::EBADR); - /// `EBADRPC` - #[cfg(bsd)] - pub const BADRPC: Self = Self(c::EBADRPC); - /// `EBADRQC` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const BADRQC: Self = Self(c::EBADRQC); - /// `EBADSLT` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const BADSLT: Self = Self(c::EBADSLT); - /// `EBFONT` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const BFONT: Self = Self(c::EBFONT); - /// `EBUSY` - #[cfg(not(windows))] - pub const BUSY: Self = Self(c::EBUSY); - /// `ECANCELED` - #[cfg(not(target_os = "l4re"))] - pub const CANCELED: Self = Self(c::ECANCELED); - /// `ECAPMODE` - #[cfg(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( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const CHRNG: Self = Self(c::ECHRNG); - /// `ECOMM` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - 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( - bsd, - windows, - target_os = "aix", - target_os = "android", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "vita", - target_os = "wasi", - )))] - pub const DEADLOCK: Self = Self(c::EDEADLOCK); - /// `EDESTADDRREQ` - #[cfg(not(target_os = "l4re"))] - 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(freebsdlike)] - pub const DOOFUS: Self = Self(c::EDOOFUS); - /// `EDOTDOT` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - 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(bsd, target_env = "newlib"))] - pub const FTYPE: Self = Self(c::EFTYPE); - /// `EHOSTDOWN` - #[cfg(not(any(target_os = "l4re", target_os = "wasi")))] - pub const HOSTDOWN: Self = Self(c::EHOSTDOWN); - /// `EHOSTUNREACH` - pub const HOSTUNREACH: Self = Self(c::EHOSTUNREACH); - /// `EHWPOISON` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", - )))] - pub const HWPOISON: Self = Self(c::EHWPOISON); - /// `EIDRM` - #[cfg(not(any(windows, target_os = "l4re")))] - pub const IDRM: Self = Self(c::EIDRM); - /// `EILSEQ` - #[cfg(not(any(windows, target_os = "l4re")))] - pub const ILSEQ: Self = Self(c::EILSEQ); - /// `EINPROGRESS` - #[cfg(not(target_os = "l4re"))] - 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` - #[cfg(not(target_os = "l4re"))] - pub const ISCONN: Self = Self(c::EISCONN); - /// `EISDIR` - #[cfg(not(windows))] - pub const ISDIR: Self = Self(c::EISDIR); - /// `EISNAM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const ISNAM: Self = Self(c::EISNAM); - /// `EKEYEXPIRED` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const KEYEXPIRED: Self = Self(c::EKEYEXPIRED); - /// `EKEYREJECTED` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const KEYREJECTED: Self = Self(c::EKEYREJECTED); - /// `EKEYREVOKED` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const KEYREVOKED: Self = Self(c::EKEYREVOKED); - /// `EL2HLT` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const L2HLT: Self = Self(c::EL2HLT); - /// `EL2NSYNC` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const L2NSYNC: Self = Self(c::EL2NSYNC); - /// `EL3HLT` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const L3HLT: Self = Self(c::EL3HLT); - /// `EL3RST` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const L3RST: Self = Self(c::EL3RST); - /// `ELIBACC` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const LIBACC: Self = Self(c::ELIBACC); - /// `ELIBBAD` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const LIBBAD: Self = Self(c::ELIBBAD); - /// `ELIBEXEC` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const LIBEXEC: Self = Self(c::ELIBEXEC); - /// `ELIBMAX` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const LIBMAX: Self = Self(c::ELIBMAX); - /// `ELIBSCN` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const LIBSCN: Self = Self(c::ELIBSCN); - /// `ELNRNG` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const LNRNG: Self = Self(c::ELNRNG); - /// `ELOOP` - pub const LOOP: Self = Self(c::ELOOP); - /// `EMEDIUMTYPE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - 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` - #[cfg(not(target_os = "l4re"))] - pub const MSGSIZE: Self = Self(c::EMSGSIZE); - /// `EMULTIHOP` - #[cfg(not(any(windows, target_os = "l4re", target_os = "openbsd")))] - pub const MULTIHOP: Self = Self(c::EMULTIHOP); - /// `ENAMETOOLONG` - pub const NAMETOOLONG: Self = Self(c::ENAMETOOLONG); - /// `ENAVAIL` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const NAVAIL: Self = Self(c::ENAVAIL); - /// `ENEEDAUTH` - #[cfg(bsd)] - pub const NEEDAUTH: Self = Self(c::ENEEDAUTH); - /// `ENETDOWN` - pub const NETDOWN: Self = Self(c::ENETDOWN); - /// `ENETRESET` - #[cfg(not(target_os = "l4re"))] - 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( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const NOANO: Self = Self(c::ENOANO); - /// `ENOATTR` - #[cfg(any(bsd, target_os = "haiku"))] - pub const NOATTR: Self = Self(c::ENOATTR); - /// `ENOBUFS` - #[cfg(not(target_os = "l4re"))] - pub const NOBUFS: Self = Self(c::ENOBUFS); - /// `ENOCSI` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const NOCSI: Self = Self(c::ENOCSI); - /// `ENODATA` - #[cfg(not(any( - freebsdlike, - windows, - target_os = "haiku", - 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( - solarish, - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const NOKEY: Self = Self(c::ENOKEY); - /// `ENOLCK` - #[cfg(not(any(windows, target_os = "l4re")))] - pub const NOLCK: Self = Self(c::ENOLCK); - /// `ENOLINK` - #[cfg(not(any(windows, target_os = "l4re", target_os = "openbsd")))] - pub const NOLINK: Self = Self(c::ENOLINK); - /// `ENOMEDIUM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - 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(any(windows, target_os = "l4re")))] - pub const NOMSG: Self = Self(c::ENOMSG); - /// `ENONET` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const NONET: Self = Self(c::ENONET); - /// `ENOPKG` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const NOPKG: Self = Self(c::ENOPKG); - /// `ENOPROTOOPT` - #[cfg(not(target_os = "l4re"))] - pub const NOPROTOOPT: Self = Self(c::ENOPROTOOPT); - /// `ENOSPC` - #[cfg(not(windows))] - pub const NOSPC: Self = Self(c::ENOSPC); - /// `ENOSR` - #[cfg(not(any( - freebsdlike, - windows, - target_os = "haiku", - target_os = "l4re", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOSR: Self = Self(c::ENOSR); - /// `ENOSTR` - #[cfg(not(any( - freebsdlike, - windows, - target_os = "haiku", - target_os = "l4re", - 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 = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita", - 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( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const NOTNAM: Self = Self(c::ENOTNAM); - /// `ENOTRECOVERABLE` - #[cfg(not(any( - freebsdlike, - netbsdlike, - windows, - target_os = "haiku", - target_os = "l4re" - )))] - pub const NOTRECOVERABLE: Self = Self(c::ENOTRECOVERABLE); - /// `ENOTSOCK` - #[cfg(not(target_os = "l4re"))] - 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( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - 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(any(windows, target_os = "l4re")))] - pub const OVERFLOW: Self = Self(c::EOVERFLOW); - /// `EOWNERDEAD` - #[cfg(not(any( - freebsdlike, - netbsdlike, - windows, - target_os = "haiku", - target_os = "l4re" - )))] - pub const OWNERDEAD: Self = Self(c::EOWNERDEAD); - /// `EPERM` - #[cfg(not(windows))] - pub const PERM: Self = Self(c::EPERM); - /// `EPFNOSUPPORT` - #[cfg(not(any(target_os = "l4re", target_os = "wasi")))] - pub const PFNOSUPPORT: Self = Self(c::EPFNOSUPPORT); - /// `EPIPE` - #[cfg(not(windows))] - pub const PIPE: Self = Self(c::EPIPE); - /// `EPROCLIM` - #[cfg(bsd)] - pub const PROCLIM: Self = Self(c::EPROCLIM); - /// `EPROCUNAVAIL` - #[cfg(bsd)] - pub const PROCUNAVAIL: Self = Self(c::EPROCUNAVAIL); - /// `EPROGMISMATCH` - #[cfg(bsd)] - pub const PROGMISMATCH: Self = Self(c::EPROGMISMATCH); - /// `EPROGUNAVAIL` - #[cfg(bsd)] - pub const PROGUNAVAIL: Self = Self(c::EPROGUNAVAIL); - /// `EPROTO` - #[cfg(not(any(windows, target_os = "l4re")))] - pub const PROTO: Self = Self(c::EPROTO); - /// `EPROTONOSUPPORT` - #[cfg(not(target_os = "l4re"))] - pub const PROTONOSUPPORT: Self = Self(c::EPROTONOSUPPORT); - /// `EPROTOTYPE` - #[cfg(not(target_os = "l4re"))] - 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( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const REMCHG: Self = Self(c::EREMCHG); - /// `EREMOTE` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const REMOTE: Self = Self(c::EREMOTE); - /// `EREMOTEIO` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const REMOTEIO: Self = Self(c::EREMOTEIO); - /// `ERESTART` - #[cfg(not(any( - bsd, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const RESTART: Self = Self(c::ERESTART); - /// `ERFKILL` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", - )))] - pub const RFKILL: Self = Self(c::ERFKILL); - /// `EROFS` - #[cfg(not(windows))] - pub const ROFS: Self = Self(c::EROFS); - /// `ERPCMISMATCH` - #[cfg(bsd)] - pub const RPCMISMATCH: Self = Self(c::ERPCMISMATCH); - /// `ESHUTDOWN` - #[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const SHUTDOWN: Self = Self(c::ESHUTDOWN); - /// `ESOCKTNOSUPPORT` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "l4re", - target_os = "vita", - 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( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const SRMNT: Self = Self(c::ESRMNT); - /// `ESTALE` - pub const STALE: Self = Self(c::ESTALE); - /// `ESTRPIPE` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi", - )))] - pub const STRPIPE: Self = Self(c::ESTRPIPE); - /// `ETIME` - #[cfg(not(any( - freebsdlike, - windows, - target_os = "l4re", - 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(any(target_os = "haiku", target_os = "l4re", 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( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "nto", - target_os = "vita", - target_os = "wasi", - )))] - pub const UCLEAN: Self = Self(c::EUCLEAN); - /// `EUNATCH` - #[cfg(not(any( - bsd, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - target_os = "wasi" - )))] - pub const UNATCH: Self = Self(c::EUNATCH); - /// `EUSERS` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "l4re", - target_os = "vita", - 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( - bsd, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "l4re", - target_os = "vita", - 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/backend/libc/io/mod.rs b/vendor/rustix/src/backend/libc/io/mod.rs deleted file mode 100644 index 48738857..00000000 --- a/vendor/rustix/src/backend/libc/io/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub(crate) mod errno; -#[cfg(not(windows))] -pub(crate) mod types; - -#[cfg_attr(windows, path = "windows_syscalls.rs")] -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/io/syscalls.rs b/vendor/rustix/src/backend/libc/io/syscalls.rs deleted file mode 100644 index f1231aaf..00000000 --- a/vendor/rustix/src/backend/libc/io/syscalls.rs +++ /dev/null @@ -1,303 +0,0 @@ -//! libc syscalls supporting `rustix::io`. - -use crate::backend::c; -#[cfg(not(target_os = "wasi"))] -use crate::backend::conv::ret_discarded_fd; -use crate::backend::conv::{borrowed_fd, ret, ret_c_int, ret_owned_fd, ret_usize}; -use crate::fd::{AsFd as _, BorrowedFd, OwnedFd, RawFd}; -#[cfg(not(any( - target_os = "aix", - target_os = "espidf", - target_os = "nto", - target_os = "vita", - target_os = "wasi" -)))] -use crate::io::DupFlags; -#[cfg(linux_kernel)] -use crate::io::ReadWriteFlags; -use crate::io::{self, FdFlags}; -use crate::ioctl::{IoctlOutput, Opcode}; -use core::cmp::min; -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -use { - crate::backend::MAX_IOV, - crate::io::{IoSlice, IoSliceMut}, -}; - -pub(crate) unsafe fn read(fd: BorrowedFd<'_>, buf: (*mut u8, usize)) -> io::Result<usize> { - ret_usize(c::read( - borrowed_fd(fd), - buf.0.cast(), - min(buf.1, READ_LIMIT), - )) -} - -pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result<usize> { - unsafe { - ret_usize(c::write( - borrowed_fd(fd), - buf.as_ptr().cast(), - min(buf.len(), READ_LIMIT), - )) - } -} - -pub(crate) unsafe fn pread( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - offset: u64, -) -> io::Result<usize> { - let len = min(buf.1, READ_LIMIT); - - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - - // ESP-IDF and Vita don't support 64-bit offsets, for example. - let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - ret_usize(c::pread(borrowed_fd(fd), buf.0.cast(), len, offset)) -} - -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; - - // ESP-IDF and Vita don't support 64-bit offsets, for example. - let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - unsafe { ret_usize(c::pwrite(borrowed_fd(fd), buf.as_ptr().cast(), len, offset)) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - unsafe { - ret_usize(c::readv( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV) as c::c_int, - )) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - unsafe { - ret_usize(c::writev( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV) as c::c_int, - )) - } -} - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -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; - - // ESP-IDF and Vita don't support 64-bit offsets, for example. - let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - unsafe { - ret_usize(c::preadv( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV) as c::c_int, - offset, - )) - } -} - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "horizon", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -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; - - // ESP-IDF and Vita don't support 64-bit offsets, for example. - let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - unsafe { - ret_usize(c::pwritev( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV) as c::c_int, - offset, - )) - } -} - -#[cfg(linux_kernel)] -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; - unsafe { - ret_usize(c::preadv2( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV) as c::c_int, - offset, - bitflags_bits!(flags), - )) - } -} - -#[cfg(linux_kernel)] -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; - unsafe { - ret_usize(c::pwritev2( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV) as c::c_int, - offset, - bitflags_bits!(flags), - )) - } -} - -// These functions are derived from Rust's library/std/src/sys/unix/fd.rs at -// revision 326ef470a8b379a180d6dc4bbef08990698a737a. - -// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`, with the -// manual 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; - -pub(crate) unsafe fn close(raw_fd: RawFd) { - let _ = c::close(raw_fd as c::c_int); -} - -#[cfg(feature = "try_close")] -pub(crate) unsafe fn try_close(raw_fd: RawFd) -> io::Result<()> { - ret(c::close(raw_fd as c::c_int)) -} - -#[inline] -pub(crate) unsafe fn ioctl( - fd: BorrowedFd<'_>, - request: Opcode, - arg: *mut c::c_void, -) -> io::Result<IoctlOutput> { - ret_c_int(c::ioctl(borrowed_fd(fd), request, arg)) -} - -#[inline] -pub(crate) unsafe fn ioctl_readonly( - fd: BorrowedFd<'_>, - request: Opcode, - arg: *mut c::c_void, -) -> io::Result<IoctlOutput> { - ioctl(fd, request, arg) -} - -pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result<FdFlags> { - let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFD))? }; - Ok(FdFlags::from_bits_retain(bitcast!(flags))) -} - -pub(crate) fn fcntl_setfd(fd: BorrowedFd<'_>, flags: FdFlags) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFD, flags.bits())) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::fcntl(borrowed_fd(fd), c::F_DUPFD_CLOEXEC, min)) } -} - -#[cfg(target_os = "espidf")] -pub(crate) fn fcntl_dupfd(fd: BorrowedFd<'_>, min: RawFd) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::fcntl(borrowed_fd(fd), c::F_DUPFD, min)) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::dup(borrowed_fd(fd))) } -} - -#[allow(clippy::needless_pass_by_ref_mut)] -#[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()))) } -} - -#[allow(clippy::needless_pass_by_ref_mut)] -#[cfg(not(any( - apple, - target_os = "aix", - target_os = "android", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - 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()), - bitflags_bits!(flags), - )) - } -} - -#[cfg(any( - apple, - target_os = "android", - target_os = "dragonfly", - target_os = "haiku", - 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) -} diff --git a/vendor/rustix/src/backend/libc/io/types.rs b/vendor/rustix/src/backend/libc/io/types.rs deleted file mode 100644 index 510206f9..00000000 --- a/vendor/rustix/src/backend/libc/io/types.rs +++ /dev/null @@ -1,65 +0,0 @@ -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: u32 { - /// `FD_CLOEXEC` - const CLOEXEC = bitcast!(c::FD_CLOEXEC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -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: u32 { - /// `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; - } -} - -#[cfg(not(target_os = "wasi"))] -bitflags! { - /// `O_*` constants for use with [`dup2`]. - /// - /// [`dup2`]: crate::io::dup2 - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct DupFlags: u32 { - /// `O_CLOEXEC` - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "android", - target_os = "redox", - )))] // Android 5.0 has dup3, but libc doesn't have bindings - const CLOEXEC = bitcast!(c::O_CLOEXEC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/io/windows_syscalls.rs b/vendor/rustix/src/backend/libc/io/windows_syscalls.rs deleted file mode 100644 index 0f953d7f..00000000 --- a/vendor/rustix/src/backend/libc/io/windows_syscalls.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Windows system calls in the `io` module. - -use crate::backend::c; -#[cfg(feature = "try_close")] -use crate::backend::conv::ret; -use crate::backend::conv::{borrowed_fd, ret_c_int, ret_send_recv, send_recv_len}; -use crate::fd::{BorrowedFd, RawFd}; -use crate::io; -use crate::ioctl::{IoctlOutput, Opcode}; - -pub(crate) unsafe fn read(fd: BorrowedFd<'_>, buf: (*mut u8, usize)) -> io::Result<usize> { - // `read` on a socket is equivalent to `recv` with no flags. - ret_send_recv(c::recv( - borrowed_fd(fd), - buf.0.cast(), - send_recv_len(buf.1), - 0, - )) -} - -pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result<usize> { - // `write` on a socket is equivalent to `send` with no flags. - unsafe { - ret_send_recv(c::send( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - 0, - )) - } -} - -pub(crate) unsafe fn close(raw_fd: RawFd) { - let _ = c::closesocket(raw_fd as c::SOCKET); -} - -#[cfg(feature = "try_close")] -pub(crate) unsafe fn try_close(raw_fd: RawFd) -> io::Result<()> { - ret(c::closesocket(raw_fd as c::SOCKET)) -} - -#[inline] -pub(crate) unsafe fn ioctl( - fd: BorrowedFd<'_>, - request: Opcode, - arg: *mut c::c_void, -) -> io::Result<IoctlOutput> { - ret_c_int(c::ioctl(borrowed_fd(fd), request, arg.cast())) -} - -#[inline] -pub(crate) unsafe fn ioctl_readonly( - fd: BorrowedFd<'_>, - request: Opcode, - arg: *mut c::c_void, -) -> io::Result<IoctlOutput> { - ioctl(fd, request, arg) -} diff --git a/vendor/rustix/src/backend/libc/io_uring/mod.rs b/vendor/rustix/src/backend/libc/io_uring/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/libc/io_uring/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/io_uring/syscalls.rs b/vendor/rustix/src/backend/libc/io_uring/syscalls.rs deleted file mode 100644 index 8bf1e987..00000000 --- a/vendor/rustix/src/backend/libc/io_uring/syscalls.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! libc syscalls supporting `rustix::io_uring`. - -use crate::backend::c; -use crate::backend::conv::{borrowed_fd, ret_owned_fd, ret_u32}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterFlags, IoringRegisterOp}; - -#[inline] -pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> { - syscall! { - fn io_uring_setup( - entries: u32, - params: *mut io_uring_params - ) via SYS_io_uring_setup -> c::c_int - } - unsafe { ret_owned_fd(io_uring_setup(entries, params)) } -} - -#[inline] -pub(crate) unsafe fn io_uring_register( - fd: BorrowedFd<'_>, - opcode: IoringRegisterOp, - arg: *const c::c_void, - nr_args: u32, -) -> io::Result<u32> { - syscall! { - fn io_uring_register( - fd: c::c_uint, - opcode: c::c_uint, - arg: *const c::c_void, - nr_args: c::c_uint - ) via SYS_io_uring_register -> c::c_int - } - ret_u32(io_uring_register( - borrowed_fd(fd) as _, - opcode as u32, - arg, - nr_args, - )) -} - -#[inline] -pub(crate) unsafe fn io_uring_register_with( - fd: BorrowedFd<'_>, - opcode: IoringRegisterOp, - flags: IoringRegisterFlags, - arg: *const c::c_void, - nr_args: u32, -) -> io::Result<u32> { - syscall! { - fn io_uring_register( - fd: c::c_uint, - opcode: c::c_uint, - arg: *const c::c_void, - nr_args: c::c_uint - ) via SYS_io_uring_register -> c::c_int - } - ret_u32(io_uring_register( - borrowed_fd(fd) as _, - (opcode as u32) | bitflags_bits!(flags), - arg, - nr_args, - )) -} - -#[inline] -pub(crate) unsafe fn io_uring_enter( - fd: BorrowedFd<'_>, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - arg: *const c::c_void, - size: usize, -) -> io::Result<u32> { - syscall! { - fn io_uring_enter2( - fd: c::c_uint, - to_submit: c::c_uint, - min_complete: c::c_uint, - flags: c::c_uint, - arg: *const c::c_void, - size: usize - ) via SYS_io_uring_enter -> c::c_int - } - ret_u32(io_uring_enter2( - borrowed_fd(fd) as _, - to_submit, - min_complete, - bitflags_bits!(flags), - arg, - size, - )) -} diff --git a/vendor/rustix/src/backend/libc/mm/mod.rs b/vendor/rustix/src/backend/libc/mm/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/libc/mm/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/mm/syscalls.rs b/vendor/rustix/src/backend/libc/mm/syscalls.rs deleted file mode 100644 index 33bc9cac..00000000 --- a/vendor/rustix/src/backend/libc/mm/syscalls.rs +++ /dev/null @@ -1,244 +0,0 @@ -//! libc syscalls supporting `rustix::mm`. - -#[cfg(not(target_os = "redox"))] -use super::types::Advice; -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -use super::types::MlockAllFlags; -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -use super::types::MremapFlags; -use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}; -#[cfg(linux_kernel)] -use super::types::{MlockFlags, UserfaultfdFlags}; -use crate::backend::c; -#[cfg(linux_kernel)] -use crate::backend::conv::ret_owned_fd; -use crate::backend::conv::{borrowed_fd, no_fd, ret}; -use crate::fd::BorrowedFd; -#[cfg(linux_kernel)] -use crate::fd::OwnedFd; -use crate::io; - -#[cfg(not(target_os = "redox"))] -pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { - // On Linux platforms, `MADV_DONTNEED` has the same value as - // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different - // value, and check for it here. - #[cfg(target_os = "linux")] - if let Advice::LinuxDontNeed = advice { - return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) }; - } - - #[cfg(not(target_os = "android"))] - { - let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) }; - - // `posix_madvise` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } - } - - #[cfg(target_os = "android")] - { - if let Advice::DontNeed = advice { - // Do nothing. Linux's `MADV_DONTNEED` isn't the same as - // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`. - Ok(()) - } else { - unsafe { ret(c::madvise(addr, len, advice as c::c_int)) } - } - } -} - -pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - let err = c::msync(addr, len, bitflags_bits!(flags)); - - // `msync` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -pub(crate) unsafe fn mmap( - ptr: *mut c::c_void, - len: usize, - prot: ProtFlags, - flags: MapFlags, - fd: BorrowedFd<'_>, - offset: u64, -) -> io::Result<*mut c::c_void> { - let res = c::mmap( - ptr, - len, - bitflags_bits!(prot), - bitflags_bits!(flags), - borrowed_fd(fd), - offset as i64, - ); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -pub(crate) unsafe fn mmap_anonymous( - ptr: *mut c::c_void, - len: usize, - prot: ProtFlags, - flags: MapFlags, -) -> io::Result<*mut c::c_void> { - let res = c::mmap( - ptr, - len, - bitflags_bits!(prot), - bitflags_bits!(flags | MapFlags::from_bits_retain(bitcast!(c::MAP_ANONYMOUS))), - no_fd(), - 0, - ); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -pub(crate) unsafe fn mprotect( - ptr: *mut c::c_void, - len: usize, - flags: MprotectFlags, -) -> io::Result<()> { - ret(c::mprotect(ptr, len, bitflags_bits!(flags))) -} - -pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> { - ret(c::munmap(ptr, len)) -} - -/// # Safety -/// -/// `mremap` is primarily unsafe due to the `old_address` parameter, as -/// anything working with memory pointed to by raw pointers is unsafe. -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -pub(crate) unsafe fn mremap( - old_address: *mut c::c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, -) -> io::Result<*mut c::c_void> { - let res = c::mremap(old_address, old_size, new_size, bitflags_bits!(flags)); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -/// # Safety -/// -/// `mremap_fixed` is primarily unsafe due to the `old_address` and -/// `new_address` parameters, as anything working with memory pointed to by raw -/// pointers is unsafe. -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -pub(crate) unsafe fn mremap_fixed( - old_address: *mut c::c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, - new_address: *mut c::c_void, -) -> io::Result<*mut c::c_void> { - let res = c::mremap( - old_address, - old_size, - new_size, - bitflags_bits!(flags | MremapFlags::from_bits_retain(bitcast!(c::MAP_FIXED))), - new_address, - ); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -/// # Safety -/// -/// `mlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(c::mlock(addr, length)) -} - -/// # Safety -/// -/// `mlock_with` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[cfg(linux_kernel)] -#[inline] -pub(crate) unsafe fn mlock_with( - addr: *mut c::c_void, - length: usize, - flags: MlockFlags, -) -> io::Result<()> { - weak_or_syscall! { - fn mlock2( - addr: *const c::c_void, - len: c::size_t, - flags: c::c_int - ) via SYS_mlock2 -> c::c_int - } - - ret(mlock2(addr, length, bitflags_bits!(flags))) -} - -/// # Safety -/// -/// `munlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(c::munlock(addr, length)) -} - -#[cfg(linux_kernel)] -pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { - syscall! { - fn userfaultfd( - flags: c::c_int - ) via SYS_userfaultfd -> c::c_int - } - ret_owned_fd(userfaultfd(bitflags_bits!(flags))) -} - -/// Locks all pages mapped into the address space of the calling process. -/// -/// This includes the pages of the code, data, and stack segment, as well as -/// shared libraries, user space kernel data, shared memory, and memory-mapped -/// files. All mapped pages are guaranteed to be resident in RAM when the call -/// returns successfully; the pages are guaranteed to stay in RAM until later -/// unlocked. -#[inline] -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> { - unsafe { ret(c::mlockall(bitflags_bits!(flags))) } -} - -/// Unlocks all pages mapped into the address space of the calling process. -#[inline] -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -pub(crate) fn munlockall() -> io::Result<()> { - unsafe { ret(c::munlockall()) } -} diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs deleted file mode 100644 index 0b99e3c4..00000000 --- a/vendor/rustix/src/backend/libc/mm/types.rs +++ /dev/null @@ -1,506 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `PROT_*` flags for use with [`mmap`]. - /// - /// For `PROT_NONE`, use `ProtFlags::empty()`. - /// - /// [`mmap`]: crate::mm::mmap - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ProtFlags: u32 { - /// `PROT_READ` - const READ = bitcast!(c::PROT_READ); - /// `PROT_WRITE` - const WRITE = bitcast!(c::PROT_WRITE); - /// `PROT_EXEC` - const EXEC = bitcast!(c::PROT_EXEC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `PROT_*` flags for use with [`mprotect`]. - /// - /// For `PROT_NONE`, use `MprotectFlags::empty()`. - /// - /// [`mprotect`]: crate::mm::mprotect - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MprotectFlags: u32 { - /// `PROT_READ` - const READ = bitcast!(c::PROT_READ); - /// `PROT_WRITE` - const WRITE = bitcast!(c::PROT_WRITE); - /// `PROT_EXEC` - const EXEC = bitcast!(c::PROT_EXEC); - /// `PROT_GROWSUP` - #[cfg(linux_kernel)] - const GROWSUP = bitcast!(c::PROT_GROWSUP); - /// `PROT_GROWSDOWN` - #[cfg(linux_kernel)] - const GROWSDOWN = bitcast!(c::PROT_GROWSDOWN); - /// `PROT_SEM` - #[cfg(linux_kernel)] - const SEM = linux_raw_sys::general::PROT_SEM; - /// `PROT_BTI` - #[cfg(all(linux_kernel, target_arch = "aarch64"))] - const BTI = linux_raw_sys::general::PROT_BTI; - /// `PROT_MTE` - #[cfg(all(linux_kernel, target_arch = "aarch64"))] - const MTE = linux_raw_sys::general::PROT_MTE; - /// `PROT_SAO` - #[cfg(all(linux_kernel, any(target_arch = "powerpc", target_arch = "powerpc64")))] - const SAO = linux_raw_sys::general::PROT_SAO; - /// `PROT_ADI` - #[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))] - const ADI = linux_raw_sys::general::PROT_ADI; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MAP_*` flags for use with [`mmap`]. - /// - /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. - /// - /// [`mmap`]: crate::mm::mmap - /// [`mmap_anonymous`]: crates::mm::mmap_anonymous - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MapFlags: u32 { - /// `MAP_SHARED` - const SHARED = bitcast!(c::MAP_SHARED); - /// `MAP_SHARED_VALIDATE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const SHARED_VALIDATE = bitcast!(c::MAP_SHARED_VALIDATE); - /// `MAP_PRIVATE` - const PRIVATE = bitcast!(c::MAP_PRIVATE); - /// `MAP_DENYWRITE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const DENYWRITE = bitcast!(c::MAP_DENYWRITE); - /// `MAP_FIXED` - const FIXED = bitcast!(c::MAP_FIXED); - /// `MAP_FIXED_NOREPLACE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const FIXED_NOREPLACE = bitcast!(c::MAP_FIXED_NOREPLACE); - /// `MAP_GROWSDOWN` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const GROWSDOWN = bitcast!(c::MAP_GROWSDOWN); - /// `MAP_HUGETLB` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const HUGETLB = bitcast!(c::MAP_HUGETLB); - /// `MAP_HUGE_2MB` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const HUGE_2MB = bitcast!(c::MAP_HUGE_2MB); - /// `MAP_HUGE_1GB` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const HUGE_1GB = bitcast!(c::MAP_HUGE_1GB); - /// `MAP_LOCKED` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const LOCKED = bitcast!(c::MAP_LOCKED); - /// `MAP_NOCORE` - #[cfg(freebsdlike)] - const NOCORE = bitcast!(c::MAP_NOCORE); - /// `MAP_NORESERVE` - #[cfg(not(any( - freebsdlike, - target_os = "aix", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const NORESERVE = bitcast!(c::MAP_NORESERVE); - /// `MAP_NOSYNC` - #[cfg(freebsdlike)] - const NOSYNC = bitcast!(c::MAP_NOSYNC); - /// `MAP_POPULATE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const POPULATE = bitcast!(c::MAP_POPULATE); - /// `MAP_STACK` - #[cfg(not(any( - apple, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "redox", - )))] - const STACK = bitcast!(c::MAP_STACK); - /// `MAP_PREFAULT_READ` - #[cfg(target_os = "freebsd")] - const PREFAULT_READ = bitcast!(c::MAP_PREFAULT_READ); - /// `MAP_SYNC` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - all( - linux_kernel, - any(target_arch = "mips", target_arch = "mips32r6", target_arch = "mips64", target_arch = "mips64r6"), - ), - )))] - const SYNC = bitcast!(c::MAP_SYNC); - /// `MAP_UNINITIALIZED` - #[cfg(any())] - const UNINITIALIZED = bitcast!(c::MAP_UNINITIALIZED); - /// `MAP_DROPPABLE` - #[cfg(linux_kernel)] - const DROPPABLE = bitcast!(c::MAP_DROPPABLE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -bitflags! { - /// `MREMAP_*` flags for use with [`mremap`]. - /// - /// For `MREMAP_FIXED`, see [`mremap_fixed`]. - /// - /// [`mremap`]: crate::mm::mremap - /// [`mremap_fixed`]: crate::mm::mremap_fixed - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MremapFlags: u32 { - /// `MREMAP_MAYMOVE` - const MAYMOVE = bitcast!(c::MREMAP_MAYMOVE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MS_*` flags for use with [`msync`]. - /// - /// [`msync`]: crate::mm::msync - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MsyncFlags: u32 { - /// `MS_SYNC`—Requests an update and waits for it to complete. - const SYNC = bitcast!(c::MS_SYNC); - /// `MS_ASYNC`—Specifies that an update be scheduled, but the call - /// returns immediately. - const ASYNC = bitcast!(c::MS_ASYNC); - /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same - /// file (so that they can be updated with the fresh values just - /// written). - const INVALIDATE = bitcast!(c::MS_INVALIDATE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `MLOCK_*` flags for use with [`mlock_with`]. - /// - /// [`mlock_with`]: crate::mm::mlock_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MlockFlags: u32 { - /// `MLOCK_ONFAULT` - const ONFAULT = bitcast!(c::MLOCK_ONFAULT); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `POSIX_MADV_*` constants for use with [`madvise`]. -/// -/// [`madvise`]: crate::mm::madvise -#[cfg(not(target_os = "redox"))] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -#[non_exhaustive] -pub enum Advice { - /// `POSIX_MADV_NORMAL` - #[cfg(not(any(target_os = "android", target_os = "haiku")))] - Normal = bitcast!(c::POSIX_MADV_NORMAL), - - /// `POSIX_MADV_NORMAL` - #[cfg(any(target_os = "android", target_os = "haiku"))] - Normal = bitcast!(c::MADV_NORMAL), - - /// `POSIX_MADV_SEQUENTIAL` - #[cfg(not(any(target_os = "android", target_os = "haiku")))] - Sequential = bitcast!(c::POSIX_MADV_SEQUENTIAL), - - /// `POSIX_MADV_SEQUENTIAL` - #[cfg(any(target_os = "android", target_os = "haiku"))] - Sequential = bitcast!(c::MADV_SEQUENTIAL), - - /// `POSIX_MADV_RANDOM` - #[cfg(not(any(target_os = "android", target_os = "haiku")))] - Random = bitcast!(c::POSIX_MADV_RANDOM), - - /// `POSIX_MADV_RANDOM` - #[cfg(any(target_os = "android", target_os = "haiku"))] - Random = bitcast!(c::MADV_RANDOM), - - /// `POSIX_MADV_WILLNEED` - #[cfg(not(any(target_os = "android", target_os = "haiku")))] - WillNeed = bitcast!(c::POSIX_MADV_WILLNEED), - - /// `POSIX_MADV_WILLNEED` - #[cfg(any(target_os = "android", target_os = "haiku"))] - WillNeed = bitcast!(c::MADV_WILLNEED), - - /// `POSIX_MADV_DONTNEED` - #[cfg(not(any( - target_os = "android", - target_os = "emscripten", - target_os = "haiku", - target_os = "hurd", - )))] - DontNeed = bitcast!(c::POSIX_MADV_DONTNEED), - - /// `POSIX_MADV_DONTNEED` - #[cfg(any(target_os = "android", target_os = "haiku"))] - DontNeed = bitcast!(i32::MAX - 1), - - /// `MADV_DONTNEED` - // `MADV_DONTNEED` has the same value as `POSIX_MADV_DONTNEED`. We don't - // have a separate `posix_madvise` from `madvise`, so we expose a special - // value which we special-case. - #[cfg(target_os = "linux")] - LinuxDontNeed = bitcast!(i32::MAX), - - /// `MADV_DONTNEED` - #[cfg(target_os = "android")] - LinuxDontNeed = bitcast!(c::MADV_DONTNEED), - /// `MADV_FREE` - #[cfg(linux_kernel)] - LinuxFree = bitcast!(c::MADV_FREE), - /// `MADV_REMOVE` - #[cfg(linux_kernel)] - LinuxRemove = bitcast!(c::MADV_REMOVE), - /// `MADV_DONTFORK` - #[cfg(linux_kernel)] - LinuxDontFork = bitcast!(c::MADV_DONTFORK), - /// `MADV_DOFORK` - #[cfg(linux_kernel)] - LinuxDoFork = bitcast!(c::MADV_DOFORK), - /// `MADV_HWPOISON` - #[cfg(linux_kernel)] - LinuxHwPoison = bitcast!(c::MADV_HWPOISON), - /// `MADV_SOFT_OFFLINE` - #[cfg(all( - linux_kernel, - not(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) - ))] - LinuxSoftOffline = bitcast!(c::MADV_SOFT_OFFLINE), - /// `MADV_MERGEABLE` - #[cfg(linux_kernel)] - LinuxMergeable = bitcast!(c::MADV_MERGEABLE), - /// `MADV_UNMERGEABLE` - #[cfg(linux_kernel)] - LinuxUnmergeable = bitcast!(c::MADV_UNMERGEABLE), - /// `MADV_HUGEPAGE` - #[cfg(linux_kernel)] - LinuxHugepage = bitcast!(c::MADV_HUGEPAGE), - /// `MADV_NOHUGEPAGE` - #[cfg(linux_kernel)] - LinuxNoHugepage = bitcast!(c::MADV_NOHUGEPAGE), - /// `MADV_DONTDUMP` (since Linux 3.4) - #[cfg(linux_kernel)] - LinuxDontDump = bitcast!(c::MADV_DONTDUMP), - /// `MADV_DODUMP` (since Linux 3.4) - #[cfg(linux_kernel)] - LinuxDoDump = bitcast!(c::MADV_DODUMP), - /// `MADV_WIPEONFORK` (since Linux 4.14) - #[cfg(linux_kernel)] - LinuxWipeOnFork = bitcast!(c::MADV_WIPEONFORK), - /// `MADV_KEEPONFORK` (since Linux 4.14) - #[cfg(linux_kernel)] - LinuxKeepOnFork = bitcast!(c::MADV_KEEPONFORK), - /// `MADV_COLD` (since Linux 5.4) - #[cfg(linux_kernel)] - LinuxCold = bitcast!(c::MADV_COLD), - /// `MADV_PAGEOUT` (since Linux 5.4) - #[cfg(linux_kernel)] - LinuxPageOut = bitcast!(c::MADV_PAGEOUT), - /// `MADV_POPULATE_READ` (since Linux 5.14) - #[cfg(linux_kernel)] - LinuxPopulateRead = bitcast!(c::MADV_POPULATE_READ), - /// `MADV_POPULATE_WRITE` (since Linux 5.14) - #[cfg(linux_kernel)] - LinuxPopulateWrite = bitcast!(c::MADV_POPULATE_WRITE), - /// `MADV_DONTNEED_LOCKED` (since Linux 5.18) - #[cfg(linux_kernel)] - LinuxDontneedLocked = bitcast!(c::MADV_DONTNEED_LOCKED), -} - -#[cfg(target_os = "emscripten")] -#[allow(non_upper_case_globals)] -impl Advice { - /// `POSIX_MADV_DONTNEED` - pub const DontNeed: Self = Self::Normal; -} - -#[cfg(linux_kernel)] -bitflags! { - /// `O_*` flags for use with [`userfaultfd`]. - /// - /// [`userfaultfd`]: crate::mm::userfaultfd - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UserfaultfdFlags: u32 { - /// `O_CLOEXEC` - const CLOEXEC = bitcast!(c::O_CLOEXEC); - /// `O_NONBLOCK` - const NONBLOCK = bitcast!(c::O_NONBLOCK); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -bitflags! { - /// `MCL_*` flags for use with [`mlockall`]. - /// - /// [`mlockall`]: crate::mm::mlockall - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MlockAllFlags: u32 { - /// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark all - /// current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`) mappings - /// to lock pages when they are faulted in. When used with - /// `MCL_CURRENT`, all present pages are locked, but `mlockall` will - /// not fault in non-present pages. When used with `MCL_FUTURE`, all - /// future mappings will be marked to lock pages when they are faulted - /// in, but they will not be populated by the lock when the mapping is - /// created. `MCL_ONFAULT` must be used with either `MCL_CURRENT` or - /// `MCL_FUTURE` or both. - #[cfg(linux_kernel)] - const ONFAULT = bitcast!(c::MCL_ONFAULT); - /// Lock all pages which will become mapped into the address space of - /// the process in the future. These could be, for instance, new pages - /// required by a growing heap and stack as well as new memory-mapped - /// files or shared memory regions. - const FUTURE = bitcast!(c::MCL_FUTURE); - /// Lock all pages which are currently mapped into the address space of - /// the process. - const CURRENT = bitcast!(c::MCL_CURRENT); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/mod.rs b/vendor/rustix/src/backend/libc/mod.rs deleted file mode 100644 index ca8afbb3..00000000 --- a/vendor/rustix/src/backend/libc/mod.rs +++ /dev/null @@ -1,220 +0,0 @@ -//! The libc backend. -//! -//! On most platforms, this uses the `libc` crate to make system calls. On -//! Windows, this uses the Winsock API in `windows-sys`, which can be adapted -//! to have a very `libc`-like interface. - -// Every FFI call requires an unsafe block, and there are a lot of FFI -// calls. For now, set this to allow for the libc backend. -#![allow(clippy::undocumented_unsafe_blocks)] -// Lots of libc types vary between platforms, so we often need a `.into()` on -// one platform where it's redundant on another. -#![allow(clippy::useless_conversion)] - -mod conv; - -#[cfg(windows)] -pub(crate) mod fd { - // Re-export `AsSocket` etc. too, as users can't implement `AsFd` etc. on - // Windows due to them having blanket impls on Windows, so users must - // implement `AsSocket` etc. - pub use crate::maybe_polyfill::os::windows::io::{ - AsRawSocket, AsSocket, BorrowedSocket as BorrowedFd, FromRawSocket, IntoRawSocket, - OwnedSocket as OwnedFd, RawSocket as RawFd, - }; - pub(crate) use windows_sys::Win32::Networking::WinSock::SOCKET as LibcFd; - - /// A version of [`AsRawFd`] for use with Winsock API. - /// - /// [`AsRawFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsRawFd.html - pub trait AsRawFd { - /// A version of [`as_raw_fd`] for use with Winsock API. - /// - /// [`as_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsRawFd.html#tymethod.as_raw_fd - fn as_raw_fd(&self) -> RawFd; - } - impl<T: AsRawSocket> AsRawFd for T { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.as_raw_socket() - } - } - - /// A version of [`IntoRawFd`] for use with Winsock API. - /// - /// [`IntoRawFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.IntoRawFd.html - pub trait IntoRawFd { - /// A version of [`into_raw_fd`] for use with Winsock API. - /// - /// [`into_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.IntoRawFd.html#tymethod.into_raw_fd - fn into_raw_fd(self) -> RawFd; - } - impl<T: IntoRawSocket> IntoRawFd for T { - #[inline] - fn into_raw_fd(self) -> RawFd { - self.into_raw_socket() - } - } - - /// A version of [`FromRawFd`] for use with Winsock API. - /// - /// [`FromRawFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html - pub trait FromRawFd { - /// A version of [`from_raw_fd`] for use with Winsock API. - /// - /// # Safety - /// - /// See the [safety requirements] for [`from_raw_fd`]. - /// - /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#tymethod.from_raw_fd - /// [safety requirements]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#safety - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self; - } - impl<T: FromRawSocket> FromRawFd for T { - #[inline] - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self::from_raw_socket(raw_fd) - } - } - - /// A version of [`AsFd`] for use with Winsock API. - /// - /// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsFd.html - pub trait AsFd { - /// An `as_fd` function for Winsock, where an `Fd` is a `Socket`. - fn as_fd(&self) -> BorrowedFd<'_>; - } - impl<T: AsSocket> AsFd for T { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_socket() - } - } -} -#[cfg(not(windows))] -pub(crate) mod fd { - pub use crate::maybe_polyfill::os::fd::*; - #[allow(unused_imports)] - pub(crate) use RawFd as LibcFd; -} - -// On Windows we emulate selected libc-compatible interfaces. On non-Windows, -// we just use libc here, since this is the libc backend. -#[cfg_attr(windows, path = "winsock_c.rs")] -pub(crate) mod c; - -#[cfg(feature = "event")] -pub(crate) mod event; -#[cfg(not(windows))] -#[cfg(feature = "fs")] -pub(crate) mod fs; -pub(crate) mod io; -#[cfg(linux_kernel)] -#[cfg(feature = "io_uring")] -pub(crate) mod io_uring; -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[cfg(feature = "mm")] -pub(crate) mod mm; -#[cfg(linux_kernel)] -#[cfg(feature = "mount")] -pub(crate) mod mount; -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "net")] -pub(crate) mod net; -#[cfg(not(any(windows, target_os = "espidf")))] -#[cfg(any( - feature = "param", - feature = "runtime", - feature = "time", - target_arch = "x86", -))] -pub(crate) mod param; -#[cfg(not(windows))] -#[cfg(feature = "pipe")] -pub(crate) mod pipe; -#[cfg(not(windows))] -#[cfg(feature = "process")] -pub(crate) mod process; -#[cfg(not(windows))] -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "pty")] -pub(crate) mod pty; -#[cfg(not(windows))] -#[cfg(feature = "rand")] -pub(crate) mod rand; -#[cfg(not(windows))] -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "system")] -pub(crate) mod system; -#[cfg(not(any(windows, target_os = "horizon", target_os = "vita")))] -#[cfg(feature = "termios")] -pub(crate) mod termios; -#[cfg(not(windows))] -#[cfg(feature = "thread")] -pub(crate) mod thread; -#[cfg(not(any(windows, target_os = "espidf")))] -#[cfg(feature = "time")] -pub(crate) mod time; - -/// If the host libc is glibc, return `true` if it is less than version 2.25. -/// -/// To restate and clarify, this function returning true does not mean the libc -/// is glibc just that if it is glibc, it is less than version 2.25. -/// -/// For now, this function is only available on Linux, but if it ends up being -/// used beyond that, this could be changed to e.g. `#[cfg(unix)]`. -#[cfg(all(unix, target_env = "gnu"))] -pub(crate) fn if_glibc_is_less_than_2_25() -> bool { - // This is also defined inside `weak_or_syscall!` in - // backend/libc/rand/syscalls.rs, but it's not convenient to re-export the - // weak symbol from that macro, so we duplicate it at a small cost here. - weak! { fn getrandom(*mut c::c_void, c::size_t, c::c_uint) -> c::ssize_t } - - // glibc 2.25 has `getrandom`, which is how we satisfy the API contract of - // this function. But, there are likely other libc versions which have it. - getrandom.get().is_none() -} - -// Private modules used by multiple public modules. -#[cfg(any(feature = "process", feature = "runtime"))] -#[cfg(not(any(windows, target_os = "wasi")))] -pub(crate) mod pid; -#[cfg(any(feature = "process", feature = "thread"))] -#[cfg(linux_kernel)] -pub(crate) mod prctl; -#[cfg(not(any( - windows, - target_os = "android", - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[cfg(feature = "shm")] -pub(crate) mod shm; -#[cfg(any(feature = "fs", feature = "thread", feature = "process"))] -#[cfg(not(any(windows, target_os = "wasi")))] -pub(crate) mod ugid; - -#[cfg(bsd)] -const MAX_IOV: usize = c::IOV_MAX as usize; - -#[cfg(any(linux_kernel, target_os = "emscripten", target_os = "nto"))] -const MAX_IOV: usize = c::UIO_MAXIOV as usize; - -#[cfg(not(any( - bsd, - linux_kernel, - windows, - target_os = "emscripten", - target_os = "espidf", - target_os = "nto", - target_os = "horizon", -)))] -const MAX_IOV: usize = 16; // The minimum value required by POSIX. diff --git a/vendor/rustix/src/backend/libc/mount/mod.rs b/vendor/rustix/src/backend/libc/mount/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/libc/mount/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/mount/syscalls.rs b/vendor/rustix/src/backend/libc/mount/syscalls.rs deleted file mode 100644 index c5414bca..00000000 --- a/vendor/rustix/src/backend/libc/mount/syscalls.rs +++ /dev/null @@ -1,268 +0,0 @@ -use crate::backend::c; -use crate::backend::conv::{borrowed_fd, c_str, ret, ret_owned_fd}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::ffi::CStr; -use crate::io; -use core::ptr::null; - -#[cfg(linux_kernel)] -pub(crate) fn mount( - source: Option<&CStr>, - target: &CStr, - file_system_type: Option<&CStr>, - flags: super::types::MountFlagsArg, - data: Option<&CStr>, -) -> io::Result<()> { - unsafe { - ret(c::mount( - source.map_or_else(null, CStr::as_ptr), - target.as_ptr(), - file_system_type.map_or_else(null, CStr::as_ptr), - flags.0, - data.map_or_else(null, CStr::as_ptr).cast(), - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn unmount(target: &CStr, flags: super::types::UnmountFlags) -> io::Result<()> { - unsafe { ret(c::umount2(target.as_ptr(), bitflags_bits!(flags))) } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsopen(fs_name: &CStr, flags: super::types::FsOpenFlags) -> io::Result<OwnedFd> { - syscall! { - fn fsopen( - fs_name: *const c::c_char, - flags: c::c_uint - ) via SYS_fsopen -> c::c_int - } - unsafe { ret_owned_fd(fsopen(c_str(fs_name), flags.bits())) } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsmount( - fs_fd: BorrowedFd<'_>, - flags: super::types::FsMountFlags, - attr_flags: super::types::MountAttrFlags, -) -> io::Result<OwnedFd> { - syscall! { - fn fsmount( - fs_fd: c::c_int, - flags: c::c_uint, - attr_flags: c::c_uint - ) via SYS_fsmount -> c::c_int - } - unsafe { ret_owned_fd(fsmount(borrowed_fd(fs_fd), flags.bits(), attr_flags.bits())) } -} - -#[cfg(linux_kernel)] -pub(crate) fn move_mount( - from_dfd: BorrowedFd<'_>, - from_pathname: &CStr, - to_dfd: BorrowedFd<'_>, - to_pathname: &CStr, - flags: super::types::MoveMountFlags, -) -> io::Result<()> { - syscall! { - fn move_mount( - from_dfd: c::c_int, - from_pathname: *const c::c_char, - to_dfd: c::c_int, - to_pathname: *const c::c_char, - flags: c::c_uint - ) via SYS_move_mount -> c::c_int - } - unsafe { - ret(move_mount( - borrowed_fd(from_dfd), - c_str(from_pathname), - borrowed_fd(to_dfd), - c_str(to_pathname), - flags.bits(), - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn open_tree( - dfd: BorrowedFd<'_>, - filename: &CStr, - flags: super::types::OpenTreeFlags, -) -> io::Result<OwnedFd> { - syscall! { - fn open_tree( - dfd: c::c_int, - filename: *const c::c_char, - flags: c::c_uint - ) via SYS_open_tree -> c::c_int - } - - unsafe { ret_owned_fd(open_tree(borrowed_fd(dfd), c_str(filename), flags.bits())) } -} - -#[cfg(linux_kernel)] -pub(crate) fn fspick( - dfd: BorrowedFd<'_>, - path: &CStr, - flags: super::types::FsPickFlags, -) -> io::Result<OwnedFd> { - syscall! { - fn fspick( - dfd: c::c_int, - path: *const c::c_char, - flags: c::c_uint - ) via SYS_fspick -> c::c_int - } - - unsafe { ret_owned_fd(fspick(borrowed_fd(dfd), c_str(path), flags.bits())) } -} - -#[cfg(linux_kernel)] -syscall! { - fn fsconfig( - fs_fd: c::c_int, - cmd: c::c_uint, - key: *const c::c_char, - val: *const c::c_char, - aux: c::c_int - ) via SYS_fsconfig -> c::c_int -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_set_flag(fs_fd: BorrowedFd<'_>, key: &CStr) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::SetFlag as _, - c_str(key), - null(), - 0, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_set_string( - fs_fd: BorrowedFd<'_>, - key: &CStr, - value: &CStr, -) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::SetString as _, - c_str(key), - c_str(value), - 0, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_set_binary( - fs_fd: BorrowedFd<'_>, - key: &CStr, - value: &[u8], -) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::SetBinary as _, - c_str(key), - value.as_ptr().cast(), - value.len().try_into().map_err(|_| io::Errno::OVERFLOW)?, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_set_fd( - fs_fd: BorrowedFd<'_>, - key: &CStr, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::SetFd as _, - c_str(key), - null(), - borrowed_fd(fd), - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_set_path( - fs_fd: BorrowedFd<'_>, - key: &CStr, - path: &CStr, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::SetPath as _, - c_str(key), - c_str(path), - borrowed_fd(fd), - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_set_path_empty( - fs_fd: BorrowedFd<'_>, - key: &CStr, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::SetPathEmpty as _, - c_str(key), - c_str(cstr!("")), - borrowed_fd(fd), - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_create(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::Create as _, - null(), - null(), - 0, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_reconfigure(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::Reconfigure as _, - null(), - null(), - 0, - )) - } -} - -#[cfg(linux_kernel)] -pub(crate) fn fsconfig_create_excl(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(fsconfig( - borrowed_fd(fs_fd), - super::types::FsConfigCmd::CreateExclusive as _, - null(), - null(), - 0, - )) - } -} diff --git a/vendor/rustix/src/backend/libc/mount/types.rs b/vendor/rustix/src/backend/libc/mount/types.rs deleted file mode 100644 index 9b88a753..00000000 --- a/vendor/rustix/src/backend/libc/mount/types.rs +++ /dev/null @@ -1,344 +0,0 @@ -use crate::backend::c; -use crate::ffi; -use bitflags::bitflags; - -#[cfg(linux_kernel)] -bitflags! { - /// `MS_*` constants for use with [`mount`]. - /// - /// [`mount`]: crate::mount::mount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MountFlags: ffi::c_ulong { - /// `MS_BIND` - const BIND = c::MS_BIND; - - /// `MS_DIRSYNC` - const DIRSYNC = c::MS_DIRSYNC; - - /// `MS_LAZYTIME` - const LAZYTIME = c::MS_LAZYTIME; - - /// `MS_MANDLOCK` - #[doc(alias = "MANDLOCK")] - const PERMIT_MANDATORY_FILE_LOCKING = c::MS_MANDLOCK; - - /// `MS_NOATIME` - const NOATIME = c::MS_NOATIME; - - /// `MS_NODEV` - const NODEV = c::MS_NODEV; - - /// `MS_NODIRATIME` - const NODIRATIME = c::MS_NODIRATIME; - - /// `MS_NOEXEC` - const NOEXEC = c::MS_NOEXEC; - - /// `MS_NOSUID` - const NOSUID = c::MS_NOSUID; - - /// `MS_RDONLY` - const RDONLY = c::MS_RDONLY; - - /// `MS_REC` - const REC = c::MS_REC; - - /// `MS_RELATIME` - const RELATIME = c::MS_RELATIME; - - /// `MS_SILENT` - const SILENT = c::MS_SILENT; - - /// `MS_STRICTATIME` - const STRICTATIME = c::MS_STRICTATIME; - - /// `MS_SYNCHRONOUS` - const SYNCHRONOUS = c::MS_SYNCHRONOUS; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `MNT_*` constants for use with [`unmount`]. - /// - /// [`unmount`]: crate::mount::unmount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UnmountFlags: u32 { - /// `MNT_FORCE` - const FORCE = bitcast!(c::MNT_FORCE); - /// `MNT_DETACH` - const DETACH = bitcast!(c::MNT_DETACH); - /// `MNT_EXPIRE` - const EXPIRE = bitcast!(c::MNT_EXPIRE); - /// `UMOUNT_NOFOLLOW` - const NOFOLLOW = bitcast!(c::UMOUNT_NOFOLLOW); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `FSOPEN_*` constants for use with [`fsopen`]. - /// - /// [`fsopen`]: crate::mount::fsopen - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FsOpenFlags: ffi::c_uint { - /// `FSOPEN_CLOEXEC` - const FSOPEN_CLOEXEC = 0x0000_0001; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `FSMOUNT_*` constants for use with [`fsmount`]. - /// - /// [`fsmount`]: crate::mount::fsmount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FsMountFlags: ffi::c_uint { - /// `FSMOUNT_CLOEXEC` - const FSMOUNT_CLOEXEC = 0x0000_0001; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `FSCONFIG_*` constants for use with the `fsconfig` syscall. -#[cfg(linux_kernel)] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub(crate) enum FsConfigCmd { - /// `FSCONFIG_SET_FLAG` - SetFlag = 0, - - /// `FSCONFIG_SET_STRING` - SetString = 1, - - /// `FSCONFIG_SET_BINARY` - SetBinary = 2, - - /// `FSCONFIG_SET_PATH` - SetPath = 3, - - /// `FSCONFIG_SET_PATH_EMPTY` - SetPathEmpty = 4, - - /// `FSCONFIG_SET_FD` - SetFd = 5, - - /// `FSCONFIG_CMD_CREATE` - Create = 6, - - /// `FSCONFIG_CMD_RECONFIGURE` - Reconfigure = 7, - - /// `FSCONFIG_CMD_CREATE_EXCL` (since Linux 6.6) - CreateExclusive = 8, -} - -#[cfg(linux_kernel)] -bitflags! { - /// `MOUNT_ATTR_*` constants for use with [`fsmount`]. - /// - /// [`fsmount`]: crate::mount::fsmount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MountAttrFlags: ffi::c_uint { - /// `MOUNT_ATTR_RDONLY` - const MOUNT_ATTR_RDONLY = 0x0000_0001; - - /// `MOUNT_ATTR_NOSUID` - const MOUNT_ATTR_NOSUID = 0x0000_0002; - - /// `MOUNT_ATTR_NODEV` - const MOUNT_ATTR_NODEV = 0x0000_0004; - - /// `MOUNT_ATTR_NOEXEC` - const MOUNT_ATTR_NOEXEC = 0x0000_0008; - - /// `MOUNT_ATTR__ATIME` - const MOUNT_ATTR__ATIME = 0x0000_0070; - - /// `MOUNT_ATTR_RELATIME` - const MOUNT_ATTR_RELATIME = 0x0000_0000; - - /// `MOUNT_ATTR_NOATIME` - const MOUNT_ATTR_NOATIME = 0x0000_0010; - - /// `MOUNT_ATTR_STRICTATIME` - const MOUNT_ATTR_STRICTATIME = 0x0000_0020; - - /// `MOUNT_ATTR_NODIRATIME` - const MOUNT_ATTR_NODIRATIME = 0x0000_0080; - - /// `MOUNT_ATTR_NOUSER` - const MOUNT_ATTR_IDMAP = 0x0010_0000; - - /// `MOUNT_ATTR__ATIME_FLAGS` - const MOUNT_ATTR_NOSYMFOLLOW = 0x0020_0000; - - /// `MOUNT_ATTR__ATIME_FLAGS` - const MOUNT_ATTR_SIZE_VER0 = 32; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `MOVE_MOUNT_*` constants for use with [`move_mount`]. - /// - /// [`move_mount`]: crate::mount::move_mount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MoveMountFlags: ffi::c_uint { - /// `MOVE_MOUNT_F_EMPTY_PATH` - const MOVE_MOUNT_F_SYMLINKS = 0x0000_0001; - - /// `MOVE_MOUNT_F_AUTOMOUNTS` - const MOVE_MOUNT_F_AUTOMOUNTS = 0x0000_0002; - - /// `MOVE_MOUNT_F_EMPTY_PATH` - const MOVE_MOUNT_F_EMPTY_PATH = 0x0000_0004; - - /// `MOVE_MOUNT_T_SYMLINKS` - const MOVE_MOUNT_T_SYMLINKS = 0x0000_0010; - - /// `MOVE_MOUNT_T_AUTOMOUNTS` - const MOVE_MOUNT_T_AUTOMOUNTS = 0x0000_0020; - - /// `MOVE_MOUNT_T_EMPTY_PATH` - const MOVE_MOUNT_T_EMPTY_PATH = 0x0000_0040; - - /// `MOVE_MOUNT__MASK` - const MOVE_MOUNT_SET_GROUP = 0x0000_0100; - - /// `MOVE_MOUNT_BENEATH` (since Linux 6.5) - const MOVE_MOUNT_BENEATH = 0x0000_0200; - - /// `MOVE_MOUNT__MASK` - const MOVE_MOUNT__MASK = 0x0000_0377; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `OPENTREE_*` constants for use with [`open_tree`]. - /// - /// [`open_tree`]: crate::mount::open_tree - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct OpenTreeFlags: ffi::c_uint { - /// `OPENTREE_CLONE` - const OPEN_TREE_CLONE = 1; - - /// `OPENTREE_CLOEXEC` - const OPEN_TREE_CLOEXEC = c::O_CLOEXEC as c::c_uint; - - /// `AT_EMPTY_PATH` - const AT_EMPTY_PATH = c::AT_EMPTY_PATH as c::c_uint; - - /// `AT_NO_AUTOMOUNT` - const AT_NO_AUTOMOUNT = c::AT_NO_AUTOMOUNT as c::c_uint; - - /// `AT_RECURSIVE` - const AT_RECURSIVE = c::AT_RECURSIVE as c::c_uint; - - /// `AT_SYMLINK_NOFOLLOW` - const AT_SYMLINK_NOFOLLOW = c::AT_SYMLINK_NOFOLLOW as c::c_uint; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `FSPICK_*` constants for use with [`fspick`]. - /// - /// [`fspick`]: crate::mount::fspick - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FsPickFlags: ffi::c_uint { - /// `FSPICK_CLOEXEC` - const FSPICK_CLOEXEC = 0x0000_0001; - - /// `FSPICK_SYMLINK_NOFOLLOW` - const FSPICK_SYMLINK_NOFOLLOW = 0x0000_0002; - - /// `FSPICK_NO_AUTOMOUNT` - const FSPICK_NO_AUTOMOUNT = 0x0000_0004; - - /// `FSPICK_EMPTY_PATH` - const FSPICK_EMPTY_PATH = 0x0000_0008; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `MS_*` constants for use with [`mount_change`]. - /// - /// [`mount_change`]: crate::mount::mount_change - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MountPropagationFlags: ffi::c_ulong { - /// `MS_SILENT` - const SILENT = c::MS_SILENT; - /// `MS_SHARED` - const SHARED = c::MS_SHARED; - /// `MS_PRIVATE` - const PRIVATE = c::MS_PRIVATE; - /// Mark a mount as a downstream of its current peer group. - /// - /// Mount and unmount events propagate from the upstream peer group - /// into the downstream. - /// - /// In Linux documentation, this flag is named `MS_SLAVE`, and the - /// concepts of “upstream” and “downstream” are called - /// “master” and “slave”. - #[doc(alias = "SLAVE")] - const DOWNSTREAM = c::MS_SLAVE; - /// `MS_UNBINDABLE` - const UNBINDABLE = c::MS_UNBINDABLE; - /// `MS_REC` - const REC = c::MS_REC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub(crate) struct InternalMountFlags: c::c_ulong { - const REMOUNT = c::MS_REMOUNT; - const MOVE = c::MS_MOVE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -pub(crate) struct MountFlagsArg(pub(crate) c::c_ulong); diff --git a/vendor/rustix/src/backend/libc/net/addr.rs b/vendor/rustix/src/backend/libc/net/addr.rs deleted file mode 100644 index 1699ffa9..00000000 --- a/vendor/rustix/src/backend/libc/net/addr.rs +++ /dev/null @@ -1,390 +0,0 @@ -//! Socket address utilities. - -use crate::backend::c; -use crate::net::AddressFamily; -#[cfg(unix)] -use { - crate::ffi::CStr, - crate::io, - crate::net::addr::SocketAddrLen, - crate::path, - core::cmp::Ordering, - core::fmt, - core::hash::{Hash, Hasher}, - core::slice, -}; -#[cfg(all(unix, feature = "alloc"))] -use {crate::ffi::CString, alloc::borrow::Cow, alloc::vec::Vec}; - -/// `struct sockaddr_un` -#[cfg(unix)] -#[derive(Clone)] -#[doc(alias = "sockaddr_un")] -pub struct SocketAddrUnix { - pub(crate) unix: c::sockaddr_un, - #[cfg(not(any(bsd, target_os = "haiku")))] - len: c::socklen_t, -} - -#[cfg(unix)] -impl SocketAddrUnix { - /// Construct a new Unix-domain address from a filesystem path. - #[inline] - pub fn new<P: path::Arg>(path: P) -> io::Result<Self> { - path.into_with_c_str(Self::_new) - } - - #[inline] - fn _new(path: &CStr) -> io::Result<Self> { - let mut unix = Self::init(); - let mut bytes = path.to_bytes_with_nul(); - if bytes.len() > unix.sun_path.len() { - bytes = path.to_bytes(); // without NUL - if bytes.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - } - for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = *b as c::c_char; - } - - #[cfg(any(bsd, target_os = "haiku"))] - { - unix.sun_len = (offsetof_sun_path() + bytes.len()).try_into().unwrap(); - } - - Ok(Self { - unix, - #[cfg(not(any(bsd, target_os = "haiku")))] - len: (offsetof_sun_path() + bytes.len()).try_into().unwrap(), - }) - } - - /// Construct a new abstract Unix-domain address from a byte slice. - #[cfg(linux_kernel)] - #[inline] - pub fn new_abstract_name(name: &[u8]) -> io::Result<Self> { - let mut unix = Self::init(); - if 1 + name.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - unix.sun_path[0] = 0; - for (i, b) in name.iter().enumerate() { - unix.sun_path[1 + i] = *b as c::c_char; - } - let len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { - unix, - #[cfg(not(any(bsd, target_os = "haiku")))] - len, - }) - } - - /// Construct a new unnamed address. - /// - /// The kernel will assign an abstract Unix-domain address to the socket - /// when you call [`bind`][crate::net::bind]. You can inspect the assigned - /// name with [`getsockname`][crate::net::getsockname]. - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://www.man7.org/linux/man-pages/man7/unix.7.html - #[cfg(linux_kernel)] - #[inline] - pub fn new_unnamed() -> Self { - Self { - unix: Self::init(), - #[cfg(not(any(bsd, target_os = "haiku")))] - len: offsetof_sun_path() as c::socklen_t, - } - } - - const fn init() -> c::sockaddr_un { - c::sockaddr_un { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "hurd", - ))] - sun_len: 0, - #[cfg(target_os = "vita")] - ss_len: 0, - sun_family: c::AF_UNIX as _, - #[cfg(any(bsd, target_os = "horizon", target_os = "nto"))] - sun_path: [0; 104], - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "nto" - )))] - sun_path: [0; 108], - #[cfg(target_os = "haiku")] - sun_path: [0; 126], - #[cfg(target_os = "aix")] - sun_path: [0; 1023], - } - } - - /// For a filesystem path address, return the path. - #[inline] - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - pub fn path(&self) -> Option<Cow<'_, CStr>> { - let bytes = self.bytes()?; - if !bytes.is_empty() && bytes[0] != 0 { - if self.unix.sun_path.len() == bytes.len() { - // SAFETY: There are no NULs contained in bytes. - unsafe { Self::path_with_termination(bytes) } - } else { - // SAFETY: `from_bytes_with_nul_unchecked` since the string is - // NUL-terminated. - Some(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }.into()) - } - } else { - None - } - } - - /// If the `sun_path` field is not NUL-terminated, terminate it. - /// - /// SAFETY: The input `bytes` must not contain any NULs. - #[cfg(feature = "alloc")] - #[cold] - unsafe fn path_with_termination(bytes: &[u8]) -> Option<Cow<'_, CStr>> { - let mut owned = Vec::with_capacity(bytes.len() + 1); - owned.extend_from_slice(bytes); - owned.push(b'\0'); - // SAFETY: `from_vec_with_nul_unchecked` since the string is - // NUL-terminated and `bytes` does not contain any NULs. - Some(Cow::Owned( - CString::from_vec_with_nul_unchecked(owned).into(), - )) - } - - /// For a filesystem path address, return the path as a byte sequence, - /// excluding the NUL terminator. - #[inline] - pub fn path_bytes(&self) -> Option<&[u8]> { - let bytes = self.bytes()?; - if !bytes.is_empty() && bytes[0] != 0 { - if self.unix.sun_path.len() == self.len() - offsetof_sun_path() { - // There is no NUL terminator. - Some(bytes) - } else { - // Remove the NUL terminator. - Some(&bytes[..bytes.len() - 1]) - } - } else { - None - } - } - - /// For an abstract address, return the identifier. - #[cfg(linux_kernel)] - #[inline] - pub fn abstract_name(&self) -> Option<&[u8]> { - if let [0, bytes @ ..] = self.bytes()? { - Some(bytes) - } else { - None - } - } - - /// `true` if the socket address is unnamed. - #[cfg(linux_kernel)] - #[inline] - pub fn is_unnamed(&self) -> bool { - self.bytes() == Some(&[]) - } - - #[inline] - pub(crate) fn addr_len(&self) -> SocketAddrLen { - #[cfg(not(any(bsd, target_os = "haiku")))] - { - bitcast!(self.len) - } - #[cfg(any(bsd, target_os = "haiku"))] - { - bitcast!(c::socklen_t::from(self.unix.sun_len)) - } - } - - #[inline] - pub(crate) fn len(&self) -> usize { - self.addr_len() as usize - } - - #[inline] - fn bytes(&self) -> Option<&[u8]> { - let len = self.len(); - if len != 0 { - let bytes = &self.unix.sun_path[..len - offsetof_sun_path()]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. - Some(unsafe { slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len()) }) - } else { - None - } - } -} - -#[cfg(unix)] -impl PartialEq for SocketAddrUnix { - #[inline] - fn eq(&self, other: &Self) -> bool { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) - } -} - -#[cfg(unix)] -impl Eq for SocketAddrUnix {} - -#[cfg(unix)] -impl PartialOrd for SocketAddrUnix { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -#[cfg(unix)] -impl Ord for SocketAddrUnix { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].cmp(&other.unix.sun_path[..other_len]) - } -} - -#[cfg(unix)] -impl Hash for SocketAddrUnix { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - let self_len = self.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].hash(state) - } -} - -#[cfg(unix)] -impl fmt::Debug for SocketAddrUnix { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "alloc")] - if let Some(path) = self.path() { - return path.fmt(f); - } - if let Some(bytes) = self.path_bytes() { - if let Ok(s) = core::str::from_utf8(bytes) { - return s.fmt(f); - } - return bytes.fmt(f); - } - #[cfg(linux_kernel)] - if let Some(name) = self.abstract_name() { - return name.fmt(f); - } - "(unnamed)".fmt(f) - } -} - -/// `struct sockaddr_storage` -/// -/// This type is guaranteed to be large enough to hold any encoded socket -/// address. -#[repr(transparent)] -#[derive(Copy, Clone)] -#[doc(alias = "sockaddr_storage")] -pub struct SocketAddrStorage(c::sockaddr_storage); - -impl SocketAddrStorage { - /// Return a socket addr storage initialized to all zero bytes. The - /// `sa_family` is set to [`AddressFamily::UNSPEC`]. - pub fn zeroed() -> Self { - assert_eq!(c::AF_UNSPEC, 0); - // SAFETY: `sockaddr_storage` is meant to be zero-initializable. - unsafe { core::mem::zeroed() } - } - - /// Return the `sa_family` of this socket address. - pub fn family(&self) -> AddressFamily { - // SAFETY: `self.0` is a `sockaddr_storage` so it has enough space. - unsafe { - AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family( - crate::utils::as_ptr(&self.0).cast::<c::sockaddr>(), - )) - } - } - - /// Clear the `sa_family` of this socket address to - /// [`AddressFamily::UNSPEC`]. - pub fn clear_family(&mut self) { - // SAFETY: `self.0` is a `sockaddr_storage` so it has enough space. - unsafe { - crate::backend::net::read_sockaddr::initialize_family_to_unspec( - crate::utils::as_mut_ptr(&mut self.0).cast::<c::sockaddr>(), - ) - } - } -} - -/// Return the offset of the `sun_path` field of `sockaddr_un`. -#[cfg(not(windows))] -#[inline] -pub(crate) fn offsetof_sun_path() -> usize { - let z = c::sockaddr_un { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - ))] - sun_len: 0_u8, - #[cfg(target_os = "vita")] - ss_len: 0, - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sun_family: 0_u8, - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - )))] - sun_family: 0_u16, - #[cfg(any(bsd, target_os = "horizon", target_os = "nto"))] - sun_path: [0; 104], - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "horizon", - target_os = "nto" - )))] - sun_path: [0; 108], - #[cfg(target_os = "haiku")] - sun_path: [0; 126], - #[cfg(target_os = "aix")] - sun_path: [0; 1023], - }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) -} diff --git a/vendor/rustix/src/backend/libc/net/ext.rs b/vendor/rustix/src/backend/libc/net/ext.rs deleted file mode 100644 index efd2b31c..00000000 --- a/vendor/rustix/src/backend/libc/net/ext.rs +++ /dev/null @@ -1,137 +0,0 @@ -use crate::backend::c; - -/// The windows `sockaddr_in6` type is a union with accessor functions which -/// are not `const fn`. Define our own layout-compatible version so that we -/// can transmute in and out of it. -#[cfg(windows)] -#[repr(C)] -struct sockaddr_in6 { - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - addr.s_addr -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. - unsafe { core::mem::transmute(addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - c::in_addr { s_addr } -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - unsafe { core::mem::transmute(s_addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - addr.s6_addr -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - unsafe { core::mem::transmute(addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - c::in6_addr { s6_addr } -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - unsafe { core::mem::transmute(s6_addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 { - addr.sin6_scope_id -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 { - let addr: &sockaddr_in6 = unsafe { core::mem::transmute(addr) }; - addr.sin6_scope_id -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn sockaddr_in6_new( - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sin6_len: u8, - sin6_family: c::sa_family_t, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - c::sockaddr_in6 { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sin6_len, - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - #[cfg(solarish)] - __sin6_src_id: 0, - #[cfg(target_os = "vita")] - sin6_vport: 0, - } -} - -#[cfg(windows)] -#[inline] -pub(crate) const fn sockaddr_in6_new( - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - let addr = sockaddr_in6 { - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - }; - unsafe { core::mem::transmute(addr) } -} diff --git a/vendor/rustix/src/backend/libc/net/mod.rs b/vendor/rustix/src/backend/libc/net/mod.rs deleted file mode 100644 index da7e1df8..00000000 --- a/vendor/rustix/src/backend/libc/net/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -pub(crate) mod addr; -pub(crate) mod ext; -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) mod msghdr; -#[cfg(linux_kernel)] -pub(crate) mod netdevice; -pub(crate) mod read_sockaddr; -pub(crate) mod send_recv; -pub(crate) mod sockopt; -pub(crate) mod syscalls; -pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/libc/net/msghdr.rs b/vendor/rustix/src/backend/libc/net/msghdr.rs deleted file mode 100644 index fe5471b9..00000000 --- a/vendor/rustix/src/backend/libc/net/msghdr.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! Utilities for dealing with message headers. -//! -//! These take closures rather than returning a `c::msghdr` directly because -//! the message headers may reference stack-local data. - -use crate::backend::c; - -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::addr::SocketAddrArg; -use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrBuf}; - -use core::mem::zeroed; - -/// Convert the value to the `msg_iovlen` field of a `msghdr` struct. -#[cfg(all( - not(any(windows, target_os = "espidf", target_os = "wasi")), - any( - target_os = "android", - all( - target_os = "linux", - not(target_env = "musl"), - not(all(target_env = "uclibc", any(target_arch = "arm", target_arch = "mips"))) - ) - ) -))] -#[inline] -fn msg_iov_len(len: usize) -> c::size_t { - len -} - -/// Convert the value to the `msg_iovlen` field of a `msghdr` struct. -#[cfg(all( - not(any( - windows, - target_os = "espidf", - target_os = "redox", - target_os = "vita", - target_os = "wasi" - )), - not(any( - target_os = "android", - all( - target_os = "linux", - not(target_env = "musl"), - not(all(target_env = "uclibc", any(target_arch = "arm", target_arch = "mips"))) - ) - )) -))] -#[inline] -fn msg_iov_len(len: usize) -> c::c_int { - len.try_into().unwrap_or(c::c_int::MAX) -} - -/// Convert the value to a `socklen_t`. -#[cfg(any( - bsd, - solarish, - target_env = "musl", - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", -))] -#[inline] -fn msg_control_len(len: usize) -> c::socklen_t { - len.try_into().unwrap_or(c::socklen_t::MAX) -} - -/// Convert the value to a `size_t`. -#[cfg(not(any( - bsd, - solarish, - windows, - target_env = "musl", - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -fn msg_control_len(len: usize) -> c::size_t { - len -} - -/// Create a message header intended to receive a datagram. -/// -/// # Safety -/// -/// If `f` dereferences the pointers in the `msghdr`, it must do so only within -/// the bounds indicated by the associated lengths in the `msghdr`. -/// -/// And, if `f` returns `Ok`, it must have updated the `msg_controllen` field -/// of the `msghdr` to indicate how many bytes it initialized. -pub(crate) unsafe fn with_recv_msghdr<R>( - name: &mut SocketAddrBuf, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - f: impl FnOnce(&mut c::msghdr) -> io::Result<R>, -) -> io::Result<R> { - control.clear(); - - let mut msghdr = zero_msghdr(); - msghdr.msg_name = name.storage.as_mut_ptr().cast(); - msghdr.msg_namelen = name.len; - msghdr.msg_iov = iov.as_mut_ptr().cast(); - msghdr.msg_iovlen = msg_iov_len(iov.len()); - msghdr.msg_control = control.as_control_ptr().cast(); - msghdr.msg_controllen = msg_control_len(control.control_len()); - - let res = f(&mut msghdr); - - // Reset the control length. - if res.is_ok() { - // SAFETY: `f` returned `Ok`, so our safety condition requires `f` to - // have initialized `msg_controllen` bytes. - control.set_control_len(msghdr.msg_controllen as usize); - } - - name.len = msghdr.msg_namelen; - - res -} - -/// Create a message header intended to send without an address. -/// -/// The returned `msghdr` will contain raw pointers to the memory -/// referenced by `iov` and `control`. -pub(crate) fn noaddr_msghdr( - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, -) -> c::msghdr { - let mut h = zero_msghdr(); - h.msg_iov = iov.as_ptr() as _; - h.msg_iovlen = msg_iov_len(iov.len()); - h.msg_control = control.as_control_ptr().cast(); - h.msg_controllen = msg_control_len(control.control_len()); - h -} - -/// Create a message header intended to send with the specified address. -/// -/// This creates a `c::msghdr` and calls a function `f` on it. The `msghdr`'s -/// raw pointers may point to temporaries, so this function should avoid -/// storing the pointers anywhere that would outlive the function call. -/// -/// # Safety -/// -/// If `f` dereferences the pointers in the `msghdr`, it must do so only within -/// the bounds indicated by the associated lengths in the `msghdr`. -pub(crate) unsafe fn with_msghdr<R>( - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(&c::msghdr) -> R, -) -> R { - addr.with_sockaddr(|addr_ptr, addr_len| { - let mut h = zero_msghdr(); - h.msg_name = addr_ptr as *mut _; - h.msg_namelen = bitcast!(addr_len); - h.msg_iov = iov.as_ptr() as _; - h.msg_iovlen = msg_iov_len(iov.len()); - h.msg_control = control.as_control_ptr().cast(); - h.msg_controllen = msg_control_len(control.control_len()); - // Pass a reference to the `c::msghdr` instead of passing it by value - // because it may contain pointers to temporary objects that won't - // live beyond the call to `with_sockaddr`. - f(&h) - }) -} - -/// Create a zero-initialized message header struct value. -#[cfg(all(unix, not(target_os = "redox")))] -pub(crate) fn zero_msghdr() -> c::msghdr { - // SAFETY: We can't initialize all the fields by value because on some - // platforms the `msghdr` struct in the libc crate contains private padding - // fields. But it is still a C type that's meant to be zero-initializable. - unsafe { zeroed() } -} diff --git a/vendor/rustix/src/backend/libc/net/netdevice.rs b/vendor/rustix/src/backend/libc/net/netdevice.rs deleted file mode 100644 index 887f768d..00000000 --- a/vendor/rustix/src/backend/libc/net/netdevice.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! Wrappers for netdevice ioctls. - -#![allow(unsafe_code)] - -#[cfg(feature = "alloc")] -use crate::alloc::string::String; -use crate::backend::c; -use crate::backend::io::syscalls::ioctl; -use crate::fd::BorrowedFd; -use crate::io; -#[cfg(feature = "alloc")] -use c::SIOCGIFNAME; -use c::{__c_anonymous_ifr_ifru, c_char, ifreq, IFNAMSIZ, SIOCGIFINDEX}; - -pub(crate) fn name_to_index(fd: BorrowedFd<'_>, if_name: &str) -> io::Result<u32> { - let if_name_bytes = if_name.as_bytes(); - if if_name_bytes.len() >= IFNAMSIZ as usize { - return Err(io::Errno::NODEV); - } - - let mut ifreq = ifreq { - ifr_name: [0; 16], - ifr_ifru: __c_anonymous_ifr_ifru { ifru_ifindex: 0 }, - }; - - let mut if_name_c_char_iter = if_name_bytes.iter().map(|byte| *byte as c_char); - ifreq.ifr_name[..if_name_bytes.len()].fill_with(|| if_name_c_char_iter.next().unwrap()); - - unsafe { ioctl(fd, SIOCGIFINDEX as _, &mut ifreq as *mut ifreq as _) }?; - let index = unsafe { ifreq.ifr_ifru.ifru_ifindex }; - Ok(index as u32) -} - -#[cfg(feature = "alloc")] -pub(crate) fn index_to_name(fd: BorrowedFd<'_>, index: u32) -> io::Result<String> { - let mut ifreq = ifreq { - ifr_name: [0; 16], - ifr_ifru: __c_anonymous_ifr_ifru { - ifru_ifindex: index as _, - }, - }; - - unsafe { ioctl(fd, SIOCGIFNAME as _, &mut ifreq as *mut ifreq as _) }?; - - if let Some(nul_byte) = ifreq.ifr_name.iter().position(|char| *char == 0) { - let name: String = ifreq.ifr_name[..nul_byte] - .iter() - .map(|v| *v as u8 as char) - .collect(); - - Ok(name) - } else { - Err(io::Errno::INVAL) - } -} diff --git a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs deleted file mode 100644 index 5f8c48ec..00000000 --- a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs +++ /dev/null @@ -1,264 +0,0 @@ -//! The BSD sockets API requires us to read the `sa_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. - -#[cfg(unix)] -use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_sin6_scope_id}; -use crate::backend::c; -#[cfg(not(windows))] -use crate::ffi::CStr; -use crate::io::Errno; -use crate::net::addr::SocketAddrLen; -#[cfg(linux_kernel)] -use crate::net::netlink::SocketAddrNetlink; -#[cfg(target_os = "linux")] -use crate::net::xdp::{SocketAddrXdp, SocketAddrXdpFlags}; -use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; -use core::mem::size_of; - -// This must match the header of `sockaddr`. -#[repr(C)] -pub(crate) struct sockaddr_header { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - ))] - sa_len: u8, - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - ))] - sa_family: u8, - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "vita" - )))] - sa_family: u16, -} - -/// Read the `sa_family` field from a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -#[inline] -pub(crate) unsafe fn read_sa_family(storage: *const c::sockaddr) -> u16 { - // Assert that we know the layout of `sockaddr`. - let _ = c::sockaddr { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sa_len: 0_u8, - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - sa_family: 0_u8, - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - )))] - sa_family: 0_u16, - #[cfg(not(any(target_os = "haiku", target_os = "horizon")))] - sa_data: [0; 14], - #[cfg(target_os = "horizon")] - sa_data: [0; 26], - #[cfg(target_os = "haiku")] - sa_data: [0; 30], - }; - - (*storage.cast::<sockaddr_header>()).sa_family.into() -} - -/// Read the first byte of the `sun_path` field, assuming we have an `AF_UNIX` -/// socket address. -#[cfg(apple)] -#[inline] -unsafe fn read_sun_path0(storage: *const c::sockaddr) -> u8 { - // In `read_sa_family` we assert that we know the layout of `sockaddr`. - storage - .cast::<u8>() - .add(super::addr::offsetof_sun_path()) - .read() -} - -/// Check if a socket address returned from the OS is considered non-empty. -/// -/// # Safety -/// -/// `storage` must point to a least an initialized `sockaddr_header`. -#[inline] -pub(crate) unsafe fn sockaddr_nonempty(storage: *const c::sockaddr, len: SocketAddrLen) -> bool { - if len == 0 { - return false; - } - - assert!(len as usize >= size_of::<c::sa_family_t>()); - let family: c::c_int = read_sa_family(storage.cast::<c::sockaddr>()).into(); - if family == c::AF_UNSPEC { - return false; - } - - // On macOS, if we get an `AF_UNIX` with an empty path, treat it as an - // absent address. - #[cfg(apple)] - if family == c::AF_UNIX && read_sun_path0(storage) == 0 { - return false; - } - - true -} - -/// Set the `sa_family` field of a socket address to `AF_UNSPEC`, so that we -/// can test for `AF_UNSPEC` to test whether it was stored to. -/// -/// # Safety -/// -/// `storage` must point to a least an initialized `sockaddr_header`. -pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) { - (*storage.cast::<sockaddr_header>()).sa_family = c::AF_UNSPEC as _; -} - -#[inline] -pub(crate) fn read_sockaddr_v4(addr: &SocketAddrAny) -> Result<SocketAddrV4, Errno> { - if addr.address_family() != AddressFamily::INET { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_in>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in>() }; - Ok(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), - u16::from_be(decode.sin_port), - )) -} - -#[inline] -pub(crate) fn read_sockaddr_v6(addr: &SocketAddrAny) -> Result<SocketAddrV6, Errno> { - if addr.address_family() != AddressFamily::INET6 { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_in6>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in6>() }; - Ok(SocketAddrV6::new( - Ipv6Addr::from(in6_addr_s6_addr(decode.sin6_addr)), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - sockaddr_in6_sin6_scope_id(decode), - )) -} - -#[cfg(unix)] -#[inline] -pub(crate) fn read_sockaddr_unix(addr: &SocketAddrAny) -> Result<SocketAddrUnix, Errno> { - if addr.address_family() != AddressFamily::UNIX { - return Err(Errno::AFNOSUPPORT); - } - - let offsetof_sun_path = super::addr::offsetof_sun_path(); - let len = addr.addr_len() as usize; - - assert!(len >= offsetof_sun_path); - - if len == offsetof_sun_path { - SocketAddrUnix::new(&[][..]) - } else { - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_un>() }; - - // On Linux check for Linux's [abstract namespace]. - // - // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html - #[cfg(linux_kernel)] - if decode.sun_path[0] == 0 { - let name = &decode.sun_path[1..len - offsetof_sun_path]; - let name = unsafe { core::mem::transmute::<&[c::c_char], &[u8]>(name) }; - return SocketAddrUnix::new_abstract_name(name); - } - - // Otherwise we expect a NUL-terminated filesystem path. - - // Trim off unused bytes from the end of `path_bytes`. - let path_bytes = if cfg!(any(solarish, target_os = "freebsd")) { - // FreeBSD and illumos sometimes set the length to longer - // than the length of the NUL-terminated string. Find the - // NUL and truncate the string accordingly. - &decode.sun_path[..decode - .sun_path - .iter() - .position(|b| *b == 0) - .ok_or(Errno::INVAL)?] - } else { - // Otherwise, use the provided length. - let provided_len = len - 1 - offsetof_sun_path; - if decode.sun_path[provided_len] != 0 { - return Err(Errno::INVAL); - } - debug_assert_eq!( - unsafe { CStr::from_ptr(decode.sun_path.as_ptr().cast()) } - .to_bytes() - .len(), - provided_len - ); - &decode.sun_path[..provided_len] - }; - - SocketAddrUnix::new(unsafe { core::mem::transmute::<&[c::c_char], &[u8]>(path_bytes) }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result<SocketAddrXdp, Errno> { - if addr.address_family() != AddressFamily::XDP { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_xdp>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_xdp>() }; - - // This ignores the `sxdp_shared_umem_fd` field, which is only expected to - // be significant in `bind` calls, and not returned from `acceptfrom` or - // `recvmsg` or similar. - Ok(SocketAddrXdp::new( - SocketAddrXdpFlags::from_bits_retain(decode.sxdp_flags), - u32::from_be(decode.sxdp_ifindex), - u32::from_be(decode.sxdp_queue_id), - )) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn read_sockaddr_netlink(addr: &SocketAddrAny) -> Result<SocketAddrNetlink, Errno> { - if addr.address_family() != AddressFamily::NETLINK { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_nl>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_nl>() }; - Ok(SocketAddrNetlink::new(decode.nl_pid, decode.nl_groups)) -} diff --git a/vendor/rustix/src/backend/libc/net/send_recv.rs b/vendor/rustix/src/backend/libc/net/send_recv.rs deleted file mode 100644 index 4b67f2c5..00000000 --- a/vendor/rustix/src/backend/libc/net/send_recv.rs +++ /dev/null @@ -1,153 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `MSG_*` flags for use with [`send`], [`sendto`], and related - /// functions. - /// - /// [`send`]: crate::net::send - /// [`sendto`]: crate::net::sendto - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SendFlags: u32 { - /// `MSG_CONFIRM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "nto", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - )))] - const CONFIRM = bitcast!(c::MSG_CONFIRM); - /// `MSG_DONTROUTE` - const DONTROUTE = bitcast!(c::MSG_DONTROUTE); - /// `MSG_DONTWAIT` - #[cfg(not(windows))] - const DONTWAIT = bitcast!(c::MSG_DONTWAIT); - /// `MSG_EOR` - #[cfg(not(any(windows, target_os = "horizon")))] - const EOR = bitcast!(c::MSG_EOR); - /// `MSG_MORE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - const MORE = bitcast!(c::MSG_MORE); - #[cfg(not(any(apple, windows, target_os = "redox", target_os = "vita")))] - /// `MSG_NOSIGNAL` - const NOSIGNAL = bitcast!(c::MSG_NOSIGNAL); - /// `MSG_OOB` - const OOB = bitcast!(c::MSG_OOB); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MSG_*` flags for use with [`recv`], [`recvfrom`], and related - /// functions. - /// - /// [`recv`]: crate::net::recv - /// [`recvfrom`]: crate::net::recvfrom - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RecvFlags: u32 { - /// `MSG_CMSG_CLOEXEC` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - const CMSG_CLOEXEC = bitcast!(c::MSG_CMSG_CLOEXEC); - /// `MSG_DONTWAIT` - #[cfg(not(windows))] - const DONTWAIT = bitcast!(c::MSG_DONTWAIT); - /// `MSG_ERRQUEUE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - const ERRQUEUE = bitcast!(c::MSG_ERRQUEUE); - /// `MSG_OOB` - const OOB = bitcast!(c::MSG_OOB); - /// `MSG_PEEK` - const PEEK = bitcast!(c::MSG_PEEK); - /// `MSG_TRUNC` - // Apple, illumos, and NetBSD have `MSG_TRUNC` but it's not documented - // for use with `recv` and friends, and in practice appears to be - // ignored. - #[cfg(not(any(apple, solarish, target_os = "horizon", target_os = "netbsd")))] - const TRUNC = bitcast!(c::MSG_TRUNC); - /// `MSG_WAITALL` - const WAITALL = bitcast!(c::MSG_WAITALL); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MSG_*` flags returned from [`recvmsg`], in the `flags` field of - /// [`RecvMsg`] - /// - /// [`recvmsg`]: crate::net::recvmsg - /// [`RecvMsg`]: crate::net::RecvMsg - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReturnFlags: u32 { - /// `MSG_OOB` - const OOB = bitcast!(c::MSG_OOB); - /// `MSG_EOR` - #[cfg(not(any(windows, target_os = "horizon")))] - const EOR = bitcast!(c::MSG_EOR); - /// `MSG_TRUNC` - #[cfg(not(target_os = "horizon"))] - const TRUNC = bitcast!(c::MSG_TRUNC); - /// `MSG_CTRUNC` - #[cfg(not(target_os = "horizon"))] - const CTRUNC = bitcast!(c::MSG_CTRUNC); - - /// `MSG_CMSG_CLOEXEC` - #[cfg(linux_kernel)] - const CMSG_CLOEXEC = bitcast!(c::MSG_CMSG_CLOEXEC); - /// `MSG_ERRQUEUE` - #[cfg(linux_kernel)] - const ERRQUEUE = bitcast!(c::MSG_ERRQUEUE); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/net/sockopt.rs b/vendor/rustix/src/backend/libc/net/sockopt.rs deleted file mode 100644 index 132ebe75..00000000 --- a/vendor/rustix/src/backend/libc/net/sockopt.rs +++ /dev/null @@ -1,1339 +0,0 @@ -//! libc syscalls supporting `rustix::net::sockopt`. - -use super::ext::{in6_addr_new, in_addr_new}; -use crate::backend::c; -use crate::backend::conv::{borrowed_fd, ret}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use crate::ffi::CStr; -use crate::io; -use crate::net::sockopt::Timeout; -#[cfg(target_os = "linux")] -use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpRingOffset, XdpStatistics, XdpUmemReg}; -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - target_os = "vita", -)))] -use crate::net::AddressFamily; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -use crate::net::Protocol; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -use crate::net::RawProtocol; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use crate::net::SocketAddrV4; -use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; -#[cfg(linux_kernel)] -use crate::net::{SocketAddrV6, UCred}; -use crate::utils::as_mut_ptr; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use alloc::borrow::ToOwned as _; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use alloc::string::String; -#[cfg(apple)] -use c::TCP_KEEPALIVE as TCP_KEEPIDLE; -#[cfg(not(any(apple, target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -use c::TCP_KEEPIDLE; -use core::mem::{size_of, MaybeUninit}; -use core::time::Duration; -#[cfg(target_os = "linux")] -use linux_raw_sys::xdp::{xdp_mmap_offsets, xdp_statistics, xdp_statistics_v1}; -#[cfg(windows)] -use windows_sys::Win32::Foundation::BOOL; - -#[inline] -fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result<T> { - let mut optlen = size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - let mut value = MaybeUninit::<T>::zeroed(); - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - - // On Windows at least, `getsockopt` has been observed writing 1 - // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though - // Windows' documentation says that should write a 4-byte `BOOL`. - // So, we initialize the memory to zeros above, and just assert - // that `getsockopt` doesn't write too many bytes here. - assert!( - optlen as usize <= size_of::<T>(), - "unexpected getsockopt size" - ); - - unsafe { Ok(value.assume_init()) } -} - -#[inline] -fn getsockopt_raw<T>( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - value: &mut MaybeUninit<T>, - optlen: &mut c::socklen_t, -) -> io::Result<()> { - unsafe { - ret(c::getsockopt( - borrowed_fd(fd), - level, - optname, - as_mut_ptr(value).cast(), - optlen, - )) - } -} - -#[inline] -fn setsockopt<T: Copy>(fd: BorrowedFd<'_>, level: i32, optname: i32, value: T) -> io::Result<()> { - let optlen = size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - setsockopt_raw(fd, level, optname, &value, optlen) -} - -#[inline] -fn setsockopt_raw<T>( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - ptr: *const T, - optlen: c::socklen_t, -) -> io::Result<()> { - unsafe { - ret(c::setsockopt( - borrowed_fd(fd), - level, - optname, - ptr.cast(), - optlen, - )) - } -} - -#[inline] -pub(crate) fn socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { - getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) -} - -#[inline] -pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) -} - -#[inline] -pub(crate) fn socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) -} - -#[inline] -pub(crate) fn socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option<Duration>) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: linger.is_some().into(), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) -} - -#[inline] -pub(crate) fn socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, -) -> io::Result<()> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - let timeout = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // Rust's musl libc bindings deprecated `time_t` while they - // transition to 64-bit `time_t`. What we want here is just - // “whatever type `timeval`'s `tv_sec` is”, so we're ok using - // the deprecated type. - #[allow(deprecated)] - let tv_sec = timeout.as_secs().try_into().unwrap_or(c::time_t::MAX); - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = c::timeval { - tv_sec, - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => c::timeval { - tv_sec: 0, - tv_usec: 0, - }, - }; - - #[cfg(windows)] - let timeout: u32 = match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `as_millis` rounds down, so we use `as_nanos` and - // manually round up. - let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - if timeout == 0 { - timeout = 1; - } - timeout - } - None => 0, - }; - - setsockopt(fd, c::SOL_SOCKET, optname, timeout) -} - -#[inline] -pub(crate) fn socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - { - let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - Ok(None) - } else { - Ok(Some( - Duration::from_secs(timeout.tv_sec as u64) - + Duration::from_micros(timeout.tv_usec as u64), - )) - } - } - - #[cfg(windows)] - { - let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout == 0 { - Ok(None) - } else { - Ok(Some(Duration::from_millis(timeout as u64))) - } - } -} - -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[inline] -pub(crate) fn socket_nosigpipe(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE).map(to_bool) -} - -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[inline] -pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) -} - -#[inline] -pub(crate) fn socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) -} - -#[inline] -pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) -} - -#[inline] -pub(crate) fn socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -pub(crate) fn set_socket_recv_buffer_size_force(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUFFORCE, size) -} - -#[inline] -pub(crate) fn socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) -} - -#[inline] -pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -pub(crate) fn set_socket_send_buffer_size_force(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUFFORCE, size) -} - -#[inline] -pub(crate) fn socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) -} - -#[inline] -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "netbsd", - target_os = "nto", - target_os = "vita", -)))] -pub(crate) fn socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) -} - -#[inline] -#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. -pub(crate) fn socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) -} - -#[inline] -pub(crate) fn socket_oobinline(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) -} - -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[inline] -pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) -} - -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[inline] -pub(crate) fn socket_reuseport(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) -} - -#[cfg(target_os = "freebsd")] -#[inline] -pub(crate) fn set_socket_reuseport_lb(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT_LB, from_bool(value)) -} - -#[cfg(target_os = "freebsd")] -#[inline] -pub(crate) fn socket_reuseport_lb(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT_LB).map(to_bool) -} - -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -#[inline] -pub(crate) fn socket_protocol(fd: BorrowedFd<'_>) -> io::Result<Option<Protocol>> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) - .map(|raw| RawProtocol::new(raw).map(Protocol::from_raw)) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn socket_cookie(fd: BorrowedFd<'_>) -> io::Result<u64> { - getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_socket_incoming_cpu(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU, value) -} - -#[inline] -pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) -} - -#[inline] -pub(crate) fn ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) -} - -#[inline] -pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) -} - -#[inline] -pub(crate) fn ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) -} - -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[inline] -pub(crate) fn ip_mtu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MTU) -} - -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[inline] -pub(crate) fn ipv6_mtu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MTU) -} - -#[inline] -pub(crate) fn set_ip_multicast_if(fd: BorrowedFd<'_>, value: &Ipv4Addr) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_IF, to_imr_addr(value)) -} - -#[inline] -pub(crate) fn ip_multicast_if(fd: BorrowedFd<'_>) -> io::Result<Ipv4Addr> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_IF).map(from_in_addr) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -pub(crate) fn set_ip_multicast_if_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_IF, mreqn) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_if(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_IF, value as c::c_int) -} - -#[inline] -pub(crate) fn ipv6_multicast_if(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_IF) -} - -#[inline] -pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) -} - -#[inline] -pub(crate) fn ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) -} - -#[inline] -pub(crate) fn ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) -} - -#[inline] -pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - let mreq = to_ip_mreq(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -pub(crate) fn set_ip_add_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) -} - -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -pub(crate) fn set_ip_add_source_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) -} - -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -pub(crate) fn set_ip_drop_source_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) -} - -#[inline] -pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_ADD_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - let mreq = to_ip_mreq(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -pub(crate) fn set_ip_drop_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) -} - -#[inline] -pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - )))] - use c::IPV6_DROP_MEMBERSHIP; - #[cfg(any( - bsd, - solarish, - target_os = "haiku", - target_os = "l4re", - target_os = "nto" - ))] - use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) -} - -#[inline] -pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops as c::c_int, - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto", - target_env = "newlib" -))] -#[inline] -pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto", - target_env = "newlib" -))] -#[inline] -pub(crate) fn ip_tos(fd: BorrowedFd<'_>) -> io::Result<u8> { - let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; - Ok(value as u8) -} - -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) -} - -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -pub(crate) fn ip_recvtos(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) -} - -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -pub(crate) fn ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn ip_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn ip_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV4> { - let level = c::IPPROTO_IP; - let optname = c::SO_ORIGINAL_DST; - - let mut addr = crate::net::SocketAddrBuf::new(); - getsockopt_raw(fd, level, optname, &mut addr.storage, &mut addr.len)?; - Ok(unsafe { addr.into_any() }.try_into().unwrap()) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV6> { - let level = c::IPPROTO_IPV6; - let optname = c::IP6T_SO_ORIGINAL_DST; - - let mut addr = crate::net::SocketAddrBuf::new(); - getsockopt_raw(fd, level, optname, &mut addr.storage, &mut addr.len)?; - Ok(unsafe { addr.into_any() }.try_into().unwrap()) -} - -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) -} - -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -pub(crate) fn ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS) -} - -#[inline] -pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) -} - -#[inline] -pub(crate) fn tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) -} - -#[inline] -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE, secs) -} - -#[inline] -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -pub(crate) fn tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) -} - -#[inline] -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -pub(crate) fn tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) -} - -#[inline] -#[cfg(any(linux_like, target_os = "fuchsia"))] -pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) -} - -#[inline] -#[cfg(any(linux_like, target_os = "fuchsia"))] -pub(crate) fn tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn tcp_quickack(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) -} - -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -pub(crate) fn set_tcp_congestion(fd: BorrowedFd<'_>, value: &str) -> io::Result<()> { - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - let optlen = value.len().try_into().unwrap(); - setsockopt_raw(fd, level, optname, value.as_ptr(), optlen) -} - -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -pub(crate) fn tcp_congestion(fd: BorrowedFd<'_>) -> io::Result<String> { - const OPTLEN: c::socklen_t = 16; - - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - let mut value = MaybeUninit::<[MaybeUninit<u8>; OPTLEN as usize]>::uninit(); - let mut optlen = OPTLEN; - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - unsafe { - let value = value.assume_init(); - let slice: &[u8] = core::mem::transmute(&value[..optlen as usize]); - assert!(slice.contains(&b'\0')); - Ok( - core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) - .unwrap() - .to_owned(), - ) - } -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_TCP, - c::TCP_THIN_LINEAR_TIMEOUTS, - from_bool(value), - ) -} - -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -pub(crate) fn tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) -} - -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) -} - -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -pub(crate) fn tcp_cork(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PEERCRED) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_reg(fd: BorrowedFd<'_>, value: XdpUmemReg) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_REG, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_fill_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_FILL_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_completion_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_COMPLETION_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_tx_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_TX_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_rx_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_RX_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_mmap_offsets(fd: BorrowedFd<'_>) -> io::Result<XdpMmapOffsets> { - // The kernel will write `xdp_mmap_offsets` or `xdp_mmap_offsets_v1` to the - // supplied pointer, depending on the kernel version. Both structs only - // contain u64 values. By using the larger of both as the parameter, we can - // shuffle the values to the non-v1 version returned by - // `get_xdp_mmap_offsets` while keeping the return type unaffected by the - // kernel version. This works because C will layout all struct members one - // after the other. - - let mut optlen = size_of::<xdp_mmap_offsets>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - let mut value = MaybeUninit::<xdp_mmap_offsets>::zeroed(); - getsockopt_raw(fd, c::SOL_XDP, c::XDP_MMAP_OFFSETS, &mut value, &mut optlen)?; - - if optlen as usize == size_of::<c::xdp_mmap_offsets_v1>() { - // SAFETY: All members of xdp_mmap_offsets are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xpd_mmap_offsets = unsafe { value.assume_init() }; - Ok(XdpMmapOffsets { - rx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.producer, - consumer: xpd_mmap_offsets.rx.consumer, - desc: xpd_mmap_offsets.rx.desc, - flags: None, - }, - tx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.flags, - consumer: xpd_mmap_offsets.tx.producer, - desc: xpd_mmap_offsets.tx.consumer, - flags: None, - }, - fr: XdpRingOffset { - producer: xpd_mmap_offsets.tx.desc, - consumer: xpd_mmap_offsets.tx.flags, - desc: xpd_mmap_offsets.fr.producer, - flags: None, - }, - cr: XdpRingOffset { - producer: xpd_mmap_offsets.fr.consumer, - consumer: xpd_mmap_offsets.fr.desc, - desc: xpd_mmap_offsets.fr.flags, - flags: None, - }, - }) - } else { - assert_eq!( - optlen as usize, - size_of::<xdp_mmap_offsets>(), - "unexpected getsockopt size" - ); - // SAFETY: All members of xdp_mmap_offsets are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()` - let xpd_mmap_offsets = unsafe { value.assume_init() }; - Ok(XdpMmapOffsets { - rx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.producer, - consumer: xpd_mmap_offsets.rx.consumer, - desc: xpd_mmap_offsets.rx.desc, - flags: Some(xpd_mmap_offsets.rx.flags), - }, - tx: XdpRingOffset { - producer: xpd_mmap_offsets.tx.producer, - consumer: xpd_mmap_offsets.tx.consumer, - desc: xpd_mmap_offsets.tx.desc, - flags: Some(xpd_mmap_offsets.tx.flags), - }, - fr: XdpRingOffset { - producer: xpd_mmap_offsets.fr.producer, - consumer: xpd_mmap_offsets.fr.consumer, - desc: xpd_mmap_offsets.fr.desc, - flags: Some(xpd_mmap_offsets.fr.flags), - }, - cr: XdpRingOffset { - producer: xpd_mmap_offsets.cr.producer, - consumer: xpd_mmap_offsets.cr.consumer, - desc: xpd_mmap_offsets.cr.desc, - flags: Some(xpd_mmap_offsets.cr.flags), - }, - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_statistics(fd: BorrowedFd<'_>) -> io::Result<XdpStatistics> { - let mut optlen = size_of::<xdp_statistics>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - let mut value = MaybeUninit::<xdp_statistics>::zeroed(); - getsockopt_raw(fd, c::SOL_XDP, c::XDP_STATISTICS, &mut value, &mut optlen)?; - - if optlen as usize == size_of::<xdp_statistics_v1>() { - // SAFETY: All members of xdp_statistics are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xdp_statistics = unsafe { value.assume_init() }; - Ok(XdpStatistics { - rx_dropped: xdp_statistics.rx_dropped, - rx_invalid_descs: xdp_statistics.rx_dropped, - tx_invalid_descs: xdp_statistics.rx_dropped, - rx_ring_full: None, - rx_fill_ring_empty_descs: None, - tx_ring_empty_descs: None, - }) - } else { - assert_eq!( - optlen as usize, - size_of::<xdp_statistics>(), - "unexpected getsockopt size" - ); - // SAFETY: All members of xdp_statistics are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xdp_statistics = unsafe { value.assume_init() }; - Ok(XdpStatistics { - rx_dropped: xdp_statistics.rx_dropped, - rx_invalid_descs: xdp_statistics.rx_invalid_descs, - tx_invalid_descs: xdp_statistics.tx_invalid_descs, - rx_ring_full: Some(xdp_statistics.rx_ring_full), - rx_fill_ring_empty_descs: Some(xdp_statistics.rx_fill_ring_empty_descs), - tx_ring_empty_descs: Some(xdp_statistics.tx_ring_empty_descs), - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_options(fd: BorrowedFd<'_>) -> io::Result<XdpOptionsFlags> { - getsockopt(fd, c::SOL_XDP, c::XDP_OPTIONS) -} - -#[inline] -fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } -} - -#[cfg(not(windows))] -#[inline] -fn from_in_addr(in_addr: c::in_addr) -> Ipv4Addr { - Ipv4Addr::from(in_addr.s_addr.to_ne_bytes()) -} - -#[cfg(windows)] -fn from_in_addr(in_addr: c::in_addr) -> Ipv4Addr { - Ipv4Addr::from(unsafe { in_addr.S_un.S_addr.to_ne_bytes() }) -} - -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { - c::ip_mreqn { - imr_multiaddr: to_imr_addr(multiaddr), - imr_address: to_imr_addr(address), - imr_ifindex: ifindex, - } -} - -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -fn to_imr_source( - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> c::ip_mreq_source { - c::ip_mreq_source { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - imr_sourceaddr: to_imr_addr(sourceaddr), - } -} - -#[inline] -fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - in_addr_new(u32::from_ne_bytes(addr.octets())) -} - -#[inline] -fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_interface: to_ipv6mr_interface(interface), - } -} - -#[inline] -fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - in6_addr_new(multiaddr.octets()) -} - -#[cfg(target_os = "android")] -#[inline] -fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int -} - -#[cfg(not(target_os = "android"))] -#[inline] -fn to_ipv6mr_interface(interface: u32) -> c::c_uint { - interface as c::c_uint -} - -// `getsockopt` and `setsockopt` represent boolean values as integers. -#[cfg(not(windows))] -type RawSocketBool = c::c_int; -#[cfg(windows)] -type RawSocketBool = BOOL; - -// Wrap `RawSocketBool` in a newtype to discourage misuse. -#[repr(transparent)] -#[derive(Copy, Clone)] -struct SocketBool(RawSocketBool); - -// Convert from a `bool` to a `SocketBool`. -#[inline] -fn from_bool(value: bool) -> SocketBool { - SocketBool(value.into()) -} - -// Convert from a `SocketBool` to a `bool`. -#[inline] -fn to_bool(value: SocketBool) -> bool { - value.0 != 0 -} - -/// Convert to seconds, rounding up if necessary. -#[inline] -fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) -} diff --git a/vendor/rustix/src/backend/libc/net/syscalls.rs b/vendor/rustix/src/backend/libc/net/syscalls.rs deleted file mode 100644 index aafea002..00000000 --- a/vendor/rustix/src/backend/libc/net/syscalls.rs +++ /dev/null @@ -1,438 +0,0 @@ -//! libc syscalls supporting `rustix::net`. - -use super::read_sockaddr::initialize_family_to_unspec; -use super::send_recv::{RecvFlags, SendFlags}; -use crate::backend::c; -#[cfg(target_os = "linux")] -use crate::backend::conv::ret_u32; -use crate::backend::conv::{borrowed_fd, ret, ret_owned_fd, ret_send_recv, send_recv_len}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::net::addr::SocketAddrArg; -#[cfg(target_os = "linux")] -use crate::net::MMsgHdr; -use crate::net::{ - AddressFamily, Protocol, Shutdown, SocketAddrAny, SocketAddrBuf, SocketFlags, SocketType, -}; -use crate::utils::as_ptr; -use core::mem::{size_of, MaybeUninit}; -use core::ptr::null_mut; -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -use { - super::msghdr::{noaddr_msghdr, with_msghdr, with_recv_msghdr}, - super::send_recv::ReturnFlags, - crate::io::{IoSlice, IoSliceMut}, - crate::net::{RecvAncillaryBuffer, RecvMsg, SendAncillaryBuffer}, -}; - -pub(crate) unsafe fn recv( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - flags: RecvFlags, -) -> io::Result<usize> { - ret_send_recv(c::recv( - borrowed_fd(fd), - buf.0.cast(), - send_recv_len(buf.1), - bitflags_bits!(flags), - )) -} - -pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result<usize> { - unsafe { - ret_send_recv(c::send( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - bitflags_bits!(flags), - )) - } -} - -pub(crate) unsafe fn recvfrom( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - flags: RecvFlags, -) -> io::Result<(usize, Option<SocketAddrAny>)> { - let mut addr = SocketAddrBuf::new(); - - // `recvfrom` does not write to the storage if the socket is - // connection-oriented sockets, so we initialize the family field to - // `AF_UNSPEC` so that we can detect this case. - initialize_family_to_unspec(addr.storage.as_mut_ptr().cast::<c::sockaddr>()); - - let nread = ret_send_recv(c::recvfrom( - borrowed_fd(fd), - buf.0.cast(), - send_recv_len(buf.1), - bitflags_bits!(flags), - addr.storage.as_mut_ptr().cast::<c::sockaddr>(), - &mut addr.len, - ))?; - - Ok((nread, addr.into_any_option())) -} - -pub(crate) fn sendto( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &impl SocketAddrArg, -) -> io::Result<usize> { - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - ret_send_recv(c::sendto( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - bitflags_bits!(flags), - addr_ptr.cast(), - bitcast!(addr_len), - )) - }) - } -} - -pub(crate) fn socket( - domain: AddressFamily, - type_: SocketType, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - let raw_protocol = match protocol { - Some(p) => p.0.get(), - None => 0, - }; - unsafe { - ret_owned_fd(c::socket( - domain.0 as c::c_int, - type_.0 as c::c_int, - raw_protocol as c::c_int, - )) - } -} - -pub(crate) fn socket_with( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - let raw_protocol = match protocol { - Some(p) => p.0.get(), - None => 0, - }; - unsafe { - ret_owned_fd(c::socket( - domain.0 as c::c_int, - (type_.0 | flags.bits()) as c::c_int, - raw_protocol as c::c_int, - )) - } -} - -pub(crate) fn bind(sockfd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> { - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - ret(c::bind( - borrowed_fd(sockfd), - addr_ptr.cast(), - bitcast!(addr_len), - )) - }) - } -} - -pub(crate) fn connect(sockfd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> { - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - ret(c::connect( - borrowed_fd(sockfd), - addr_ptr.cast(), - bitcast!(addr_len), - )) - }) - } -} - -pub(crate) fn connect_unspec(sockfd: BorrowedFd<'_>) -> io::Result<()> { - debug_assert_eq!(c::AF_UNSPEC, 0); - let addr = MaybeUninit::<c::sockaddr_storage>::zeroed(); - unsafe { - ret(c::connect( - borrowed_fd(sockfd), - as_ptr(&addr).cast(), - size_of::<c::sockaddr_storage>() as c::socklen_t, - )) - } -} - -pub(crate) fn listen(sockfd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { - unsafe { ret(c::listen(borrowed_fd(sockfd), backlog)) } -} - -pub(crate) fn accept(sockfd: BorrowedFd<'_>) -> io::Result<OwnedFd> { - unsafe { - let owned_fd = ret_owned_fd(c::accept(borrowed_fd(sockfd), null_mut(), null_mut()))?; - Ok(owned_fd) - } -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn recvmsg( - sockfd: BorrowedFd<'_>, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - msg_flags: RecvFlags, -) -> io::Result<RecvMsg> { - let mut addr = SocketAddrBuf::new(); - - // SAFETY: This passes the `msghdr` reference to the OS which reads the - // buffers only within the designated bounds. - let (bytes, flags) = unsafe { - with_recv_msghdr(&mut addr, iov, control, |msghdr| { - let bytes = ret_send_recv(c::recvmsg( - borrowed_fd(sockfd), - msghdr, - bitflags_bits!(msg_flags), - ))?; - Ok((bytes, msghdr.msg_flags)) - })? - }; - - Ok(RecvMsg { - bytes, - address: unsafe { addr.into_any_option() }, - flags: ReturnFlags::from_bits_retain(bitcast!(flags)), - }) -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn sendmsg( - sockfd: BorrowedFd<'_>, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - let msghdr = noaddr_msghdr(iov, control); - unsafe { - ret_send_recv(c::sendmsg( - borrowed_fd(sockfd), - &msghdr, - bitflags_bits!(msg_flags), - )) - } -} - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub(crate) fn sendmsg_addr( - sockfd: BorrowedFd<'_>, - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - // SAFETY: This passes the `msghdr` reference to the OS which reads the - // buffers only within the designated bounds. - unsafe { - with_msghdr(addr, iov, control, |msghdr| { - ret_send_recv(c::sendmsg( - borrowed_fd(sockfd), - msghdr, - bitflags_bits!(msg_flags), - )) - }) - } -} - -#[cfg(target_os = "linux")] -pub(crate) fn sendmmsg( - sockfd: BorrowedFd<'_>, - msgs: &mut [MMsgHdr<'_>], - flags: SendFlags, -) -> io::Result<usize> { - unsafe { - ret_u32(c::sendmmsg( - borrowed_fd(sockfd), - msgs.as_mut_ptr() as _, - msgs.len().try_into().unwrap_or(c::c_uint::MAX), - bitflags_bits!(flags), - )) - .map(|ret| ret as usize) - } -} - -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, flags: SocketFlags) -> io::Result<OwnedFd> { - unsafe { - let owned_fd = ret_owned_fd(c::accept4( - borrowed_fd(sockfd), - null_mut(), - null_mut(), - flags.bits() as c::c_int, - ))?; - Ok(owned_fd) - } -} - -pub(crate) fn acceptfrom(sockfd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - unsafe { - let mut addr = SocketAddrBuf::new(); - let owned_fd = ret_owned_fd(c::accept( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::<c::sockaddr>(), - &mut addr.len, - ))?; - Ok((owned_fd, addr.into_any_option())) - } -} - -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -pub(crate) fn acceptfrom_with( - sockfd: BorrowedFd<'_>, - flags: SocketFlags, -) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - unsafe { - let mut addr = SocketAddrBuf::new(); - let owned_fd = ret_owned_fd(c::accept4( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::<c::sockaddr>(), - &mut addr.len, - flags.bits() as c::c_int, - ))?; - Ok((owned_fd, addr.into_any_option())) - } -} - -/// Darwin lacks `accept4`, but does have `accept`. We define `SocketFlags` to -/// have no flags, so we can discard it here. -#[cfg(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -))] -pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, _flags: SocketFlags) -> io::Result<OwnedFd> { - accept(sockfd) -} - -/// Darwin lacks `accept4`, but does have `accept`. We define `SocketFlags` to -/// have no flags, so we can discard it here. -#[cfg(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -))] -pub(crate) fn acceptfrom_with( - sockfd: BorrowedFd<'_>, - _flags: SocketFlags, -) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - acceptfrom(sockfd) -} - -pub(crate) fn shutdown(sockfd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { - unsafe { ret(c::shutdown(borrowed_fd(sockfd), how as c::c_int)) } -} - -pub(crate) fn getsockname(sockfd: BorrowedFd<'_>) -> io::Result<SocketAddrAny> { - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(c::getsockname( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::<c::sockaddr>(), - &mut addr.len, - ))?; - Ok(addr.into_any()) - } -} - -pub(crate) fn getpeername(sockfd: BorrowedFd<'_>) -> io::Result<Option<SocketAddrAny>> { - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(c::getpeername( - borrowed_fd(sockfd), - addr.storage.as_mut_ptr().cast::<c::sockaddr>(), - &mut addr.len, - ))?; - Ok(addr.into_any_option()) - } -} - -#[cfg(not(windows))] -pub(crate) fn socketpair( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<(OwnedFd, OwnedFd)> { - let raw_protocol = match protocol { - Some(p) => p.0.get(), - None => 0, - }; - unsafe { - let mut fds = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(c::socketpair( - c::c_int::from(domain.0), - (type_.0 | flags.bits()) as c::c_int, - raw_protocol as c::c_int, - fds.as_mut_ptr().cast::<c::c_int>(), - ))?; - - let [fd0, fd1] = fds.assume_init(); - Ok((fd0, fd1)) - } -} diff --git a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs deleted file mode 100644 index 08f04646..00000000 --- a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! The BSD sockets API requires us to read the `sa_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. - -use super::ext::{in6_addr_new, in_addr_new, sockaddr_in6_new}; -use crate::backend::c; -use crate::net::{SocketAddrV4, SocketAddrV6}; - -pub(crate) fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { - c::sockaddr_in { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita", - ))] - sin_len: core::mem::size_of::<c::sockaddr_in>() as _, - sin_family: c::AF_INET as _, - sin_port: u16::to_be(v4.port()), - sin_addr: in_addr_new(u32::from_ne_bytes(v4.ip().octets())), - #[cfg(not(any(target_os = "haiku", target_os = "vita")))] - sin_zero: [0; 8_usize], - #[cfg(target_os = "haiku")] - sin_zero: [0; 24_usize], - #[cfg(target_os = "vita")] - sin_zero: [0; 6_usize], - #[cfg(target_os = "vita")] - sin_vport: 0, - } -} - -pub(crate) fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { - #[cfg(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - ))] - { - sockaddr_in6_new( - core::mem::size_of::<c::sockaddr_in6>() as _, - c::AF_INET6 as _, - u16::to_be(v6.port()), - u32::to_be(v6.flowinfo()), - in6_addr_new(v6.ip().octets()), - v6.scope_id(), - ) - } - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "vita" - )))] - { - sockaddr_in6_new( - c::AF_INET6 as _, - u16::to_be(v6.port()), - u32::to_be(v6.flowinfo()), - in6_addr_new(v6.ip().octets()), - v6.scope_id(), - ) - } -} diff --git a/vendor/rustix/src/backend/libc/param/auxv.rs b/vendor/rustix/src/backend/libc/param/auxv.rs deleted file mode 100644 index 6b6ea955..00000000 --- a/vendor/rustix/src/backend/libc/param/auxv.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::backend::c; -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -use crate::ffi::CStr; - -// `getauxval` wasn't supported in glibc until 2.16. -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -weak!(fn getauxval(c::c_ulong) -> *mut c::c_void); - -#[inline] -pub(crate) fn page_size() -> usize { - unsafe { c::sysconf(c::_SC_PAGESIZE) as usize } -} - -#[cfg(not(any(target_os = "horizon", target_os = "vita", target_os = "wasi")))] -#[inline] -pub(crate) fn clock_ticks_per_second() -> u64 { - unsafe { c::sysconf(c::_SC_CLK_TCK) as u64 } -} - -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -#[inline] -pub(crate) fn linux_hwcap() -> (usize, usize) { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { - let hwcap = libc_getauxval(c::AT_HWCAP) as usize; - let hwcap2 = libc_getauxval(c::AT_HWCAP2) as usize; - (hwcap, hwcap2) - } - } else { - (0, 0) - } -} - -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -#[inline] -pub(crate) fn linux_minsigstksz() -> usize { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { libc_getauxval(c::AT_MINSIGSTKSZ) as usize } - } else { - 0 - } -} - -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -#[inline] -pub(crate) fn linux_execfn() -> &'static CStr { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { CStr::from_ptr(libc_getauxval(c::AT_EXECFN).cast()) } - } else { - cstr!("") - } -} diff --git a/vendor/rustix/src/backend/libc/param/mod.rs b/vendor/rustix/src/backend/libc/param/mod.rs deleted file mode 100644 index 2cb2fe78..00000000 --- a/vendor/rustix/src/backend/libc/param/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod auxv; diff --git a/vendor/rustix/src/backend/libc/pid/mod.rs b/vendor/rustix/src/backend/libc/pid/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/libc/pid/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/pid/syscalls.rs b/vendor/rustix/src/backend/libc/pid/syscalls.rs deleted file mode 100644 index d0ed4bc9..00000000 --- a/vendor/rustix/src/backend/libc/pid/syscalls.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! libc syscalls for PIDs - -use crate::backend::c; -use crate::pid::Pid; - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getpid() -> Pid { - unsafe { - let pid = c::getpid(); - Pid::from_raw_unchecked(pid) - } -} diff --git a/vendor/rustix/src/backend/libc/pipe/mod.rs b/vendor/rustix/src/backend/libc/pipe/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/libc/pipe/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/pipe/syscalls.rs b/vendor/rustix/src/backend/libc/pipe/syscalls.rs deleted file mode 100644 index fe524954..00000000 --- a/vendor/rustix/src/backend/libc/pipe/syscalls.rs +++ /dev/null @@ -1,126 +0,0 @@ -use crate::backend::c; -use crate::backend::conv::ret; -use crate::fd::OwnedFd; -use crate::io; -#[cfg(not(any( - apple, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "nto", - target_os = "wasi" -)))] -use crate::pipe::PipeFlags; -use core::mem::MaybeUninit; -#[cfg(linux_kernel)] -use { - crate::backend::conv::{borrowed_fd, ret_c_int, ret_usize}, - crate::backend::MAX_IOV, - crate::fd::BorrowedFd, - crate::pipe::{IoSliceRaw, SpliceFlags}, - crate::utils::option_as_mut_ptr, - core::cmp::min, -}; - -#[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( - apple, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - 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>(), - bitflags_bits!(flags), - ))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn splice( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - let off_in = option_as_mut_ptr(off_in).cast(); - let off_out = option_as_mut_ptr(off_out).cast(); - - unsafe { - ret_usize(c::splice( - borrowed_fd(fd_in), - off_in, - borrowed_fd(fd_out), - off_out, - len, - flags.bits(), - )) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) unsafe fn vmsplice( - fd: BorrowedFd<'_>, - bufs: &[IoSliceRaw<'_>], - flags: SpliceFlags, -) -> io::Result<usize> { - ret_usize(c::vmsplice( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), MAX_IOV), - flags.bits(), - )) -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn tee( - fd_in: BorrowedFd<'_>, - fd_out: BorrowedFd<'_>, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - unsafe { - ret_usize(c::tee( - borrowed_fd(fd_in), - borrowed_fd(fd_out), - len, - flags.bits(), - )) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn fcntl_getpipe_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETPIPE_SZ)).map(|size| size as usize) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn fcntl_setpipe_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<usize> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?; - - unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)).map(|size| size as usize) } -} diff --git a/vendor/rustix/src/backend/libc/pipe/types.rs b/vendor/rustix/src/backend/libc/pipe/types.rs deleted file mode 100644 index db04a942..00000000 --- a/vendor/rustix/src/backend/libc/pipe/types.rs +++ /dev/null @@ -1,117 +0,0 @@ -#[cfg(linux_kernel)] -use crate::ffi; -#[cfg(linux_kernel)] -use core::marker::PhantomData; -#[cfg(not(any(apple, target_os = "wasi")))] -use {crate::backend::c, bitflags::bitflags}; - -#[cfg(not(any(apple, target_os = "wasi")))] -bitflags! { - /// `O_*` constants for use with [`pipe_with`]. - /// - /// [`pipe_with`]: crate::pipe::pipe_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PipeFlags: u32 { - /// `O_CLOEXEC` - const CLOEXEC = bitcast!(c::O_CLOEXEC); - /// `O_DIRECT` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - )))] - const DIRECT = bitcast!(c::O_DIRECT); - /// `O_NONBLOCK` - const NONBLOCK = bitcast!(c::O_NONBLOCK); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `SPLICE_F_*` constants for use with [`splice`], [`vmsplice`], and - /// [`tee`]. - /// - /// [`splice`]: crate::pipe::splice - /// [`vmsplice`]: crate::pipe::splice - /// [`tee`]: crate::pipe::tee - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpliceFlags: ffi::c_uint { - /// `SPLICE_F_MOVE` - const MOVE = c::SPLICE_F_MOVE; - /// `SPLICE_F_NONBLOCK` - const NONBLOCK = c::SPLICE_F_NONBLOCK; - /// `SPLICE_F_MORE` - const MORE = c::SPLICE_F_MORE; - /// `SPLICE_F_GIFT` - const GIFT = c::SPLICE_F_GIFT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// A buffer type for use with [`vmsplice`]. -/// -/// It is guaranteed to be ABI compatible with the iovec type on Unix platforms -/// and `WSABUF` on Windows. Unlike `IoSlice` and `IoSliceMut` it is -/// semantically like a raw pointer, and therefore can be shared or mutated as -/// needed. -/// -/// [`vmsplice`]: crate::pipe::vmsplice -#[cfg(linux_kernel)] -#[repr(transparent)] -pub struct IoSliceRaw<'a> { - _buf: c::iovec, - _lifetime: PhantomData<&'a ()>, -} - -#[cfg(linux_kernel)] -impl<'a> IoSliceRaw<'a> { - /// Creates a new `IoSlice` wrapping a byte slice. - pub fn from_slice(buf: &'a [u8]) -> Self { - IoSliceRaw { - _buf: c::iovec { - iov_base: (buf.as_ptr() as *mut u8).cast::<c::c_void>(), - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } - } - - /// Creates a new `IoSlice` wrapping a mutable byte slice. - pub fn from_slice_mut(buf: &'a mut [u8]) -> Self { - IoSliceRaw { - _buf: c::iovec { - iov_base: buf.as_mut_ptr().cast::<c::c_void>(), - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } - } -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - - #[cfg(not(any(apple, target_os = "wasi")))] - #[test] - fn test_types() { - assert_eq_size!(PipeFlags, c::c_int); - - #[cfg(linux_kernel)] - assert_eq_size!(SpliceFlags, c::c_int); - } -} diff --git a/vendor/rustix/src/backend/libc/prctl/mod.rs b/vendor/rustix/src/backend/libc/prctl/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/libc/prctl/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/prctl/syscalls.rs b/vendor/rustix/src/backend/libc/prctl/syscalls.rs deleted file mode 100644 index 451cecc2..00000000 --- a/vendor/rustix/src/backend/libc/prctl/syscalls.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::backend::c; -use crate::backend::conv::ret_c_int; -use crate::io; - -#[inline] -pub(crate) unsafe fn prctl( - option: c::c_int, - arg2: *mut c::c_void, - arg3: *mut c::c_void, - arg4: *mut c::c_void, - arg5: *mut c::c_void, -) -> io::Result<c::c_int> { - ret_c_int(c::prctl(option, arg2, arg3, arg4, arg5)) -} diff --git a/vendor/rustix/src/backend/libc/process/mod.rs b/vendor/rustix/src/backend/libc/process/mod.rs deleted file mode 100644 index a937d7f8..00000000 --- a/vendor/rustix/src/backend/libc/process/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -pub(crate) mod wait; diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs deleted file mode 100644 index 3c67f2c3..00000000 --- a/vendor/rustix/src/backend/libc/process/syscalls.rs +++ /dev/null @@ -1,704 +0,0 @@ -//! libc syscalls supporting `rustix::process`. - -use crate::backend::c; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::backend::conv::borrowed_fd; -#[cfg(any(target_os = "linux", feature = "fs"))] -use crate::backend::conv::c_str; -#[cfg(all(feature = "alloc", feature = "fs", not(target_os = "wasi")))] -use crate::backend::conv::ret_discarded_char_ptr; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::backend::conv::ret_infallible; -#[cfg(not(target_os = "wasi"))] -use crate::backend::conv::ret_pid_t; -#[cfg(all(feature = "alloc", not(target_os = "wasi")))] -use crate::backend::conv::ret_usize; -use crate::backend::conv::{ret, ret_c_int}; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::fd::BorrowedFd; -#[cfg(target_os = "linux")] -use crate::fd::{AsRawFd as _, OwnedFd, RawFd}; -#[cfg(any(target_os = "linux", feature = "fs"))] -use crate::ffi::CStr; -#[cfg(feature = "fs")] -use crate::fs::Mode; -use crate::io; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::process::Flock; -#[cfg(all(feature = "alloc", not(target_os = "wasi")))] -use crate::process::Gid; -#[cfg(not(target_os = "wasi"))] -use crate::process::Pid; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -use crate::process::Signal; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "vita", - target_os = "wasi" -)))] -use crate::process::Uid; -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -use crate::process::{RawPid, WaitOptions, WaitStatus}; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::process::{Resource, Rlimit}; -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use crate::process::{WaitId, WaitIdOptions, WaitIdStatus}; -use core::mem::MaybeUninit; -#[cfg(target_os = "linux")] -use { - super::super::conv::ret_owned_fd, crate::process::PidfdFlags, crate::process::PidfdGetfdFlags, -}; - -#[cfg(feature = "fs")] -#[cfg(not(target_os = "wasi"))] -pub(crate) fn chdir(path: &CStr) -> io::Result<()> { - unsafe { ret(c::chdir(c_str(path))) } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -pub(crate) fn fchdir(dirfd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fchdir(borrowed_fd(dirfd))) } -} - -#[cfg(feature = "fs")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -pub(crate) fn chroot(path: &CStr) -> io::Result<()> { - unsafe { ret(c::chroot(c_str(path))) } -} - -#[cfg(all(feature = "alloc", feature = "fs"))] -#[cfg(not(target_os = "wasi"))] -pub(crate) fn getcwd(buf: &mut [MaybeUninit<u8>]) -> io::Result<()> { - unsafe { ret_discarded_char_ptr(c::getcwd(buf.as_mut_ptr().cast(), buf.len())) } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getppid() -> Option<Pid> { - unsafe { - let pid: i32 = c::getppid(); - Pid::from_raw(pid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { - unsafe { - let pgid = ret_pid_t(c::getpgid(Pid::as_raw(pid) as _))?; - Ok(Pid::from_raw_unchecked(pgid)) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { - unsafe { ret(c::setpgid(Pid::as_raw(pid) as _, Pid::as_raw(pgid) as _)) } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getpgrp() -> Pid { - unsafe { - let pgid = c::getpgrp(); - Pid::from_raw_unchecked(pgid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "fs")] -#[inline] -pub(crate) fn umask(mask: Mode) -> Mode { - unsafe { Mode::from_bits_retain(c::umask(mask.bits() as c::mode_t).into()) } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -#[inline] -pub(crate) fn nice(inc: i32) -> io::Result<i32> { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::nice(inc) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::getpriority(c::PRIO_USER, uid.as_raw() as _) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::getpriority(c::PRIO_PGRP, Pid::as_raw(pgid) as _) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::getpriority(c::PRIO_PROCESS, Pid::as_raw(pid) as _) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - unsafe { ret(c::setpriority(c::PRIO_USER, uid.as_raw() as _, priority)) } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { - unsafe { - ret(c::setpriority( - c::PRIO_PGRP, - Pid::as_raw(pgid) as _, - priority, - )) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { - unsafe { - ret(c::setpriority( - c::PRIO_PROCESS, - Pid::as_raw(pid) as _, - priority, - )) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn getrlimit(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::<c::rlimit>::uninit(); - unsafe { - ret_infallible(c::getrlimit(limit as _, result.as_mut_ptr())); - rlimit_from_libc(result.assume_init()) - } -} - -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { - let lim = rlimit_to_libc(new)?; - unsafe { ret(c::setrlimit(limit as _, &lim)) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Result<Rlimit> { - let lim = rlimit_to_libc(new)?; - let mut result = MaybeUninit::<c::rlimit>::uninit(); - unsafe { - ret(c::prlimit( - Pid::as_raw(pid), - limit as _, - &lim, - result.as_mut_ptr(), - ))?; - Ok(rlimit_from_libc(result.assume_init())) - } -} - -/// Convert a C `c::rlimit` to a Rust `Rlimit`. -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -fn rlimit_from_libc(lim: c::rlimit) -> Rlimit { - let current = if lim.rlim_cur == c::RLIM_INFINITY { - None - } else { - Some(lim.rlim_cur.try_into().unwrap()) - }; - let maximum = if lim.rlim_max == c::RLIM_INFINITY { - None - } else { - Some(lim.rlim_max.try_into().unwrap()) - }; - Rlimit { current, maximum } -} - -/// Convert a Rust [`Rlimit`] to a C `c::rlimit`. -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -fn rlimit_to_libc(lim: Rlimit) -> io::Result<c::rlimit> { - let Rlimit { current, maximum } = lim; - let rlim_cur = match current { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => c::RLIM_INFINITY as _, - }; - let rlim_max = match maximum { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => c::RLIM_INFINITY as _, - }; - Ok(c::rlimit { rlim_cur, rlim_max }) -} - -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -#[inline] -pub(crate) fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(!0, waitopts) -} - -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -#[inline] -pub(crate) fn waitpid( - pid: Option<Pid>, - waitopts: WaitOptions, -) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(Pid::as_raw(pid), waitopts) -} - -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -#[inline] -pub(crate) fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(-pgid.as_raw_nonzero().get(), waitopts) -} - -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -#[inline] -pub(crate) fn _waitpid( - pid: RawPid, - waitopts: WaitOptions, -) -> io::Result<Option<(Pid, WaitStatus)>> { - unsafe { - let mut status: c::c_int = 0; - let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?; - Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status as _)))) - } -} - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn waitid(id: WaitId<'_>, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // Get the id to wait on. - match id { - WaitId::All => _waitid_all(options), - WaitId::Pid(pid) => _waitid_pid(pid, options), - WaitId::Pgid(pgid) => _waitid_pgid(pgid, options), - #[cfg(target_os = "linux")] - WaitId::PidFd(fd) => _waitid_pidfd(fd, options), - #[cfg(not(target_os = "linux"))] - WaitId::__EatLifetime(_) => unreachable!(), - } -} - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -fn _waitid_all(options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(c::waitid( - c::P_ALL, - 0, - status.as_mut_ptr(), - options.bits() as _, - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -fn _waitid_pid(pid: Pid, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(c::waitid( - c::P_PID, - Pid::as_raw(Some(pid)) as _, - status.as_mut_ptr(), - options.bits() as _, - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -fn _waitid_pgid(pgid: Option<Pid>, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(c::waitid( - c::P_PGID, - Pid::as_raw(pgid) as _, - status.as_mut_ptr(), - options.bits() as _, - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -#[cfg(target_os = "linux")] -#[inline] -fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(c::waitid( - c::P_PIDFD, - fd.as_raw_fd() as _, - status.as_mut_ptr(), - options.bits() as _, - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -/// Convert a `siginfo_t` to a `WaitIdStatus`. -/// -/// # Safety -/// -/// The caller must ensure that `status` is initialized and that `waitid` -/// returned successfully. -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitIdStatus> { - let status = status.assume_init(); - // `si_pid` is supposedly the better way to check that the struct has been - // filled, e.g. the Linux manual page says about the `WNOHANG` case “zero - // out the si_pid field before the call and check for a nonzero value”. - // But e.g. NetBSD/OpenBSD don't have it exposed in the libc crate for now, - // and some platforms don't have it at all. For simplicity, always check - // `si_signo`. We have zero-initialized the whole struct, and all kernels - // should set `SIGCHLD` here. - if status.si_signo == 0 { - None - } else { - Some(WaitIdStatus(status)) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> { - unsafe { - let pid = ret_pid_t(c::getsid(Pid::as_raw(pid) as _))?; - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn setsid() -> io::Result<Pid> { - unsafe { - let pid = ret_c_int(c::setsid())?; - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(c::kill(pid.as_raw_nonzero().get(), sig.as_raw())) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { - ret(c::kill( - pid.as_raw_nonzero().get().wrapping_neg(), - sig.as_raw(), - )) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { - unsafe { ret(c::kill(0, sig.as_raw())) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn test_kill_process(pid: Pid) -> io::Result<()> { - unsafe { ret(c::kill(pid.as_raw_nonzero().get(), 0)) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn test_kill_process_group(pid: Pid) -> io::Result<()> { - unsafe { ret(c::kill(pid.as_raw_nonzero().get().wrapping_neg(), 0)) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn test_kill_current_process_group() -> io::Result<()> { - unsafe { ret(c::kill(0, 0)) } -} - -#[cfg(freebsdlike)] -#[inline] -pub(crate) unsafe fn procctl( - idtype: c::idtype_t, - id: c::id_t, - option: c::c_int, - data: *mut c::c_void, -) -> io::Result<()> { - ret(c::procctl(idtype, id, option, data)) -} - -#[cfg(target_os = "linux")] -pub(crate) fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { - syscall! { - fn pidfd_open( - pid: c::pid_t, - flags: c::c_uint - ) via SYS_pidfd_open -> c::c_int - } - unsafe { - ret_owned_fd(pidfd_open( - pid.as_raw_nonzero().get(), - bitflags_bits!(flags), - )) - } -} - -#[cfg(target_os = "linux")] -pub(crate) fn pidfd_send_signal(pidfd: BorrowedFd<'_>, sig: Signal) -> io::Result<()> { - syscall! { - fn pidfd_send_signal( - pid: c::pid_t, - sig: c::c_int, - info: *const c::siginfo_t, - flags: c::c_int - ) via SYS_pidfd_send_signal -> c::c_int - } - unsafe { - ret(pidfd_send_signal( - borrowed_fd(pidfd), - sig.as_raw(), - core::ptr::null(), - 0, - )) - } -} - -#[cfg(target_os = "linux")] -pub(crate) fn pidfd_getfd( - pidfd: BorrowedFd<'_>, - targetfd: RawFd, - flags: PidfdGetfdFlags, -) -> io::Result<OwnedFd> { - syscall! { - fn pidfd_getfd( - pidfd: c::c_int, - targetfd: c::c_int, - flags: c::c_uint - ) via SYS_pidfd_getfd -> c::c_int - } - unsafe { - ret_owned_fd(pidfd_getfd( - borrowed_fd(pidfd), - targetfd, - bitflags_bits!(flags), - )) - } -} - -#[cfg(target_os = "linux")] -pub(crate) fn pivot_root(new_root: &CStr, put_old: &CStr) -> io::Result<()> { - syscall! { - fn pivot_root( - new_root: *const c::c_char, - put_old: *const c::c_char - ) via SYS_pivot_root -> c::c_int - } - unsafe { ret(pivot_root(c_str(new_root), c_str(put_old))) } -} - -#[cfg(all(feature = "alloc", not(target_os = "wasi")))] -pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> { - let len = buf.len().try_into().map_err(|_| io::Errno::NOMEM)?; - - unsafe { ret_usize(c::getgroups(len, buf.as_mut_ptr().cast()) as isize) } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub(crate) fn fcntl_getlk(fd: BorrowedFd<'_>, lock: &Flock) -> io::Result<Option<Flock>> { - let mut curr_lock: c::flock = lock.as_raw(); - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_GETLK, &mut curr_lock))? }; - - // If no blocking lock is found, `fcntl(GETLK, ..)` sets `l_type` to - // `F_UNLCK`. - if curr_lock.l_type == c::F_UNLCK as _ { - Ok(None) - } else { - Ok(Some(unsafe { Flock::from_raw_unchecked(curr_lock) })) - } -} diff --git a/vendor/rustix/src/backend/libc/process/types.rs b/vendor/rustix/src/backend/libc/process/types.rs deleted file mode 100644 index 4771ddaf..00000000 --- a/vendor/rustix/src/backend/libc/process/types.rs +++ /dev/null @@ -1,139 +0,0 @@ -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::backend::c; - -/// A resource value for use with [`getrlimit`], [`setrlimit`], and -/// [`prlimit`]. -/// -/// [`getrlimit`]: crate::process::getrlimit -/// [`setrlimit`]: crate::process::setrlimit -/// [`prlimit`]: crate::process::prlimit -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(not(target_os = "l4re"), repr(u32))] -#[cfg_attr(target_os = "l4re", repr(u64))] -#[non_exhaustive] -pub enum Resource { - /// `RLIMIT_CPU` - Cpu = bitcast!(c::RLIMIT_CPU), - /// `RLIMIT_FSIZE` - Fsize = bitcast!(c::RLIMIT_FSIZE), - /// `RLIMIT_DATA` - Data = bitcast!(c::RLIMIT_DATA), - /// `RLIMIT_STACK` - Stack = bitcast!(c::RLIMIT_STACK), - /// `RLIMIT_CORE` - #[cfg(not(target_os = "haiku"))] - Core = bitcast!(c::RLIMIT_CORE), - /// `RLIMIT_RSS` - // "nto" has `RLIMIT_RSS`, but it has the same value as `RLIMIT_AS`. - #[cfg(not(any( - apple, - solarish, - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - )))] - Rss = bitcast!(c::RLIMIT_RSS), - /// `RLIMIT_NPROC` - #[cfg(not(any(solarish, target_os = "cygwin", target_os = "haiku")))] - Nproc = bitcast!(c::RLIMIT_NPROC), - /// `RLIMIT_NOFILE` - Nofile = bitcast!(c::RLIMIT_NOFILE), - /// `RLIMIT_MEMLOCK` - #[cfg(not(any(solarish, target_os = "aix", target_os = "cygwin", target_os = "haiku")))] - Memlock = bitcast!(c::RLIMIT_MEMLOCK), - /// `RLIMIT_AS` - #[cfg(not(target_os = "openbsd"))] - As = bitcast!(c::RLIMIT_AS), - /// `RLIMIT_LOCKS` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Locks = bitcast!(c::RLIMIT_LOCKS), - /// `RLIMIT_SIGPENDING` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Sigpending = bitcast!(c::RLIMIT_SIGPENDING), - /// `RLIMIT_MSGQUEUE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Msgqueue = bitcast!(c::RLIMIT_MSGQUEUE), - /// `RLIMIT_NICE` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Nice = bitcast!(c::RLIMIT_NICE), - /// `RLIMIT_RTPRIO` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Rtprio = bitcast!(c::RLIMIT_RTPRIO), - /// `RLIMIT_RTTIME` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Rttime = bitcast!(c::RLIMIT_RTTIME), -} - -#[cfg(apple)] -#[allow(non_upper_case_globals)] -impl Resource { - /// `RLIMIT_RSS` - pub const Rss: Self = Self::As; -} - -#[cfg(freebsdlike)] -pub type RawId = c::id_t; diff --git a/vendor/rustix/src/backend/libc/process/wait.rs b/vendor/rustix/src/backend/libc/process/wait.rs deleted file mode 100644 index 9f9810d7..00000000 --- a/vendor/rustix/src/backend/libc/process/wait.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::backend::c; - -pub(crate) use c::{ - WEXITSTATUS, WIFCONTINUED, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, -}; - -#[cfg(not(target_os = "horizon"))] -pub(crate) use c::{WCONTINUED, WUNTRACED}; - -#[cfg(not(any( - target_os = "cygwin", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) use c::{WEXITED, WNOWAIT, WSTOPPED}; diff --git a/vendor/rustix/src/backend/libc/pty/mod.rs b/vendor/rustix/src/backend/libc/pty/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/libc/pty/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/pty/syscalls.rs b/vendor/rustix/src/backend/libc/pty/syscalls.rs deleted file mode 100644 index 8405cfdc..00000000 --- a/vendor/rustix/src/backend/libc/pty/syscalls.rs +++ /dev/null @@ -1,118 +0,0 @@ -//! libc syscalls supporting `rustix::pty`. - -use crate::backend::c; -use crate::backend::conv::{borrowed_fd, ret}; -use crate::fd::BorrowedFd; -use crate::io; -#[cfg(all( - feature = "alloc", - any( - apple, - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" - ) -))] -use { - crate::ffi::{CStr, CString}, - crate::path::SMALL_PATH_BUFFER_SIZE, - alloc::borrow::ToOwned as _, - alloc::vec::Vec, -}; - -#[cfg(not(linux_kernel))] -use crate::{backend::conv::ret_owned_fd, fd::OwnedFd, pty::OpenptFlags}; - -#[cfg(not(linux_kernel))] -#[inline] -pub(crate) fn openpt(flags: OpenptFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::posix_openpt(flags.bits() as _)) } -} - -#[cfg(all( - feature = "alloc", - any( - apple, - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" - ) -))] -#[inline] -pub(crate) fn ptsname(fd: BorrowedFd<'_>, mut buffer: Vec<u8>) -> io::Result<CString> { - // This code would benefit from having a better way to read into - // uninitialized memory, but that requires `unsafe`. - buffer.clear(); - buffer.reserve(SMALL_PATH_BUFFER_SIZE); - buffer.resize(buffer.capacity(), 0_u8); - - loop { - // On platforms with `ptsname_r`, use it. - #[cfg(any(linux_like, target_os = "fuchsia", target_os = "illumos"))] - let r = unsafe { c::ptsname_r(borrowed_fd(fd), buffer.as_mut_ptr().cast(), buffer.len()) }; - - // FreeBSD 12 doesn't have `ptsname_r`. - #[cfg(target_os = "freebsd")] - let r = unsafe { - weak! { - fn ptsname_r( - c::c_int, - *mut c::c_char, - c::size_t - ) -> c::c_int - } - if let Some(func) = ptsname_r.get() { - func(borrowed_fd(fd), buffer.as_mut_ptr().cast(), buffer.len()) - } else { - c::ENOSYS - } - }; - - // macOS 10.13.4 has `ptsname_r`; use it if we have it, otherwise fall - // back to calling the underlying ioctl directly. - #[cfg(apple)] - let r = unsafe { - weak! { fn ptsname_r(c::c_int, *mut c::c_char, c::size_t) -> c::c_int } - - if let Some(libc_ptsname_r) = ptsname_r.get() { - libc_ptsname_r(borrowed_fd(fd), buffer.as_mut_ptr().cast(), buffer.len()) - } else { - // The size declared in the `TIOCPTYGNAME` macro in - // sys/ttycom.h is 128. - let mut name: [u8; 128] = [0_u8; 128]; - match c::ioctl(borrowed_fd(fd), c::TIOCPTYGNAME as _, &mut name) { - 0 => { - let len = CStr::from_ptr(name.as_ptr().cast()).to_bytes().len(); - core::ptr::copy_nonoverlapping(name.as_ptr(), buffer.as_mut_ptr(), len + 1); - 0 - } - _ => libc_errno::errno().0, - } - } - }; - - if r == 0 { - return Ok(unsafe { CStr::from_ptr(buffer.as_ptr().cast()).to_owned() }); - } - if r != c::ERANGE { - return Err(io::Errno::from_raw_os_error(r)); - } - - // Use `Vec` reallocation strategy to grow capacity exponentially. - buffer.reserve(1); - buffer.resize(buffer.capacity(), 0_u8); - } -} - -#[inline] -pub(crate) fn unlockpt(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::unlockpt(borrowed_fd(fd))) } -} - -#[cfg(not(linux_kernel))] -#[inline] -pub(crate) fn grantpt(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::grantpt(borrowed_fd(fd))) } -} diff --git a/vendor/rustix/src/backend/libc/rand/mod.rs b/vendor/rustix/src/backend/libc/rand/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/libc/rand/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/rand/syscalls.rs b/vendor/rustix/src/backend/libc/rand/syscalls.rs deleted file mode 100644 index ce17c6aa..00000000 --- a/vendor/rustix/src/backend/libc/rand/syscalls.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! libc syscalls supporting `rustix::rand`. - -#[cfg(linux_kernel)] -use {crate::backend::c, crate::backend::conv::ret_usize, crate::io, crate::rand::GetRandomFlags}; - -#[cfg(linux_kernel)] -pub(crate) unsafe fn getrandom(buf: (*mut u8, usize), flags: GetRandomFlags) -> io::Result<usize> { - // `getrandom` wasn't supported in glibc until 2.25. - weak_or_syscall! { - fn getrandom(buf: *mut c::c_void, buflen: c::size_t, flags: c::c_uint) via SYS_getrandom -> c::ssize_t - } - - ret_usize(getrandom(buf.0.cast(), buf.1, flags.bits())) -} diff --git a/vendor/rustix/src/backend/libc/rand/types.rs b/vendor/rustix/src/backend/libc/rand/types.rs deleted file mode 100644 index 46690b57..00000000 --- a/vendor/rustix/src/backend/libc/rand/types.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[cfg(linux_kernel)] -use crate::backend::c; -#[cfg(linux_kernel)] -use bitflags::bitflags; - -#[cfg(linux_kernel)] -bitflags! { - /// `GRND_*` flags for use with [`getrandom`]. - /// - /// [`getrandom`]: crate::rand::getrandom - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct GetRandomFlags: u32 { - /// `GRND_RANDOM` - const RANDOM = c::GRND_RANDOM; - /// `GRND_NONBLOCK` - const NONBLOCK = c::GRND_NONBLOCK; - /// `GRND_INSECURE` - const INSECURE = c::GRND_INSECURE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/shm/mod.rs b/vendor/rustix/src/backend/libc/shm/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/libc/shm/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/shm/syscalls.rs b/vendor/rustix/src/backend/libc/shm/syscalls.rs deleted file mode 100644 index e5d61ac6..00000000 --- a/vendor/rustix/src/backend/libc/shm/syscalls.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::ffi::CStr; - -use crate::backend::c; -use crate::backend::conv::{c_str, ret, ret_owned_fd}; -use crate::fd::OwnedFd; -use crate::fs::Mode; -use crate::{io, shm}; - -pub(crate) fn shm_open(name: &CStr, oflags: shm::OFlags, mode: Mode) -> io::Result<OwnedFd> { - // On this platforms, `mode_t` is `u16` and can't be passed directly to a - // variadic function. - #[cfg(apple)] - let mode: c::c_uint = mode.bits().into(); - - // Otherwise, cast to `mode_t` as that's what `open` is documented to take. - #[cfg(not(apple))] - let mode: c::mode_t = mode.bits() as _; - - unsafe { ret_owned_fd(c::shm_open(c_str(name), bitflags_bits!(oflags), mode)) } -} - -pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> { - unsafe { ret(c::shm_unlink(c_str(name))) } -} diff --git a/vendor/rustix/src/backend/libc/shm/types.rs b/vendor/rustix/src/backend/libc/shm/types.rs deleted file mode 100644 index 59f19b38..00000000 --- a/vendor/rustix/src/backend/libc/shm/types.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `O_*` constants for use with [`shm::open`]. - /// - /// [`shm::open`]: crate:shm::open - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ShmOFlags: u32 { - /// `O_CREAT` - #[doc(alias = "CREAT")] - const CREATE = bitcast!(c::O_CREAT); - - /// `O_EXCL` - const EXCL = bitcast!(c::O_EXCL); - - /// `O_RDONLY` - const RDONLY = bitcast!(c::O_RDONLY); - - /// `O_RDWR` - const RDWR = bitcast!(c::O_RDWR); - - /// `O_TRUNC` - const TRUNC = bitcast!(c::O_TRUNC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/libc/system/mod.rs b/vendor/rustix/src/backend/libc/system/mod.rs deleted file mode 100644 index bff7fd56..00000000 --- a/vendor/rustix/src/backend/libc/system/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/system/syscalls.rs b/vendor/rustix/src/backend/libc/system/syscalls.rs deleted file mode 100644 index 0e8a7b36..00000000 --- a/vendor/rustix/src/backend/libc/system/syscalls.rs +++ /dev/null @@ -1,162 +0,0 @@ -//! libc syscalls supporting `rustix::process`. - -use super::types::RawUname; -use crate::backend::c; -#[cfg(not(target_os = "wasi"))] -use crate::backend::conv::ret_infallible; -#[cfg(target_os = "linux")] -use crate::system::RebootCommand; -use core::mem::MaybeUninit; -#[cfg(linux_kernel)] -use { - crate::backend::conv::c_str, crate::fd::BorrowedFd, crate::ffi::CStr, crate::system::Sysinfo, -}; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use {crate::backend::conv::ret, crate::io}; - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::<RawUname>::uninit(); - unsafe { - let r = c::uname(uname.as_mut_ptr()); - - // On POSIX, `uname` is documented to return non-negative on success - // instead of the usual 0, though some specific systems do document - // that they always use zero allowing us to skip this check. - #[cfg(not(any(apple, freebsdlike, linux_like, target_os = "netbsd")))] - let r = core::cmp::min(r, 0); - - ret_infallible(r); - uname.assume_init() - } -} - -#[cfg(linux_kernel)] -pub(crate) fn sysinfo() -> Sysinfo { - let mut info = MaybeUninit::<Sysinfo>::uninit(); - unsafe { - ret_infallible(c::sysinfo(info.as_mut_ptr())); - info.assume_init() - } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { - unsafe { - ret(c::sethostname( - name.as_ptr().cast(), - name.len().try_into().map_err(|_| io::Errno::INVAL)?, - )) - } -} - -#[cfg(not(any( - target_os = "android", - target_os = "cygwin", - target_os = "emscripten", - target_os = "espidf", - target_os = "illumos", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "solaris", - target_os = "vita", - target_os = "wasi", -)))] -pub(crate) fn setdomainname(name: &[u8]) -> io::Result<()> { - unsafe { - ret(c::setdomainname( - name.as_ptr().cast(), - name.len().try_into().map_err(|_| io::Errno::INVAL)?, - )) - } -} - -// <https://github.com/rust-lang/libc/pull/4212> -#[cfg(target_os = "android")] -pub(crate) fn setdomainname(name: &[u8]) -> io::Result<()> { - syscall! { - fn setdomainname( - name: *const c::c_char, - len: c::size_t - ) via SYS_setdomainname -> c::c_int - } - - unsafe { - ret(setdomainname( - name.as_ptr().cast(), - name.len().try_into().map_err(|_| io::Errno::INVAL)?, - )) - } -} - -#[cfg(target_os = "linux")] -pub(crate) fn reboot(cmd: RebootCommand) -> io::Result<()> { - unsafe { ret(c::reboot(cmd as i32)) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn init_module(image: &[u8], param_values: &CStr) -> io::Result<()> { - syscall! { - fn init_module( - module_image: *const c::c_void, - len: c::c_ulong, - param_values: *const c::c_char - ) via SYS_init_module -> c::c_int - } - - unsafe { - ret(init_module( - image.as_ptr().cast(), - image.len() as _, - c_str(param_values), - )) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn finit_module( - fd: BorrowedFd<'_>, - param_values: &CStr, - flags: c::c_int, -) -> io::Result<()> { - use crate::fd::AsRawFd as _; - - syscall! { - fn finit_module( - fd: c::c_int, - param_values: *const c::c_char, - flags: c::c_int - ) via SYS_finit_module -> c::c_int - } - - unsafe { ret(finit_module(fd.as_raw_fd(), c_str(param_values), flags)) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn delete_module(name: &CStr, flags: c::c_int) -> io::Result<()> { - syscall! { - fn delete_module( - name: *const c::c_char, - flags: c::c_int - ) via SYS_delete_module -> c::c_int - } - unsafe { ret(delete_module(c_str(name), flags)) } -} diff --git a/vendor/rustix/src/backend/libc/system/types.rs b/vendor/rustix/src/backend/libc/system/types.rs deleted file mode 100644 index 731e89be..00000000 --- a/vendor/rustix/src/backend/libc/system/types.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::backend::c; - -/// `sysinfo` -#[cfg(linux_kernel)] -pub type Sysinfo = c::sysinfo; - -#[cfg(not(target_os = "wasi"))] -pub(crate) type RawUname = c::utsname; diff --git a/vendor/rustix/src/backend/libc/termios/mod.rs b/vendor/rustix/src/backend/libc/termios/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/libc/termios/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/termios/syscalls.rs b/vendor/rustix/src/backend/libc/termios/syscalls.rs deleted file mode 100644 index e27f0b2e..00000000 --- a/vendor/rustix/src/backend/libc/termios/syscalls.rs +++ /dev/null @@ -1,518 +0,0 @@ -//! libc syscalls supporting `rustix::termios`. -//! -//! # Safety -//! -//! See the `rustix::backend::syscalls` module documentation for details. - -use crate::backend::c; -#[cfg(not(target_os = "wasi"))] -use crate::backend::conv::ret_pid_t; -use crate::backend::conv::{borrowed_fd, ret}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::ffi::CStr; -#[cfg(any( - not(target_os = "espidf"), - not(any(target_os = "fuchsia", target_os = "wasi")) -))] -use core::mem::MaybeUninit; -#[cfg(not(target_os = "wasi"))] -use {crate::io, crate::pid::Pid}; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -use { - crate::termios::{Action, OptionalActions, QueueSelector, Termios, Winsize}, - crate::utils::as_mut_ptr, -}; - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { - // On Linux, use `TCGETS2`, and fall back to `TCGETS` if needed. - #[cfg(linux_kernel)] - { - use crate::termios::{ControlModes, InputModes, LocalModes, OutputModes, SpecialCodes}; - - let mut termios2 = MaybeUninit::<c::termios2>::uninit(); - let ptr = termios2.as_mut_ptr(); - - // SAFETY: This invokes the `TCGETS2` ioctl, which initializes the full - // `Termios` structure. - let termios2 = unsafe { - match ret(c::ioctl(borrowed_fd(fd), c::TCGETS2 as _, ptr)) { - Ok(()) => {} - - // A `NOTTY` or `ACCESS` might mean the OS doesn't support - // `TCGETS2`, for example a seccomp environment or WSL that - // only knows about `TCGETS`. Fall back to the old `TCGETS`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - Err(io::Errno::NOTTY) | Err(io::Errno::ACCESS) => { - tcgetattr_fallback(fd, &mut termios2)? - } - - Err(err) => return Err(err), - } - - // Now all the fields are set. - termios2.assume_init() - }; - - // Convert from the Linux `termios2` to our `Termios`. - let mut result = Termios { - input_modes: InputModes::from_bits_retain(termios2.c_iflag), - output_modes: OutputModes::from_bits_retain(termios2.c_oflag), - control_modes: ControlModes::from_bits_retain(termios2.c_cflag), - local_modes: LocalModes::from_bits_retain(termios2.c_lflag), - line_discipline: termios2.c_line, - special_codes: SpecialCodes(Default::default()), - - // On PowerPC musl targets, `c_ispeed`/`c_ospeed` are named - // `__c_ispeed`/`__c_ospeed`. - #[cfg(not(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - )))] - input_speed: termios2.c_ispeed, - #[cfg(not(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - )))] - output_speed: termios2.c_ospeed, - #[cfg(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - ))] - input_speed: termios2.__c_ispeed, - #[cfg(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - ))] - output_speed: termios2.__c_ospeed, - }; - - // Copy in the control codes, since libc's `c_cc` array may have a - // different length from the ioctl's. - let nccs = termios2.c_cc.len(); - result.special_codes.0[..nccs].copy_from_slice(&termios2.c_cc); - - Ok(result) - } - - #[cfg(not(linux_kernel))] - unsafe { - let mut result = MaybeUninit::<Termios>::uninit(); - - // `result` is a `Termios` which starts with the same layout as - // `c::termios`, so we can cast the pointer. - ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr().cast()))?; - - Ok(result.assume_init()) - } -} - -/// Implement `tcgetattr` using the old `TCGETS` ioctl. -#[cfg(all( - linux_kernel, - not(any(target_arch = "powerpc", target_arch = "powerpc64")) -))] -#[cold] -fn tcgetattr_fallback( - fd: BorrowedFd<'_>, - termios: &mut MaybeUninit<c::termios2>, -) -> io::Result<()> { - use crate::termios::speed; - use core::ptr::{addr_of, addr_of_mut}; - - // SAFETY: This invokes the `TCGETS` ioctl, which, if it succeeds, - // initializes the `Termios` structure except for the `input_speed` and - // `output_speed` fields, which we manually initialize before forming a - // reference to the full `Termios`. - unsafe { - let ptr = termios.as_mut_ptr(); - - // Do the old `TCGETS` call, which doesn't initialize `input_speed` or - // `output_speed`. - ret(c::ioctl(borrowed_fd(fd), c::TCGETS as _, ptr))?; - - // Read the `control_modes` field without forming a reference to the - // `Termios` because it isn't fully initialized yet. - let control_modes = addr_of!((*ptr).c_cflag).read(); - - // Infer `output_speed`. - let encoded_out = control_modes & c::CBAUD; - let output_speed = match speed::decode(encoded_out) { - Some(output_speed) => output_speed, - None => return Err(io::Errno::RANGE), - }; - addr_of_mut!((*ptr).c_ospeed).write(output_speed); - - // Infer `input_speed`. For input speeds, `B0` is special-cased to mean - // the input speed is the same as the output speed. - let encoded_in = (control_modes & c::CIBAUD) >> c::IBSHIFT; - let input_speed = if encoded_in == c::B0 { - output_speed - } else { - match speed::decode(encoded_in) { - Some(input_speed) => input_speed, - None => return Err(io::Errno::RANGE), - } - }; - addr_of_mut!((*ptr).c_ispeed).write(input_speed); - } - - Ok(()) -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { - unsafe { - let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; - - // This doesn't appear to be documented, but on Linux, it appears - // `tcsetpgrp` can succeed and set the pid to 0 if we pass it a - // pseudo-terminal device fd. For now, translate it into `OPNOTSUPP`. - #[cfg(linux_kernel)] - if pid == 0 { - return Err(io::Errno::OPNOTSUPP); - } - - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { - unsafe { ret(c::tcsetpgrp(borrowed_fd(fd), pid.as_raw_nonzero().get())) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn tcsetattr( - fd: BorrowedFd<'_>, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - // On Linux, use `TCSETS2`, and fall back to `TCSETS` if needed. - #[cfg(linux_kernel)] - { - use crate::termios::speed; - - let output_speed = termios.output_speed(); - let input_speed = termios.input_speed(); - - let mut termios2 = c::termios2 { - c_iflag: termios.input_modes.bits(), - c_oflag: termios.output_modes.bits(), - c_cflag: termios.control_modes.bits(), - c_lflag: termios.local_modes.bits(), - c_line: termios.line_discipline, - c_cc: Default::default(), - - // On PowerPC musl targets, `c_ispeed`/`c_ospeed` are named - // `__c_ispeed`/`__c_ospeed`. - #[cfg(not(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - )))] - c_ispeed: input_speed, - #[cfg(not(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - )))] - c_ospeed: output_speed, - #[cfg(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - ))] - __c_ispeed: input_speed, - #[cfg(all( - target_env = "musl", - any(target_arch = "powerpc", target_arch = "powerpc64") - ))] - __c_ospeed: output_speed, - }; - - // Ensure that our input and output speeds are set, as `libc` - // routines don't always support setting these separately. - termios2.c_cflag &= !c::CBAUD; - termios2.c_cflag |= speed::encode(output_speed).unwrap_or(c::BOTHER); - termios2.c_cflag &= !c::CIBAUD; - termios2.c_cflag |= speed::encode(input_speed).unwrap_or(c::BOTHER) << c::IBSHIFT; - - // Copy in the control codes, since libc's `c_cc` array may have a - // different length from the ioctl's. - let nccs = termios2.c_cc.len(); - termios2 - .c_cc - .copy_from_slice(&termios.special_codes.0[..nccs]); - - // Translate from `optional_actions` into a `TCSETS2` ioctl request - // code. On MIPS, `optional_actions` has `TCSETS` added to it. - let request = c::TCSETS2 as c::c_ulong - + if cfg!(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) { - optional_actions as c::c_ulong - c::TCSETS as c::c_ulong - } else { - optional_actions as c::c_ulong - }; - - // SAFETY: This invokes the `TCSETS2` ioctl. - unsafe { - match ret(c::ioctl(borrowed_fd(fd), request as _, &termios2)) { - Ok(()) => Ok(()), - - // Similar to `tcgetattr_fallback`, `NOTTY` or `ACCESS` might - // mean the OS doesn't support `TCSETS2`. Fall back to the old - // `TCSETS`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - Err(io::Errno::NOTTY) | Err(io::Errno::ACCESS) => { - tcsetattr_fallback(fd, optional_actions, &termios2) - } - - Err(err) => Err(err), - } - } - } - - #[cfg(not(linux_kernel))] - unsafe { - ret(c::tcsetattr( - borrowed_fd(fd), - optional_actions as _, - crate::utils::as_ptr(termios).cast(), - )) - } -} - -/// Implement `tcsetattr` using the old `TCSETS` ioctl. -#[cfg(all( - linux_kernel, - not(any(target_arch = "powerpc", target_arch = "powerpc64")) -))] -#[cold] -fn tcsetattr_fallback( - fd: BorrowedFd<'_>, - optional_actions: OptionalActions, - termios2: &c::termios2, -) -> io::Result<()> { - // `TCSETS` silently accepts `BOTHER` in `c_cflag` even though it doesn't - // read `c_ispeed`/`c_ospeed`, so detect this case and fail if needed. - let encoded_out = termios2.c_cflag & c::CBAUD; - let encoded_in = (termios2.c_cflag & c::CIBAUD) >> c::IBSHIFT; - if encoded_out == c::BOTHER || encoded_in == c::BOTHER { - return Err(io::Errno::RANGE); - } - - // Translate from `optional_actions` into a `TCSETS` ioctl request code. On - // MIPS, `optional_actions` already has `TCSETS` added to it. - let request = if cfg!(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) { - optional_actions as c::c_ulong - } else { - optional_actions as c::c_ulong + c::TCSETS as c::c_ulong - }; - - // SAFETY: This invokes the `TCSETS` ioctl. - unsafe { ret(c::ioctl(borrowed_fd(fd), request as _, termios2)) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn tcsendbreak(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::tcsendbreak(borrowed_fd(fd), 0)) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn tcdrain(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::tcdrain(borrowed_fd(fd))) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn tcflush(fd: BorrowedFd<'_>, queue_selector: QueueSelector) -> io::Result<()> { - unsafe { ret(c::tcflush(borrowed_fd(fd), queue_selector as _)) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub(crate) fn tcflow(fd: BorrowedFd<'_>, action: Action) -> io::Result<()> { - unsafe { ret(c::tcflow(borrowed_fd(fd), action as _)) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn tcgetsid(fd: BorrowedFd<'_>) -> io::Result<Pid> { - unsafe { - let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?; - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "wasi")))] -pub(crate) fn tcsetwinsize(fd: BorrowedFd<'_>, winsize: Winsize) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCSWINSZ, &winsize)) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "wasi")))] -pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result<Winsize> { - unsafe { - let mut buf = MaybeUninit::<Winsize>::uninit(); - ret(c::ioctl( - borrowed_fd(fd), - c::TIOCGWINSZ.into(), - buf.as_mut_ptr(), - ))?; - Ok(buf.assume_init()) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "nto", target_os = "wasi")))] -#[inline] -pub(crate) fn set_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - #[cfg(bsd)] - let encoded_speed = arbitrary_speed; - - #[cfg(not(bsd))] - let encoded_speed = match crate::termios::speed::encode(arbitrary_speed) { - Some(encoded_speed) => encoded_speed, - #[cfg(linux_kernel)] - None => c::BOTHER, - #[cfg(not(linux_kernel))] - None => return Err(io::Errno::INVAL), - }; - - #[cfg(not(linux_kernel))] - unsafe { - ret(c::cfsetspeed( - as_mut_ptr(termios).cast(), - encoded_speed.into(), - )) - } - - // Linux libc implementations don't support arbitrary speeds, so we encode - // the speed manually. - #[cfg(linux_kernel)] - { - use crate::termios::ControlModes; - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD | c::CIBAUD); - termios.control_modes |= - ControlModes::from_bits_retain(encoded_speed | (encoded_speed << c::IBSHIFT)); - - termios.input_speed = arbitrary_speed; - termios.output_speed = arbitrary_speed; - - Ok(()) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn set_output_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - #[cfg(bsd)] - let encoded_speed = arbitrary_speed; - - #[cfg(not(bsd))] - let encoded_speed = match crate::termios::speed::encode(arbitrary_speed) { - Some(encoded_speed) => encoded_speed, - #[cfg(linux_kernel)] - None => c::BOTHER, - #[cfg(not(linux_kernel))] - None => return Err(io::Errno::INVAL), - }; - - #[cfg(not(linux_kernel))] - unsafe { - ret(c::cfsetospeed( - as_mut_ptr(termios).cast(), - encoded_speed.into(), - )) - } - - // Linux libc implementations don't support arbitrary speeds or setting the - // input and output speeds separately, so we encode the speed manually. - #[cfg(linux_kernel)] - { - use crate::termios::ControlModes; - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD); - termios.control_modes |= ControlModes::from_bits_retain(encoded_speed); - - termios.output_speed = arbitrary_speed; - - Ok(()) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -pub(crate) fn set_input_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - #[cfg(bsd)] - let encoded_speed = arbitrary_speed; - - #[cfg(not(bsd))] - let encoded_speed = match crate::termios::speed::encode(arbitrary_speed) { - Some(encoded_speed) => encoded_speed, - #[cfg(linux_kernel)] - None => c::BOTHER, - #[cfg(not(linux_kernel))] - None => return Err(io::Errno::INVAL), - }; - - #[cfg(not(linux_kernel))] - unsafe { - ret(c::cfsetispeed( - as_mut_ptr(termios).cast(), - encoded_speed.into(), - )) - } - - // Linux libc implementations don't support arbitrary speeds or setting the - // input and output speeds separately, so we encode the speed manually. - #[cfg(linux_kernel)] - { - use crate::termios::ControlModes; - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CIBAUD); - termios.control_modes |= ControlModes::from_bits_retain(encoded_speed << c::IBSHIFT); - - termios.input_speed = arbitrary_speed; - - Ok(()) - } -} - -#[cfg(not(any(target_os = "espidf", target_os = "nto", target_os = "wasi")))] -#[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - unsafe { c::cfmakeraw(as_mut_ptr(termios).cast()) } -} - -pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { - // Use the return value of `isatty` alone. We don't check `errno` because - // we return `bool` rather than `io::Result<bool>`, because we assume - // `BorrowedFd` protects us from `EBADF`, and any other reasonably - // anticipated `errno` value would end up interpreted as “assume it's not a - // terminal” anyway. - unsafe { c::isatty(borrowed_fd(fd)) != 0 } -} - -#[cfg(feature = "alloc")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> { - unsafe { - // `ttyname_r` returns its error status rather than using `errno`. - match c::ttyname_r(borrowed_fd(dirfd), buf.as_mut_ptr().cast(), buf.len()) { - 0 => Ok(CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len()), - err => Err(io::Errno::from_raw_os_error(err)), - } - } -} diff --git a/vendor/rustix/src/backend/libc/termios/types.rs b/vendor/rustix/src/backend/libc/termios/types.rs deleted file mode 100644 index 4b0d29f5..00000000 --- a/vendor/rustix/src/backend/libc/termios/types.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! Types for the `termios` module. - -#![allow(non_camel_case_types)] - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -use crate::ffi; - -// We don't want to use `tcflag_t` directly so we don't expose libc -// publicly. Redox uses `u32`, apple uses `c_ulong`, everything else -// seems to use `c_uint`. - -#[cfg(apple)] -pub type tcflag_t = ffi::c_ulong; -#[cfg(target_os = "redox")] -pub type tcflag_t = u32; -#[cfg(not(any(apple, target_os = "espidf", target_os = "redox", target_os = "wasi")))] -pub type tcflag_t = ffi::c_uint; diff --git a/vendor/rustix/src/backend/libc/thread/cpu_set.rs b/vendor/rustix/src/backend/libc/thread/cpu_set.rs deleted file mode 100644 index 30473b70..00000000 --- a/vendor/rustix/src/backend/libc/thread/cpu_set.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Rust implementation of the `CPU_*` macro API. - -#![allow(non_snake_case)] - -use super::types::{RawCpuSet, CPU_SETSIZE}; -use crate::backend::c; - -#[inline] -pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { - assert!( - cpu < CPU_SETSIZE, - "cpu out of bounds: the cpu max is {} but the cpu is {}", - CPU_SETSIZE, - cpu - ); - unsafe { c::CPU_SET(cpu, cpuset) } -} - -#[inline] -pub(crate) fn CPU_ZERO(cpuset: &mut RawCpuSet) { - unsafe { c::CPU_ZERO(cpuset) } -} - -#[inline] -pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { - assert!( - cpu < CPU_SETSIZE, - "cpu out of bounds: the cpu max is {} but the cpu is {}", - CPU_SETSIZE, - cpu - ); - unsafe { c::CPU_CLR(cpu, cpuset) } -} - -#[inline] -pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { - assert!( - cpu < CPU_SETSIZE, - "cpu out of bounds: the cpu max is {} but the cpu is {}", - CPU_SETSIZE, - cpu - ); - unsafe { c::CPU_ISSET(cpu, cpuset) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { - unsafe { c::CPU_COUNT(cpuset).try_into().unwrap() } -} - -#[inline] -pub(crate) fn CPU_EQUAL(this: &RawCpuSet, that: &RawCpuSet) -> bool { - #[cfg(any(linux_like, target_os = "fuchsia", target_os = "hurd"))] - unsafe { - c::CPU_EQUAL(this, that) - } - - #[cfg(not(any(linux_like, target_os = "fuchsia", target_os = "hurd")))] - unsafe { - for i in 0..c::CPU_SETSIZE as usize { - if c::CPU_ISSET(i, this) != c::CPU_ISSET(i, that) { - return false; - } - } - true - } -} diff --git a/vendor/rustix/src/backend/libc/thread/futex.rs b/vendor/rustix/src/backend/libc/thread/futex.rs deleted file mode 100644 index 5e836a9a..00000000 --- a/vendor/rustix/src/backend/libc/thread/futex.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::backend::c; - -bitflags::bitflags! { - /// `FUTEX_*` flags for use with the functions in [`futex`]. - /// - /// [`futex`]: mod@crate::thread::futex - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Flags: u32 { - /// `FUTEX_PRIVATE_FLAG` - const PRIVATE = bitcast!(c::FUTEX_PRIVATE_FLAG); - /// `FUTEX_CLOCK_REALTIME` - const CLOCK_REALTIME = bitcast!(c::FUTEX_CLOCK_REALTIME); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `FUTEX2_*` flags for use with the functions in [`Waitv`]. - /// - /// Not to be confused with [`WaitvFlags`], which is passed as an argument - /// to the `waitv` function. - /// - /// [`Waitv`]: crate::thread::futex::Waitv - /// [`WaitvFlags`]: crate::thread::futex::WaitvFlags - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitFlags: u32 { - /// `FUTEX_U8` - const SIZE_U8 = linux_raw_sys::general::FUTEX2_SIZE_U8; - /// `FUTEX_U16` - const SIZE_U16 = linux_raw_sys::general::FUTEX2_SIZE_U16; - /// `FUTEX_U32` - const SIZE_U32 = linux_raw_sys::general::FUTEX2_SIZE_U32; - /// `FUTEX_U64` - const SIZE_U64 = linux_raw_sys::general::FUTEX2_SIZE_U64; - /// `FUTEX_SIZE_MASK` - const SIZE_MASK = linux_raw_sys::general::FUTEX2_SIZE_MASK; - - /// `FUTEX2_NUMA` - const NUMA = linux_raw_sys::general::FUTEX2_NUMA; - - /// `FUTEX2_PRIVATE` - const PRIVATE = linux_raw_sys::general::FUTEX2_PRIVATE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `FUTEX_*` operations for use with the futex syscall wrappers. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub(crate) enum Operation { - /// `FUTEX_WAIT` - Wait = bitcast!(c::FUTEX_WAIT), - /// `FUTEX_WAKE` - Wake = bitcast!(c::FUTEX_WAKE), - /// `FUTEX_FD` - Fd = bitcast!(c::FUTEX_FD), - /// `FUTEX_REQUEUE` - Requeue = bitcast!(c::FUTEX_REQUEUE), - /// `FUTEX_CMP_REQUEUE` - CmpRequeue = bitcast!(c::FUTEX_CMP_REQUEUE), - /// `FUTEX_WAKE_OP` - WakeOp = bitcast!(c::FUTEX_WAKE_OP), - /// `FUTEX_LOCK_PI` - LockPi = bitcast!(c::FUTEX_LOCK_PI), - /// `FUTEX_UNLOCK_PI` - UnlockPi = bitcast!(c::FUTEX_UNLOCK_PI), - /// `FUTEX_TRYLOCK_PI` - TrylockPi = bitcast!(c::FUTEX_TRYLOCK_PI), - /// `FUTEX_WAIT_BITSET` - WaitBitset = bitcast!(c::FUTEX_WAIT_BITSET), - /// `FUTEX_WAKE_BITSET` - WakeBitset = bitcast!(c::FUTEX_WAKE_BITSET), - /// `FUTEX_WAIT_REQUEUE_PI` - WaitRequeuePi = bitcast!(c::FUTEX_WAIT_REQUEUE_PI), - /// `FUTEX_CMP_REQUEUE_PI` - CmpRequeuePi = bitcast!(c::FUTEX_CMP_REQUEUE_PI), - /// `FUTEX_LOCK_PI2` - LockPi2 = bitcast!(c::FUTEX_LOCK_PI2), -} - -/// `FUTEX_WAITERS` -pub const WAITERS: u32 = linux_raw_sys::general::FUTEX_WAITERS; - -/// `FUTEX_OWNER_DIED` -pub const OWNER_DIED: u32 = linux_raw_sys::general::FUTEX_OWNER_DIED; diff --git a/vendor/rustix/src/backend/libc/thread/mod.rs b/vendor/rustix/src/backend/libc/thread/mod.rs deleted file mode 100644 index ea2bfd71..00000000 --- a/vendor/rustix/src/backend/libc/thread/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -pub(crate) mod cpu_set; -#[cfg(linux_kernel)] -pub(crate) mod futex; -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/thread/syscalls.rs b/vendor/rustix/src/backend/libc/thread/syscalls.rs deleted file mode 100644 index 9198a7fb..00000000 --- a/vendor/rustix/src/backend/libc/thread/syscalls.rs +++ /dev/null @@ -1,780 +0,0 @@ -//! libc syscalls supporting `rustix::thread`. - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -use super::types::RawCpuSet; -use crate::backend::c; -use crate::backend::conv::ret; -use crate::io; -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -use crate::pid::Pid; -#[cfg(not(any( - apple, - freebsdlike, - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use crate::thread::ClockId; -#[cfg(linux_kernel)] -use crate::thread::{Cpuid, MembarrierCommand, MembarrierQuery}; -#[cfg(not(target_os = "redox"))] -use crate::thread::{NanosleepRelativeResult, Timespec}; -#[cfg(all(target_env = "gnu", fix_y2038))] -use crate::timespec::LibcTimespec; -#[cfg(not(fix_y2038))] -use crate::timespec::{as_libc_timespec_mut_ptr, as_libc_timespec_ptr}; -#[cfg(linux_kernel)] -use crate::utils::option_as_ptr; -use core::mem::MaybeUninit; -#[cfg(linux_kernel)] -use core::sync::atomic::AtomicU32; -#[cfg(linux_kernel)] -use { - crate::backend::conv::{borrowed_fd, ret_c_int, ret_u32, ret_usize}, - crate::fd::BorrowedFd, - crate::thread::futex, - crate::utils::as_mut_ptr, -}; - -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __clock_nanosleep_time64(c::clockid_t, c::c_int, *const LibcTimespec, *mut LibcTimespec) -> c::c_int); -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __nanosleep64(*const LibcTimespec, *mut LibcTimespec) -> c::c_int); - -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "haiku", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - // Old 32-bit version: libc has `clock_nanosleep` but it is not y2038 safe - // by default. But there may be a `__clock_nanosleep_time64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { - let flags = 0; - let mut remain = MaybeUninit::<LibcTimespec>::uninit(); - - unsafe { - return match libc_clock_nanosleep( - id as c::clockid_t, - flags, - &request.clone().into(), - remain.as_mut_ptr(), - ) { - 0 => NanosleepRelativeResult::Ok, - err if err == io::Errno::INTR.0 => { - NanosleepRelativeResult::Interrupted(remain.assume_init().into()) - } - err => NanosleepRelativeResult::Err(io::Errno(err)), - }; - } - } - - clock_nanosleep_relative_old(id, request) - } - - // Main version: libc is y2038 safe and has `clock_nanosleep`. - #[cfg(not(fix_y2038))] - unsafe { - let flags = 0; - let mut remain = MaybeUninit::<Timespec>::uninit(); - - match c::clock_nanosleep( - id as c::clockid_t, - flags, - as_libc_timespec_ptr(request), - as_libc_timespec_mut_ptr(&mut remain), - ) { - 0 => NanosleepRelativeResult::Ok, - err if err == io::Errno::INTR.0 => { - NanosleepRelativeResult::Interrupted(remain.assume_init()) - } - err => NanosleepRelativeResult::Err(io::Errno(err)), - } - } -} - -#[cfg(all( - fix_y2038, - not(any( - apple, - target_os = "emscripten", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )) -))] -fn clock_nanosleep_relative_old( - id: crate::clockid::ClockId, - request: &Timespec, -) -> NanosleepRelativeResult { - let tv_sec = match request.tv_sec.try_into() { - Ok(tv_sec) => tv_sec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), - }; - let tv_nsec = match request.tv_nsec.try_into() { - Ok(tv_nsec) => tv_nsec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::INVAL), - }; - let old_request = c::timespec { tv_sec, tv_nsec }; - let mut old_remain = MaybeUninit::<c::timespec>::uninit(); - let flags = 0; - - unsafe { - match c::clock_nanosleep( - id as c::clockid_t, - flags, - &old_request, - old_remain.as_mut_ptr(), - ) { - 0 => NanosleepRelativeResult::Ok, - err if err == io::Errno::INTR.0 => { - let old_remain = old_remain.assume_init(); - let remain = Timespec { - tv_sec: old_remain.tv_sec.into(), - tv_nsec: old_remain.tv_nsec.into(), - }; - NanosleepRelativeResult::Interrupted(remain) - } - err => NanosleepRelativeResult::Err(io::Errno(err)), - } - } -} - -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "haiku", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { - // Old 32-bit version: libc has `clock_nanosleep` but it is not y2038 safe - // by default. But there may be a `__clock_nanosleep_time64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { - let flags = c::TIMER_ABSTIME; - unsafe { - return match libc_clock_nanosleep( - id as c::clockid_t, - flags, - &request.clone().into(), - core::ptr::null_mut(), - ) { - 0 => Ok(()), - err => Err(io::Errno(err)), - }; - } - } - - clock_nanosleep_absolute_old(id, request) - } - - // Main version: libc is y2038 safe and has `clock_nanosleep`. - #[cfg(not(fix_y2038))] - { - let flags = c::TIMER_ABSTIME; - - match unsafe { - c::clock_nanosleep( - id as c::clockid_t, - flags as _, - as_libc_timespec_ptr(request), - core::ptr::null_mut(), - ) - } { - 0 => Ok(()), - err => Err(io::Errno(err)), - } - } -} - -#[cfg(all( - fix_y2038, - not(any( - apple, - target_os = "emscripten", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )) -))] -fn clock_nanosleep_absolute_old(id: crate::clockid::ClockId, request: &Timespec) -> io::Result<()> { - let flags = c::TIMER_ABSTIME; - - let old_request = c::timespec { - tv_sec: request.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: request.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - match unsafe { - c::clock_nanosleep( - id as c::clockid_t, - flags, - &old_request, - core::ptr::null_mut(), - ) - } { - 0 => Ok(()), - err => Err(io::Errno(err)), - } -} - -#[cfg(not(target_os = "redox"))] -#[inline] -pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { - // Old 32-bit version: libc has `nanosleep` but it is not y2038 safe by - // default. But there may be a `__nanosleep64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_nanosleep) = __nanosleep64.get() { - let mut remain = MaybeUninit::<LibcTimespec>::uninit(); - unsafe { - return match ret(libc_nanosleep(&request.clone().into(), remain.as_mut_ptr())) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => { - NanosleepRelativeResult::Interrupted(remain.assume_init().into()) - } - Err(err) => NanosleepRelativeResult::Err(err), - }; - } - } - - nanosleep_old(request) - } - - // Main version: libc is y2038 safe and has `nanosleep`. - #[cfg(not(fix_y2038))] - unsafe { - let mut remain = MaybeUninit::<Timespec>::uninit(); - - match ret(c::nanosleep( - as_libc_timespec_ptr(request), - as_libc_timespec_mut_ptr(&mut remain), - )) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(remain.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(fix_y2038)] -fn nanosleep_old(request: &Timespec) -> NanosleepRelativeResult { - let tv_sec = match request.tv_sec.try_into() { - Ok(tv_sec) => tv_sec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), - }; - let tv_nsec = match request.tv_nsec.try_into() { - Ok(tv_nsec) => tv_nsec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::INVAL), - }; - let old_request = c::timespec { tv_sec, tv_nsec }; - let mut old_remain = MaybeUninit::<c::timespec>::uninit(); - - unsafe { - match ret(c::nanosleep(&old_request, old_remain.as_mut_ptr())) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => { - let old_remain = old_remain.assume_init(); - let remain = Timespec { - tv_sec: old_remain.tv_sec.into(), - tv_nsec: old_remain.tv_nsec.into(), - }; - NanosleepRelativeResult::Interrupted(remain) - } - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(linux_kernel)] -#[inline] -#[must_use] -pub(crate) fn gettid() -> Pid { - // `gettid` wasn't supported in glibc until 2.30, and musl until 1.2.2, - // so use `syscall`. - // <https://sourceware.org/bugzilla/show_bug.cgi?id=6399#c62> - weak_or_syscall! { - fn gettid() via SYS_gettid -> c::pid_t - } - - unsafe { - let tid = gettid(); - Pid::from_raw_unchecked(tid) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn setns(fd: BorrowedFd<'_>, nstype: c::c_int) -> io::Result<c::c_int> { - // `setns` wasn't supported in glibc until 2.14, and musl until 0.9.5, - // so use `syscall`. - weak_or_syscall! { - fn setns(fd: c::c_int, nstype: c::c_int) via SYS_setns -> c::c_int - } - - unsafe { ret_c_int(setns(borrowed_fd(fd), nstype)) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn unshare(flags: crate::thread::UnshareFlags) -> io::Result<()> { - unsafe { ret(c::unshare(flags.bits() as i32)) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn capget( - header: &mut linux_raw_sys::general::__user_cap_header_struct, - data: &mut [MaybeUninit<linux_raw_sys::general::__user_cap_data_struct>], -) -> io::Result<()> { - syscall! { - fn capget( - hdrp: *mut linux_raw_sys::general::__user_cap_header_struct, - data: *mut linux_raw_sys::general::__user_cap_data_struct - ) via SYS_capget -> c::c_int - } - - unsafe { - ret(capget( - as_mut_ptr(header), - data.as_mut_ptr() - .cast::<linux_raw_sys::general::__user_cap_data_struct>(), - )) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn capset( - header: &mut linux_raw_sys::general::__user_cap_header_struct, - data: &[linux_raw_sys::general::__user_cap_data_struct], -) -> io::Result<()> { - syscall! { - fn capset( - hdrp: *mut linux_raw_sys::general::__user_cap_header_struct, - data: *const linux_raw_sys::general::__user_cap_data_struct - ) via SYS_capset -> c::c_int - } - - unsafe { ret(capset(as_mut_ptr(header), data.as_ptr())) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn setuid_thread(uid: crate::ugid::Uid) -> io::Result<()> { - syscall! { - fn setuid(uid: c::uid_t) via SYS_setuid -> c::c_int - } - - unsafe { ret(setuid(uid.as_raw())) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn setresuid_thread( - ruid: crate::ugid::Uid, - euid: crate::ugid::Uid, - suid: crate::ugid::Uid, -) -> io::Result<()> { - #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))] - const SYS: c::c_long = c::SYS_setresuid32 as c::c_long; - #[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))] - const SYS: c::c_long = c::SYS_setresuid as c::c_long; - - syscall! { - fn setresuid(ruid: c::uid_t, euid: c::uid_t, suid: c::uid_t) via SYS -> c::c_int - } - - unsafe { ret(setresuid(ruid.as_raw(), euid.as_raw(), suid.as_raw())) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn setgid_thread(gid: crate::ugid::Gid) -> io::Result<()> { - syscall! { - fn setgid(gid: c::gid_t) via SYS_setgid -> c::c_int - } - - unsafe { ret(setgid(gid.as_raw())) } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn setresgid_thread( - rgid: crate::ugid::Gid, - egid: crate::ugid::Gid, - sgid: crate::ugid::Gid, -) -> io::Result<()> { - #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))] - const SYS: c::c_long = c::SYS_setresgid32 as c::c_long; - #[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))] - const SYS: c::c_long = c::SYS_setresgid as c::c_long; - - syscall! { - fn setresgid(rgid: c::gid_t, egid: c::gid_t, sgid: c::gid_t) via SYS -> c::c_int - } - - unsafe { ret(setresgid(rgid.as_raw(), egid.as_raw(), sgid.as_raw())) } -} - -/// # Safety -/// -/// The raw pointers must point to valid aligned memory. -#[cfg(linux_kernel)] -pub(crate) unsafe fn futex_val2( - uaddr: *const AtomicU32, - op: super::futex::Operation, - flags: futex::Flags, - val: u32, - val2: u32, - uaddr2: *const AtomicU32, - val3: u32, -) -> io::Result<usize> { - // Pass `val2` in the least-significant bytes of the `timeout` argument. - // [“the kernel casts the timeout value first to unsigned long, then to - // uint32_t”], so we perform that exact conversion in reverse to create - // the pointer. - // - // [“the kernel casts the timeout value first to unsigned long, then to uint32_t”]: https://man7.org/linux/man-pages/man2/futex.2.html - let timeout = val2 as usize as *const Timespec; - - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "aarch64", target_arch = "x86_64")) - ))] - { - // TODO: Upstream this to the libc crate. - #[allow(non_upper_case_globals)] - const SYS_futex_time64: i32 = linux_raw_sys::general::__NR_futex_time64 as i32; - - syscall! { - fn futex_time64( - uaddr: *const AtomicU32, - futex_op: c::c_int, - val: u32, - timeout: *const Timespec, - uaddr2: *const AtomicU32, - val3: u32 - ) via SYS_futex_time64 -> c::ssize_t - } - - ret_usize(futex_time64( - uaddr, - op as i32 | flags.bits() as i32, - val, - timeout, - uaddr2, - val3, - )) - } - - #[cfg(any( - target_pointer_width = "64", - target_arch = "aarch64", - target_arch = "x86_64" - ))] - { - syscall! { - fn futex( - uaddr: *const AtomicU32, - futex_op: c::c_int, - val: u32, - timeout: *const Timespec, - uaddr2: *const AtomicU32, - val3: u32 - ) via SYS_futex -> c::c_long - } - - ret_usize(futex( - uaddr, - op as i32 | flags.bits() as i32, - val, - timeout.cast(), - uaddr2, - val3, - ) as isize) - } -} - -/// # Safety -/// -/// The raw pointers must point to valid aligned memory. -#[cfg(linux_kernel)] -pub(crate) unsafe fn futex_timeout( - uaddr: *const AtomicU32, - op: super::futex::Operation, - flags: futex::Flags, - val: u32, - timeout: Option<&Timespec>, - uaddr2: *const AtomicU32, - val3: u32, -) -> io::Result<usize> { - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "aarch64", target_arch = "x86_64")) - ))] - { - // TODO: Upstream this to the libc crate. - #[allow(non_upper_case_globals)] - const SYS_futex_time64: i32 = linux_raw_sys::general::__NR_futex_time64 as i32; - - syscall! { - fn futex_time64( - uaddr: *const AtomicU32, - futex_op: c::c_int, - val: u32, - timeout: *const Timespec, - uaddr2: *const AtomicU32, - val3: u32 - ) via SYS_futex_time64 -> c::ssize_t - } - - ret_usize(futex_time64( - uaddr, - op as i32 | flags.bits() as i32, - val, - option_as_ptr(timeout), - uaddr2, - val3, - )) - .or_else(|err| { - // See the comments in `clock_gettime_via_syscall` about emulation. - if err == io::Errno::NOSYS { - futex_old_timespec(uaddr, op, flags, val, timeout, uaddr2, val3) - } else { - Err(err) - } - }) - } - - #[cfg(any( - target_pointer_width = "64", - target_arch = "aarch64", - target_arch = "x86_64" - ))] - { - syscall! { - fn futex( - uaddr: *const AtomicU32, - futex_op: c::c_int, - val: u32, - timeout: *const Timespec, - uaddr2: *const AtomicU32, - val3: u32 - ) via SYS_futex -> c::c_long - } - - ret_usize(futex( - uaddr, - op as i32 | flags.bits() as i32, - val, - option_as_ptr(timeout).cast(), - uaddr2, - val3, - ) as isize) - } -} - -/// # Safety -/// -/// The raw pointers must point to valid aligned memory. -#[cfg(linux_kernel)] -#[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "aarch64", target_arch = "x86_64")) -))] -unsafe fn futex_old_timespec( - uaddr: *const AtomicU32, - op: super::futex::Operation, - flags: futex::Flags, - val: u32, - timeout: Option<&Timespec>, - uaddr2: *const AtomicU32, - val3: u32, -) -> io::Result<usize> { - syscall! { - fn futex( - uaddr: *const AtomicU32, - futex_op: c::c_int, - val: u32, - timeout: *const linux_raw_sys::general::__kernel_old_timespec, - uaddr2: *const AtomicU32, - val3: u32 - ) via SYS_futex -> c::c_long - } - - let old_timeout = if let Some(timeout) = timeout { - Some(linux_raw_sys::general::__kernel_old_timespec { - tv_sec: timeout.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: timeout.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }) - } else { - None - }; - ret_usize(futex( - uaddr, - op as i32 | flags.bits() as i32, - val, - option_as_ptr(old_timeout.as_ref()), - uaddr2, - val3, - ) as isize) -} - -#[cfg(linux_kernel)] -pub(crate) fn futex_waitv( - waiters: &[futex::Wait], - flags: futex::WaitvFlags, - timeout: Option<&Timespec>, - clockid: ClockId, -) -> io::Result<usize> { - use futex::Wait as FutexWait; - use linux_raw_sys::general::__kernel_clockid_t as clockid_t; - syscall! { - fn futex_waitv( - waiters: *const FutexWait, - nr_futexes: c::c_uint, - flags: c::c_uint, - timeout: *const Timespec, - clockid: clockid_t - ) via SYS_futex_waitv -> c::c_int - } - - let nr_futexes: c::c_uint = waiters.len().try_into().map_err(|_| io::Errno::INVAL)?; - - unsafe { - ret_c_int(futex_waitv( - waiters.as_ptr(), - nr_futexes, - flags.bits(), - option_as_ptr(timeout).cast(), - clockid as _, - )) - .map(|n| n as usize) - } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn setgroups_thread(groups: &[crate::ugid::Gid]) -> io::Result<()> { - syscall! { - fn setgroups(size: c::size_t, list: *const c::gid_t) via SYS_setgroups -> c::c_int - } - ret(unsafe { setgroups(groups.len(), groups.as_ptr().cast()) }) -} - -#[cfg(any(linux_kernel, target_os = "dragonfly"))] -#[inline] -pub(crate) fn sched_getcpu() -> usize { - let r = unsafe { c::sched_getcpu() }; - debug_assert!(r >= 0); - r as usize -} - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - ret(c::sched_getaffinity( - Pid::as_raw(pid) as _, - core::mem::size_of::<RawCpuSet>(), - cpuset, - )) - } -} - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(c::sched_setaffinity( - Pid::as_raw(pid) as _, - core::mem::size_of::<RawCpuSet>(), - cpuset, - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - let _ = c::sched_yield(); - } -} - -// The `membarrier` syscall has a third argument, but it's only used when -// the `flags` argument is `MEMBARRIER_CMD_FLAG_CPU`. -#[cfg(linux_kernel)] -syscall! { - fn membarrier_all( - cmd: c::c_int, - flags: c::c_uint - ) via SYS_membarrier -> c::c_int -} - -#[cfg(linux_kernel)] -pub(crate) fn membarrier_query() -> MembarrierQuery { - // glibc does not have a wrapper for `membarrier`; [the documentation] - // says to use `syscall`. - // - // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES - const MEMBARRIER_CMD_QUERY: u32 = 0; - unsafe { - match ret_u32(membarrier_all(MEMBARRIER_CMD_QUERY as i32, 0)) { - Ok(query) => MembarrierQuery::from_bits_retain(query), - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[cfg(linux_kernel)] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { ret(membarrier_all(cmd as i32, 0)) } -} - -#[cfg(linux_kernel)] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; - - syscall! { - fn membarrier_cpu( - cmd: c::c_int, - flags: c::c_uint, - cpu_id: c::c_int - ) via SYS_membarrier -> c::c_int - } - - unsafe { - ret(membarrier_cpu( - cmd as i32, - MEMBARRIER_CMD_FLAG_CPU, - bitcast!(cpu.as_raw()), - )) - } -} diff --git a/vendor/rustix/src/backend/libc/thread/types.rs b/vendor/rustix/src/backend/libc/thread/types.rs deleted file mode 100644 index 105749ed..00000000 --- a/vendor/rustix/src/backend/libc/thread/types.rs +++ /dev/null @@ -1,60 +0,0 @@ -#[cfg(all( - any(freebsdlike, linux_kernel, target_os = "fuchsia"), - not(any(target_os = "espidf", target_os = "vita")) -))] -use crate::backend::c; - -/// A command for use with [`membarrier`] and [`membarrier_cpu`]. -/// -/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. -/// -/// [`membarrier`]: crate::thread::membarrier -/// [`membarrier_cpu`]: crate::thread::membarrier_cpu -/// [`membarrier_query`]: crate::thread::membarrier_query -#[cfg(linux_kernel)] -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[repr(u32)] -#[non_exhaustive] -pub enum MembarrierCommand { - /// `MEMBARRIER_CMD_GLOBAL` - #[doc(alias = "Shared")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - Global = c::MEMBARRIER_CMD_GLOBAL as u32, - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - GlobalExpedited = c::MEMBARRIER_CMD_GLOBAL_EXPEDITED as u32, - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - RegisterGlobalExpedited = c::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as u32, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - PrivateExpedited = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED as u32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - RegisterPrivateExpedited = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as u32, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - PrivateExpeditedSyncCore = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as u32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - RegisterPrivateExpeditedSyncCore = - c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as u32, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - PrivateExpeditedRseq = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as u32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - RegisterPrivateExpeditedRseq = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as u32, -} - -/// A CPU identifier as a raw integer. -#[cfg(linux_kernel)] -pub type RawCpuid = u32; - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -pub(crate) type RawCpuSet = c::cpu_set_t; -#[cfg(freebsdlike)] -pub(crate) type RawCpuSet = c::cpuset_t; - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn raw_cpu_set_new() -> RawCpuSet { - let mut set = unsafe { core::mem::zeroed() }; - super::cpu_set::CPU_ZERO(&mut set); - set -} - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; diff --git a/vendor/rustix/src/backend/libc/time/mod.rs b/vendor/rustix/src/backend/libc/time/mod.rs deleted file mode 100644 index bff7fd56..00000000 --- a/vendor/rustix/src/backend/libc/time/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/time/syscalls.rs b/vendor/rustix/src/backend/libc/time/syscalls.rs deleted file mode 100644 index c17a9d2f..00000000 --- a/vendor/rustix/src/backend/libc/time/syscalls.rs +++ /dev/null @@ -1,484 +0,0 @@ -//! libc syscalls supporting `rustix::time`. - -use crate::backend::c; -use crate::backend::conv::ret; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(any(all(target_env = "gnu", fix_y2038), not(fix_y2038)))] -use crate::backend::time::types::LibcItimerspec; -#[cfg(not(target_os = "wasi"))] -use crate::clockid::{ClockId, DynamicClockId}; -use crate::io; -#[cfg(not(fix_y2038))] -use crate::timespec::as_libc_timespec_mut_ptr; -#[cfg(not(fix_y2038))] -#[cfg(not(any( - target_os = "redox", - target_os = "wasi", - all(apple, not(target_os = "macos")) -)))] -use crate::timespec::as_libc_timespec_ptr; -#[cfg(all(target_env = "gnu", fix_y2038))] -use crate::timespec::LibcTimespec; -use crate::timespec::Timespec; -use core::mem::MaybeUninit; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use { - crate::backend::conv::{borrowed_fd, ret_owned_fd}, - crate::fd::{BorrowedFd, OwnedFd}, - crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, -}; - -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __clock_gettime64(c::clockid_t, *mut LibcTimespec) -> c::c_int); -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __clock_settime64(c::clockid_t, *const LibcTimespec) -> c::c_int); -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __clock_getres64(c::clockid_t, *mut LibcTimespec) -> c::c_int); -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __timerfd_gettime64(c::c_int, *mut LibcItimerspec) -> c::c_int); -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __timerfd_settime64(c::c_int, c::c_int, *const LibcItimerspec, *mut LibcItimerspec) -> c::c_int); - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[inline] -#[must_use] -pub(crate) fn clock_getres(id: ClockId) -> Timespec { - // Old 32-bit version: libc has `clock_getres` but it is not y2038 safe by - // default. But there may be a `__clock_getres64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_clock_getres) = __clock_getres64.get() { - let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); - unsafe { - ret(libc_clock_getres(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); - return timespec.assume_init().into(); - } - } - - clock_getres_old(id) - } - - // Main version: libc is y2038 safe and has `clock_getres`. - #[cfg(not(fix_y2038))] - unsafe { - let mut timespec = MaybeUninit::<Timespec>::uninit(); - let _ = c::clock_getres(id as c::clockid_t, as_libc_timespec_mut_ptr(&mut timespec)); - timespec.assume_init() - } -} - -#[cfg(fix_y2038)] -#[must_use] -fn clock_getres_old(id: ClockId) -> Timespec { - let mut old_timespec = MaybeUninit::<c::timespec>::uninit(); - - let old_timespec = unsafe { - ret(c::clock_getres( - id as c::clockid_t, - old_timespec.as_mut_ptr(), - )) - .unwrap(); - old_timespec.assume_init() - }; - - Timespec { - tv_sec: old_timespec.tv_sec.into(), - tv_nsec: old_timespec.tv_nsec.into(), - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn clock_gettime(id: ClockId) -> Timespec { - // Old 32-bit version: libc has `clock_gettime` but it is not y2038 safe by - // default. But there may be a `__clock_gettime64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_clock_gettime) = __clock_gettime64.get() { - let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); - unsafe { - ret(libc_clock_gettime( - id as c::clockid_t, - timespec.as_mut_ptr(), - )) - .unwrap(); - return timespec.assume_init().into(); - } - } - - clock_gettime_old(id) - } - - // Use `.unwrap()` here because `clock_getres` can fail if the clock itself - // overflows a number of seconds, but if that happens, the monotonic clocks - // can't maintain their invariants, or the realtime clocks aren't properly - // configured. - #[cfg(not(fix_y2038))] - unsafe { - let mut timespec = MaybeUninit::<Timespec>::uninit(); - ret(c::clock_gettime( - id as c::clockid_t, - as_libc_timespec_mut_ptr(&mut timespec), - )) - .unwrap(); - let timespec = timespec.assume_init(); - #[cfg(apple)] - let timespec = fix_negative_timespec_nsecs(timespec); - timespec - } -} - -#[cfg(fix_y2038)] -#[must_use] -fn clock_gettime_old(id: ClockId) -> Timespec { - let mut old_timespec = MaybeUninit::<c::timespec>::uninit(); - - let old_timespec = unsafe { - ret(c::clock_gettime( - id as c::clockid_t, - old_timespec.as_mut_ptr(), - )) - .unwrap(); - old_timespec.assume_init() - }; - - Timespec { - tv_sec: old_timespec.tv_sec.into(), - tv_nsec: old_timespec.tv_nsec.into(), - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timespec> { - let id: c::clockid_t = match id { - DynamicClockId::Known(id) => id as c::clockid_t, - - #[cfg(linux_kernel)] - DynamicClockId::Dynamic(fd) => { - use crate::fd::AsRawFd as _; - const CLOCKFD: i32 = 3; - (!fd.as_raw_fd() << 3) | CLOCKFD - } - - #[cfg(not(linux_kernel))] - DynamicClockId::Dynamic(_fd) => { - // Dynamic clocks are not supported on this platform. - return Err(io::Errno::INVAL); - } - - #[cfg(linux_kernel)] - DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM, - - #[cfg(linux_kernel)] - DynamicClockId::Tai => c::CLOCK_TAI, - - #[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd" - ))] - DynamicClockId::Boottime => c::CLOCK_BOOTTIME, - - #[cfg(any(linux_kernel, target_os = "fuchsia"))] - DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM, - }; - - // Old 32-bit version: libc has `clock_gettime` but it is not y2038 - // safe by default. But there may be a `__clock_gettime64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_clock_gettime) = __clock_gettime64.get() { - let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); - unsafe { - ret(libc_clock_gettime( - id as c::clockid_t, - timespec.as_mut_ptr(), - ))?; - - return Ok(timespec.assume_init().into()); - } - } - - clock_gettime_dynamic_old(id) - } - - // Main version: libc is y2038 safe and has `clock_gettime`. - #[cfg(not(fix_y2038))] - unsafe { - let mut timespec = MaybeUninit::<Timespec>::uninit(); - - ret(c::clock_gettime( - id as c::clockid_t, - as_libc_timespec_mut_ptr(&mut timespec), - ))?; - let timespec = timespec.assume_init(); - #[cfg(apple)] - let timespec = fix_negative_timespec_nsecs(timespec); - Ok(timespec) - } -} - -#[cfg(fix_y2038)] -#[inline] -fn clock_gettime_dynamic_old(id: c::clockid_t) -> io::Result<Timespec> { - let mut old_timespec = MaybeUninit::<c::timespec>::uninit(); - - let old_timespec = unsafe { - ret(c::clock_gettime( - id as c::clockid_t, - old_timespec.as_mut_ptr(), - ))?; - - old_timespec.assume_init() - }; - - Ok(Timespec { - tv_sec: old_timespec.tv_sec.into(), - tv_nsec: old_timespec.tv_nsec.into(), - }) -} - -#[cfg(not(any( - target_os = "redox", - target_os = "wasi", - all(apple, not(target_os = "macos")) -)))] -#[inline] -pub(crate) fn clock_settime(id: ClockId, timespec: Timespec) -> io::Result<()> { - // Old 32-bit version: libc has `clock_gettime` but it is not y2038 safe by - // default. But there may be a `__clock_settime64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_clock_settime) = __clock_settime64.get() { - unsafe { - let mut new_timespec = core::mem::zeroed::<LibcTimespec>(); - new_timespec.tv_sec = timespec.tv_sec; - new_timespec.tv_nsec = timespec.tv_nsec as _; - return ret(libc_clock_settime(id as c::clockid_t, &new_timespec)); - } - } - - clock_settime_old(id, timespec) - } - - // Main version: libc is y2038 safe and has `clock_settime`. - #[cfg(not(fix_y2038))] - unsafe { - ret(c::clock_settime( - id as c::clockid_t, - as_libc_timespec_ptr(×pec), - )) - } -} - -#[cfg(not(any( - target_os = "redox", - target_os = "wasi", - all(apple, not(target_os = "macos")) -)))] -#[cfg(fix_y2038)] -fn clock_settime_old(id: ClockId, timespec: Timespec) -> io::Result<()> { - let old_timespec = c::timespec { - tv_sec: timespec - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: timespec.tv_nsec as _, - }; - - unsafe { ret(c::clock_settime(id as c::clockid_t, &old_timespec)) } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -pub(crate) fn timerfd_create(id: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::timerfd_create(id as c::clockid_t, bitflags_bits!(flags))) } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -pub(crate) fn timerfd_settime( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result<Itimerspec> { - // Old 32-bit version: libc has `timerfd_settime` but it is not y2038 safe - // by default. But there may be a `__timerfd_settime64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_timerfd_settime) = __timerfd_settime64.get() { - let mut result = MaybeUninit::<LibcItimerspec>::uninit(); - unsafe { - ret(libc_timerfd_settime( - borrowed_fd(fd), - bitflags_bits!(flags), - &new_value.clone().into(), - result.as_mut_ptr(), - ))?; - return Ok(result.assume_init().into()); - } - } - - timerfd_settime_old(fd, flags, new_value) - } - - #[cfg(not(fix_y2038))] - unsafe { - use crate::backend::time::types::{as_libc_itimerspec_mut_ptr, as_libc_itimerspec_ptr}; - - let mut result = MaybeUninit::<LibcItimerspec>::uninit(); - ret(c::timerfd_settime( - borrowed_fd(fd), - bitflags_bits!(flags), - as_libc_itimerspec_ptr(new_value), - as_libc_itimerspec_mut_ptr(&mut result), - ))?; - Ok(result.assume_init()) - } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(fix_y2038)] -fn timerfd_settime_old( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result<Itimerspec> { - let mut old_result = MaybeUninit::<c::itimerspec>::uninit(); - - // Convert `new_value` to the old `itimerspec` format. - let old_new_value = c::itimerspec { - it_interval: c::timespec { - tv_sec: new_value - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_interval - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - it_value: c::timespec { - tv_sec: new_value - .it_value - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_value - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - }; - - let old_result = unsafe { - ret(c::timerfd_settime( - borrowed_fd(fd), - bitflags_bits!(flags), - &old_new_value, - old_result.as_mut_ptr(), - ))?; - old_result.assume_init() - }; - - Ok(Itimerspec { - it_interval: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - it_value: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - }) -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { - // Old 32-bit version: libc has `timerfd_gettime` but it is not y2038 safe - // by default. But there may be a `__timerfd_gettime64` we can use. - #[cfg(fix_y2038)] - { - #[cfg(target_env = "gnu")] - if let Some(libc_timerfd_gettime) = __timerfd_gettime64.get() { - let mut result = MaybeUninit::<LibcItimerspec>::uninit(); - unsafe { - ret(libc_timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr()))?; - return Ok(result.assume_init().into()); - } - } - - timerfd_gettime_old(fd) - } - - #[cfg(not(fix_y2038))] - unsafe { - use crate::backend::time::types::as_libc_itimerspec_mut_ptr; - - let mut result = MaybeUninit::<LibcItimerspec>::uninit(); - ret(c::timerfd_gettime( - borrowed_fd(fd), - as_libc_itimerspec_mut_ptr(&mut result), - ))?; - Ok(result.assume_init()) - } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(fix_y2038)] -fn timerfd_gettime_old(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { - let mut old_result = MaybeUninit::<c::itimerspec>::uninit(); - - let old_result = unsafe { - ret(c::timerfd_gettime(borrowed_fd(fd), old_result.as_mut_ptr()))?; - old_result.assume_init() - }; - - Ok(Itimerspec { - it_interval: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - it_value: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - }) -} - -/// See [`crate::timespec::fix_negative_nsecs`] for details. -#[cfg(apple)] -#[cfg(not(fix_y2038))] -fn fix_negative_timespec_nsecs(mut ts: Timespec) -> Timespec { - let (sec, nsec) = crate::timespec::fix_negative_nsecs(ts.tv_sec as _, ts.tv_nsec as _); - ts.tv_sec = sec as _; - ts.tv_nsec = nsec as _; - ts -} diff --git a/vendor/rustix/src/backend/libc/time/types.rs b/vendor/rustix/src/backend/libc/time/types.rs deleted file mode 100644 index 0a7fd83c..00000000 --- a/vendor/rustix/src/backend/libc/time/types.rs +++ /dev/null @@ -1,179 +0,0 @@ -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use crate::backend::c; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use crate::time::Itimerspec; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(fix_y2038)] -use crate::timespec::LibcTimespec; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use bitflags::bitflags; - -/// On most platforms, `LibcItimerspec` is just `Itimerspec`. -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(not(fix_y2038))] -pub(crate) type LibcItimerspec = Itimerspec; - -/// On 32-bit glibc platforms, `LibcTimespec` differs from `Timespec`, so we -/// define our own struct, with bidirectional `From` impls. -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(fix_y2038)] -#[repr(C)] -#[derive(Debug, Clone)] -pub(crate) struct LibcItimerspec { - pub it_interval: LibcTimespec, - pub it_value: LibcTimespec, -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(fix_y2038)] -impl From<LibcItimerspec> for Itimerspec { - #[inline] - fn from(t: LibcItimerspec) -> Self { - Self { - it_interval: t.it_interval.into(), - it_value: t.it_value.into(), - } - } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(fix_y2038)] -impl From<Itimerspec> for LibcItimerspec { - #[inline] - fn from(t: Itimerspec) -> Self { - Self { - it_interval: t.it_interval.into(), - it_value: t.it_value.into(), - } - } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(not(fix_y2038))] -pub(crate) fn as_libc_itimerspec_ptr(itimerspec: &Itimerspec) -> *const c::itimerspec { - #[cfg(test)] - { - assert_eq_size!(Itimerspec, c::itimerspec); - } - crate::utils::as_ptr(itimerspec).cast::<c::itimerspec>() -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[cfg(not(fix_y2038))] -pub(crate) fn as_libc_itimerspec_mut_ptr( - itimerspec: &mut core::mem::MaybeUninit<Itimerspec>, -) -> *mut c::itimerspec { - #[cfg(test)] - { - assert_eq_size!(Itimerspec, c::itimerspec); - } - itimerspec.as_mut_ptr().cast::<c::itimerspec>() -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -bitflags! { - /// `TFD_*` flags for use with [`timerfd_create`]. - /// - /// [`timerfd_create`]: crate::time::timerfd_create - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct TimerfdFlags: u32 { - /// `TFD_NONBLOCK` - #[doc(alias = "TFD_NONBLOCK")] - const NONBLOCK = bitcast!(c::TFD_NONBLOCK); - - /// `TFD_CLOEXEC` - #[doc(alias = "TFD_CLOEXEC")] - const CLOEXEC = bitcast!(c::TFD_CLOEXEC); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -bitflags! { - /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. - /// - /// [`timerfd_settime`]: crate::time::timerfd_settime - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct TimerfdTimerFlags: u32 { - /// `TFD_TIMER_ABSTIME` - #[doc(alias = "TFD_TIMER_ABSTIME")] - const ABSTIME = bitcast!(c::TFD_TIMER_ABSTIME); - - /// `TFD_TIMER_CANCEL_ON_SET` - #[cfg(linux_kernel)] - #[doc(alias = "TFD_TIMER_CANCEL_ON_SET")] - const CANCEL_ON_SET = bitcast!(c::TFD_TIMER_CANCEL_ON_SET); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `CLOCK_*` constants for use with [`timerfd_create`]. -/// -/// [`timerfd_create`]: crate::time::timerfd_create -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum TimerfdClockId { - /// `CLOCK_REALTIME`—A clock that tells the “real” time. - /// - /// This is a clock that tells the amount of time elapsed since the Unix - /// epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so it is - /// not monotonic. Successive reads may see decreasing times, so it isn't - /// reliable for measuring durations. - #[doc(alias = "CLOCK_REALTIME")] - Realtime = bitcast!(c::CLOCK_REALTIME), - - /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. - /// - /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so - /// individual times aren't meaningful. However, since it isn't settable, - /// it is reliable for measuring durations. - /// - /// This clock does not advance while the system is suspended; see - /// `Boottime` for a clock that does. - #[doc(alias = "CLOCK_MONOTONIC")] - Monotonic = bitcast!(c::CLOCK_MONOTONIC), - - /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. - /// - /// This clock is similar to `Monotonic`, but does advance while the system - /// is suspended. - #[doc(alias = "CLOCK_BOOTTIME")] - Boottime = bitcast!(c::CLOCK_BOOTTIME), - - /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. - /// - /// This clock is like `Realtime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - #[doc(alias = "CLOCK_REALTIME_ALARM")] - RealtimeAlarm = bitcast!(c::CLOCK_REALTIME_ALARM), - - /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. - /// - /// This clock is like `Boottime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - #[doc(alias = "CLOCK_BOOTTIME_ALARM")] - BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM), -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - - #[cfg(any(linux_kernel, target_os = "fuchsia"))] - #[test] - fn test_types() { - assert_eq_size!(TimerfdFlags, c::c_int); - assert_eq_size!(TimerfdTimerFlags, c::c_int); - } -} diff --git a/vendor/rustix/src/backend/libc/ugid/mod.rs b/vendor/rustix/src/backend/libc/ugid/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/libc/ugid/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/ugid/syscalls.rs b/vendor/rustix/src/backend/libc/ugid/syscalls.rs deleted file mode 100644 index f191116e..00000000 --- a/vendor/rustix/src/backend/libc/ugid/syscalls.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::backend::c; -use crate::ugid::{Gid, RawGid, RawUid, Uid}; - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getuid() -> Uid { - unsafe { - let uid = c::getuid() as RawUid; - Uid::from_raw(uid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn geteuid() -> Uid { - unsafe { - let uid = c::geteuid() as RawUid; - Uid::from_raw(uid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getgid() -> Gid { - unsafe { - let gid = c::getgid() as RawGid; - Gid::from_raw(gid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getegid() -> Gid { - unsafe { - let gid = c::getegid() as RawGid; - Gid::from_raw(gid) - } -} diff --git a/vendor/rustix/src/backend/libc/winsock_c.rs b/vendor/rustix/src/backend/libc/winsock_c.rs deleted file mode 100644 index c583e331..00000000 --- a/vendor/rustix/src/backend/libc/winsock_c.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! Adapt the Winsock API to resemble a POSIX-style libc API. - -#![allow(unused_imports)] -#![allow(non_camel_case_types)] -#![allow(dead_code)] - -use windows_sys::Win32::Networking::WinSock; - -// Define the basic C types. With Rust 1.64, we can use these from `core::ffi`. -pub(crate) type c_schar = i8; -pub(crate) type c_uchar = u8; -pub(crate) type c_short = i16; -pub(crate) type c_ushort = u16; -pub(crate) type c_int = i32; -pub(crate) type c_uint = u32; -pub(crate) type c_longlong = i64; -pub(crate) type c_ulonglong = u64; -pub(crate) type ssize_t = isize; -pub(crate) type c_char = i8; -pub(crate) type c_long = i32; -pub(crate) type c_ulong = u32; -pub(crate) use core::ffi::c_void; - -// windows-sys declares these constants as `u16`. For better compatibility with -// Unix-family APIs, redeclare them as `i32`. -pub(crate) const AF_INET: i32 = WinSock::AF_INET as _; -pub(crate) const AF_INET6: i32 = WinSock::AF_INET6 as _; -pub(crate) const AF_UNSPEC: i32 = WinSock::AF_UNSPEC as _; - -// Include the contents of `WinSock`, renaming as needed to match POSIX. -// -// Use `WSA_E_CANCELLED` for `ECANCELED` instead of `WSAECANCELLED`, because -// `WSAECANCELLED` will be removed in the future. -// <https://docs.microsoft.com/en-us/windows/win32/api/ws2spi/nc-ws2spi-lpnsplookupserviceend#remarks> -pub(crate) use WinSock::{ - closesocket as close, ioctlsocket as ioctl, WSAPoll as poll, ADDRESS_FAMILY as sa_family_t, - ADDRINFOA as addrinfo, IN6_ADDR as in6_addr, IN_ADDR as in_addr, IPV6_MREQ as ipv6_mreq, - IP_MREQ as ip_mreq, LINGER as linger, SD_BOTH as SHUT_RDWR, SD_RECEIVE as SHUT_RD, - SD_SEND as SHUT_WR, SOCKADDR as sockaddr, SOCKADDR_IN as sockaddr_in, - SOCKADDR_IN6 as sockaddr_in6, SOCKADDR_STORAGE as sockaddr_storage, WSAEACCES as EACCES, - WSAEADDRINUSE as EADDRINUSE, WSAEADDRNOTAVAIL as EADDRNOTAVAIL, - WSAEAFNOSUPPORT as EAFNOSUPPORT, WSAEALREADY as EALREADY, WSAEBADF as EBADF, - WSAECONNABORTED as ECONNABORTED, WSAECONNREFUSED as ECONNREFUSED, WSAECONNRESET as ECONNRESET, - WSAEDESTADDRREQ as EDESTADDRREQ, WSAEDISCON as EDISCON, WSAEDQUOT as EDQUOT, - WSAEFAULT as EFAULT, WSAEHOSTDOWN as EHOSTDOWN, WSAEHOSTUNREACH as EHOSTUNREACH, - WSAEINPROGRESS as EINPROGRESS, WSAEINTR as EINTR, WSAEINVAL as EINVAL, - WSAEINVALIDPROCTABLE as EINVALIDPROCTABLE, WSAEINVALIDPROVIDER as EINVALIDPROVIDER, - WSAEISCONN as EISCONN, WSAELOOP as ELOOP, WSAEMFILE as EMFILE, WSAEMSGSIZE as EMSGSIZE, - WSAENAMETOOLONG as ENAMETOOLONG, WSAENETDOWN as ENETDOWN, WSAENETRESET as ENETRESET, - WSAENETUNREACH as ENETUNREACH, WSAENOBUFS as ENOBUFS, WSAENOMORE as ENOMORE, - WSAENOPROTOOPT as ENOPROTOOPT, WSAENOTCONN as ENOTCONN, WSAENOTEMPTY as ENOTEMPTY, - WSAENOTSOCK as ENOTSOCK, WSAEOPNOTSUPP as EOPNOTSUPP, WSAEPFNOSUPPORT as EPFNOSUPPORT, - WSAEPROCLIM as EPROCLIM, WSAEPROTONOSUPPORT as EPROTONOSUPPORT, WSAEPROTOTYPE as EPROTOTYPE, - WSAEPROVIDERFAILEDINIT as EPROVIDERFAILEDINIT, WSAEREFUSED as EREFUSED, WSAEREMOTE as EREMOTE, - WSAESHUTDOWN as ESHUTDOWN, WSAESOCKTNOSUPPORT as ESOCKTNOSUPPORT, WSAESTALE as ESTALE, - WSAETIMEDOUT as ETIMEDOUT, WSAETOOMANYREFS as ETOOMANYREFS, WSAEUSERS as EUSERS, - WSAEWOULDBLOCK as EWOULDBLOCK, WSAEWOULDBLOCK as EAGAIN, WSAPOLLFD as pollfd, - WSA_E_CANCELLED as ECANCELED, *, -}; - -// Windows doesn't have `timespec`, just `timeval`. Rustix only uses `timespec` -// in its public API. So define one, and we'll convert it internally. -pub struct timespec { - pub tv_sec: time_t, - pub tv_nsec: crate::ffi::c_long, -} -pub type time_t = i64; diff --git a/vendor/rustix/src/backend/linux_raw/arch/aarch64.rs b/vendor/rustix/src/backend/linux_raw/arch/aarch64.rs deleted file mode 100644 index 4f9e52af..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/aarch64.rs +++ /dev/null @@ -1,269 +0,0 @@ -//! aarch64 Linux system calls. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[cfg(target_pointer_width = "32")] -compile_error!("arm64-ilp32 is not supported yet"); - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - lateout("x0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "svc 0", - "brk #0x1", - in("x8") nr.to_asm(), - in("x0") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - in("x5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - in("x5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/arm.rs b/vendor/rustix/src/backend/linux_raw/arch/arm.rs deleted file mode 100644 index 4317154f..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/arm.rs +++ /dev/null @@ -1,266 +0,0 @@ -//! arm Linux system calls. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - lateout("r0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "svc 0", - "udf #16", - in("r7") nr.to_asm(), - in("r0") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - in("r5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - in("r5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/mips.rs b/vendor/rustix/src/backend/linux_raw/arch/mips.rs deleted file mode 100644 index eb66e261..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/mips.rs +++ /dev/null @@ -1,544 +0,0 @@ -//! mipsel Linux system calls. -//! -//! On mipsel, Linux indicates success or failure using `$a3` rather -//! than by returning a negative error code as most other architectures do. -//! -//! MIPS-family platforms have a special calling convention for `__NR_pipe`, -//! however we use `__NR_pipe2` instead to avoid having to implement it. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, A6, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - "teq $0,$0", - in("$2" /*$v0*/) nr.to_asm(), - in("$4" /*$a0*/) a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall7_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - a6: ArgReg<'_, A6>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "sw {}, 24($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - in(reg) a6.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/mips32r6.rs b/vendor/rustix/src/backend/linux_raw/arch/mips32r6.rs deleted file mode 100644 index d273a968..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/mips32r6.rs +++ /dev/null @@ -1,544 +0,0 @@ -//! mipsisa32r6el Linux system calls. -//! -//! On mipsisa32r6el, Linux indicates success or failure using `$a3` rather -//! than by returning a negative error code as most other architectures do. -//! -//! MIPS-family platforms have a special calling convention for `__NR_pipe`, -//! however we use `__NR_pipe2` instead to avoid having to implement it. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, A6, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - "teq $0,$0", - in("$2" /*$v0*/) nr.to_asm(), - in("$4" /*$a0*/) a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall7_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - a6: ArgReg<'_, A6>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "sw {}, 24($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - in(reg) a6.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/mips64.rs b/vendor/rustix/src/backend/linux_raw/arch/mips64.rs deleted file mode 100644 index 821812f2..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/mips64.rs +++ /dev/null @@ -1,467 +0,0 @@ -//! mips64el Linux system calls. -//! -//! On mips64el, Linux indicates success or failure using `$a3` (`$7`) rather -//! than by returning a negative error code as most other architectures do. -//! -//! MIPS-family platforms have a special calling convention for `__NR_pipe`, -//! however we use `__NR_pipe2` instead to avoid having to implement it. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - "teq $0,$0", - in("$2" /*$v0*/) nr.to_asm(), - in("$4" /*$a0*/) a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - inlateout("$9" /*$a5*/) a5.to_asm() => _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - inlateout("$9" /*$a5*/) a5.to_asm() => _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/mips64r6.rs b/vendor/rustix/src/backend/linux_raw/arch/mips64r6.rs deleted file mode 100644 index 2a3cf564..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/mips64r6.rs +++ /dev/null @@ -1,471 +0,0 @@ -//! mipsisa64r6el Linux system calls. -//! -//! On mipsisa64r6el, Linux indicates success or failure using `$a3` (`$7`) -//! rather than by returning a negative error code as most other architectures -//! do. -//! -//! MIPS-family platforms have a special calling convention for `__NR_pipe`, -//! however we use `__NR_pipe2` instead to avoid having to implement it. -//! -//! MIPS R6 inline assembly currently doesn't differ from MIPS, because no -//! explicit call of R6-only or R2-only instructions exist here. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - "teq $0,$0", - in("$2" /*$v0*/) nr.to_asm(), - in("$4" /*$a0*/) a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - inlateout("$9" /*$a5*/) a5.to_asm() => _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - inlateout("$9" /*$a5*/) a5.to_asm() => _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/mod.rs deleted file mode 100644 index 8d675adb..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/mod.rs +++ /dev/null @@ -1,321 +0,0 @@ -//! Architecture-specific syscall code. -//! -//! This module also has a `choose` submodule which chooses a scheme and is -//! what most of the `rustix` syscalls use. -//! -//! Compilers should really have intrinsics for making system calls. They're -//! much like regular calls, with custom calling conventions, and calling -//! conventions are otherwise the compiler's job. But for now, use inline asm. -//! -//! The calling conventions for Linux syscalls are [documented here]. -//! -//! [documented here]: https://man7.org/linux/man-pages/man2/syscall.2.html -//! -//! # Safety -//! -//! This contains the inline `asm` statements performing the syscall -//! instructions. - -#![allow(unsafe_code)] -#![cfg_attr(not(feature = "all-apis"), allow(unused_imports))] -// We'll use as many arguments as syscalls need. -#![allow(clippy::too_many_arguments)] - -// These functions always use the machine's syscall instruction, even when it -// isn't the fastest option available. -#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")] -#[cfg_attr(all(target_arch = "arm", not(thumb_mode)), path = "arm.rs")] -#[cfg_attr(all(target_arch = "arm", thumb_mode), path = "thumb.rs")] -#[cfg_attr(target_arch = "mips", path = "mips.rs")] -#[cfg_attr(target_arch = "mips32r6", path = "mips32r6.rs")] -#[cfg_attr(target_arch = "mips64", path = "mips64.rs")] -#[cfg_attr(target_arch = "mips64r6", path = "mips64r6.rs")] -#[cfg_attr(target_arch = "powerpc", path = "powerpc.rs")] -#[cfg_attr(target_arch = "powerpc64", path = "powerpc64.rs")] -#[cfg_attr(target_arch = "riscv64", path = "riscv64.rs")] -#[cfg_attr(target_arch = "s390x", path = "s390x.rs")] -#[cfg_attr(target_arch = "x86", path = "x86.rs")] -#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")] -pub(in crate::backend) mod asm; - -// On most architectures, the architecture syscall instruction is fast, so use -// it directly. -#[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86_64", -))] -pub(in crate::backend) use self::asm as choose; - -// On 32-bit x86, use vDSO wrappers for all syscalls. We could use the -// architecture syscall instruction (`int 0x80`), but the vDSO -// `__kernel_vsyscall` mechanism is much faster. -#[cfg(target_arch = "x86")] -pub(in crate::backend) use super::vdso_wrappers::x86_via_vdso as choose; - -// This would be the code for always using `int 0x80` on 32-bit x86. -//#[cfg(target_arch = "x86")] -//pub(in crate::backend) use self::asm as choose; - -// Macros for invoking system calls. -// -// These factor out: -// - Calling `nr` on the syscall number to convert it into `SyscallNumber`. -// - Calling `.into()` on each of the arguments to convert them into `ArgReg`. -// - Qualifying the `syscall*` and `__NR_*` identifiers. -// - Counting the number of arguments. -macro_rules! syscall { - ($nr:ident) => { - $crate::backend::arch::choose::syscall0($crate::backend::reg::nr( - linux_raw_sys::general::$nr, - )) - }; - - ($nr:ident, $a0:expr) => { - $crate::backend::arch::choose::syscall1( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr) => { - $crate::backend::arch::choose::syscall2( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { - $crate::backend::arch::choose::syscall3( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => { - $crate::backend::arch::choose::syscall4( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => { - $crate::backend::arch::choose::syscall5( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => { - $crate::backend::arch::choose::syscall6( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => { - $crate::backend::arch::choose::syscall7( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - $a6.into(), - ) - }; -} - -// Macro to invoke a syscall that always uses direct assembly, rather than the -// vDSO. Useful when still finding the vDSO. -#[allow(unused_macros)] -macro_rules! syscall_always_asm { - ($nr:ident) => { - $crate::backend::arch::asm::syscall0($crate::backend::reg::nr(linux_raw_sys::general::$nr)) - }; - - ($nr:ident, $a0:expr) => { - $crate::backend::arch::asm::syscall1( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr) => { - $crate::backend::arch::asm::syscall2( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { - $crate::backend::arch::asm::syscall3( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => { - $crate::backend::arch::asm::syscall4( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => { - $crate::backend::arch::asm::syscall5( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => { - $crate::backend::arch::asm::syscall6( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => { - $crate::backend::arch::asm::syscall7( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - $a6.into(), - ) - }; -} - -/// Like `syscall`, but adds the `readonly` attribute to the inline asm, which -/// indicates that the syscall does not mutate any memory. -macro_rules! syscall_readonly { - ($nr:ident) => { - $crate::backend::arch::choose::syscall0_readonly($crate::backend::reg::nr( - linux_raw_sys::general::$nr, - )) - }; - - ($nr:ident, $a0:expr) => { - $crate::backend::arch::choose::syscall1_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr) => { - $crate::backend::arch::choose::syscall2_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { - $crate::backend::arch::choose::syscall3_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => { - $crate::backend::arch::choose::syscall4_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => { - $crate::backend::arch::choose::syscall5_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => { - $crate::backend::arch::choose::syscall6_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => { - $crate::backend::arch::choose::syscall7_readonly( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - $a6.into(), - ) - }; -} - -/// Like `syscall`, but indicates that the syscall does not return. -#[cfg(feature = "runtime")] -macro_rules! syscall_noreturn { - ($nr:ident, $a0:expr) => { - $crate::backend::arch::choose::syscall1_noreturn( - $crate::backend::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/powerpc.rs b/vendor/rustix/src/backend/linux_raw/arch/powerpc.rs deleted file mode 100644 index 481b49f4..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/powerpc.rs +++ /dev/null @@ -1,414 +0,0 @@ -//! powerpc Linux system calls. -//! -//! On powerpc, Linux indicates success or failure using `cr0.SO` rather -//! than by returning a negative error code as most other architectures do. In -//! theory we could immediately translate this into a `Result`, and it'd save a -//! few branches. And in theory we could have specialized sequences for use -//! with syscalls that are known to never fail. However, those would require -//! more extensive changes in rustix's platform-independent code. For now, we -//! check the flag and negate the error value to make PowerPC look like other -//! architectures. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - lateout("r3") r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "sc", - "trap", - in("r0") nr.to_asm(), - in("r3") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - inlateout("r8") a5.to_asm() => _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - inlateout("r8") a5.to_asm() => _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/powerpc64.rs b/vendor/rustix/src/backend/linux_raw/arch/powerpc64.rs deleted file mode 100644 index f21ed6aa..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/powerpc64.rs +++ /dev/null @@ -1,414 +0,0 @@ -//! powerpc64le Linux system calls. -//! -//! On powerpc64le, Linux indicates success or failure using `cr0.SO` rather -//! than by returning a negative error code as most other architectures do. In -//! theory we could immediately translate this into a `Result`, and it'd save a -//! few branches. And in theory we could have specialized sequences for use -//! with syscalls that are known to never fail. However, those would require -//! more extensive changes in rustix's platform-independent code. For now, we -//! check the flag and negate the error value to make PowerPC64 look like other -//! architectures. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - lateout("r3") r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "sc", - "trap", - in("r0") nr.to_asm(), - in("r3") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - inlateout("r8") a5.to_asm() => _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - inlateout("r8") a5.to_asm() => _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/riscv64.rs b/vendor/rustix/src/backend/linux_raw/arch/riscv64.rs deleted file mode 100644 index 512657ac..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/riscv64.rs +++ /dev/null @@ -1,266 +0,0 @@ -//! riscv64 Linux system calls. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - lateout("a0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "ecall", - "unimp", - in("a7") nr.to_asm(), - in("a0") a0.to_asm(), - options(nostack, noreturn) - ); -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - in("a5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - in("a5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/s390x.rs b/vendor/rustix/src/backend/linux_raw/arch/s390x.rs deleted file mode 100644 index 5d6e14f1..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/s390x.rs +++ /dev/null @@ -1,288 +0,0 @@ -//! s390x Linux system calls. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - lateout("r2") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "svc 0", - "j .+2", - in("r1") nr.to_asm(), - in("r2") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - in("r5") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - in("r5") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - in("r5") a3.to_asm(), - in("r6") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - in("r5") a3.to_asm(), - in("r6") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - if nr.nr == linux_raw_sys::general::__NR_mmap as usize { - let mut a = [ - a0.to_asm(), - a1.to_asm(), - a2.to_asm(), - a3.to_asm(), - a4.to_asm(), - a5.to_asm(), - ]; - return syscall1(nr, a.as_mut_ptr().into()); - } - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - in("r5") a3.to_asm(), - in("r6") a4.to_asm(), - in("r7") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - if nr.nr == linux_raw_sys::general::__NR_mmap as usize { - let a = [ - a0.to_asm(), - a1.to_asm(), - a2.to_asm(), - a3.to_asm(), - a4.to_asm(), - a5.to_asm(), - ]; - return syscall1_readonly(nr, a.as_ptr().into()); - } - let r0; - asm!( - "svc 0", - in("r1") nr.to_asm(), - inlateout("r2") a0.to_asm() => r0, - in("r3") a1.to_asm(), - in("r4") a2.to_asm(), - in("r5") a3.to_asm(), - in("r6") a4.to_asm(), - in("r7") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/thumb.rs b/vendor/rustix/src/backend/linux_raw/arch/thumb.rs deleted file mode 100644 index 0989430d..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/thumb.rs +++ /dev/null @@ -1,323 +0,0 @@ -//! arm Linux system calls, using thumb-mode. -//! -//! In thumb-mode, r7 is the frame pointer and is not permitted to be used in -//! an inline asm operand, so we have to use a different register and copy it -//! into r7 inside the inline asm. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - lateout("r0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "mov r7, {nr}", - "svc 0", - "udf #16", - nr = in(reg) nr.to_asm(), - in("r0") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - in("r5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "mov {tmp}, r7", - "mov r7, {nr}", - "svc 0", - "mov r7, {tmp}", - nr = in(reg) nr.to_asm(), - tmp = out(reg) _, - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - in("r5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/x86.rs b/vendor/rustix/src/backend/linux_raw/arch/x86.rs deleted file mode 100644 index 95376415..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/x86.rs +++ /dev/null @@ -1,492 +0,0 @@ -//! 32-bit x86 Linux system calls. -//! -//! There are two forms; `indirect_*` which take a callee, which allow calling -//! through the vDSO when possible, and plain forms, which use the `int 0x80` -//! instruction. -//! -//! Most `rustix` syscalls use the vsyscall mechanism rather than going using -//! `int 0x80` sequences, as vsyscall is much faster. -//! -//! Syscalls made with `int 0x80` preserve the flags register, while syscalls -//! made using vsyscall do not. - -#![allow(dead_code)] - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use crate::backend::vdso_wrappers::SyscallType; -use core::arch::asm; - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall0( - callee: SyscallType, - nr: SyscallNumber<'_>, -) -> RetReg<R0> { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall1( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall1_noreturn( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> ! { - asm!( - "call {callee}", - "ud2", - callee = in(reg) callee, - in("eax") nr.to_asm(), - in("ebx") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall2( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall3( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall4( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - // a3 should go in esi, but `asm!` won't let us use it as an operand. - // Temporarily swap it into place, and then swap it back afterward. - // - // We hard-code the callee operand to use edi instead of `in(reg)` because - // even though we can't name esi as an operand, the compiler can use esi to - // satisfy `in(reg)`. - asm!( - "xchg esi, {a3}", - "call edi", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - in("edi") callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall5( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - // Oof. a3 should go in esi, and `asm!` won't let us use that register as - // an operand. And we can't request stack slots. And there are no other - // registers free. Use eax as a temporary pointer to a slice, since it gets - // clobbered as the return value anyway. - asm!( - "push esi", - "push [eax + 0]", - "mov esi, [eax + 4]", - "mov eax, [eax + 8]", - "call [esp]", - "pop esi", - "pop esi", - inout("eax") &[callee as _, a3.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn indirect_syscall6( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - // Oof again. a3 should go in esi, and a5 should go in ebp, and `asm!` - // won't let us use either of those registers as operands. And we can't - // request stack slots. And there are no other registers free. Use eax as a - // temporary pointer to a slice, since it gets clobbered as the return - // value anyway. - // - // This is another reason that syscalls should be compiler intrinsics - // rather than inline asm. - asm!( - "push ebp", - "push esi", - "push [eax + 0]", - "mov esi, [eax + 4]", - "mov ebp, [eax + 8]", - "mov eax, [eax + 12]", - "call [esp]", - "pop esi", - "pop esi", - "pop ebp", - inout("eax") &[callee as _, a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "int $$0x80", - "ud2", - in("eax") nr.to_asm(), - in("ebx") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - // a3 should go in esi, but `asm!` won't let us use it as an operand. - // Temporarily swap it into place, and then swap it back afterward. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - // See the comments in `syscall4`. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - // As in `syscall4`, use xchg to handle a3. a4 should go in edi, and we can - // use that register as an operand. Unlike in `indirect_syscall5`, we don't - // have a `callee` operand taking up a register, so we have enough - // registers and don't need to use a slice. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - // See the comments in `syscall5`. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - // See the comments in `indirect_syscall6`. - asm!( - "push ebp", - "push esi", - "mov esi, [eax + 0]", - "mov ebp, [eax + 4]", - "mov eax, [eax + 8]", - "int $$0x80", - "pop esi", - "pop ebp", - inout("eax") &[a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - // See the comments in `indirect_syscall6`. - asm!( - "push ebp", - "push esi", - "mov esi, [eax + 0]", - "mov ebp, [eax + 4]", - "mov eax, [eax + 8]", - "int $$0x80", - "pop esi", - "pop ebp", - inout("eax") &[a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/arch/x86_64.rs b/vendor/rustix/src/backend/linux_raw/arch/x86_64.rs deleted file mode 100644 index 6d105c08..00000000 --- a/vendor/rustix/src/backend/linux_raw/arch/x86_64.rs +++ /dev/null @@ -1,294 +0,0 @@ -//! x86-64 Linux system calls. - -use crate::backend::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm as _, A0, A1, A2, A3, A4, A5, R0, -}; -use core::arch::asm; - -#[cfg(target_pointer_width = "32")] -compile_error!("x32 is not yet supported"); - -#[inline] -pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - "ud2", - in("rax") nr.to_asm(), - in("rdi") a0.to_asm(), - options(nostack, noreturn) - ) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - in("r9") a5.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::backend) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg<R0> { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - in("r9") a5.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/backend/linux_raw/c.rs b/vendor/rustix/src/backend/linux_raw/c.rs deleted file mode 100644 index 755dadcd..00000000 --- a/vendor/rustix/src/backend/linux_raw/c.rs +++ /dev/null @@ -1,385 +0,0 @@ -//! Adapt the Linux API to resemble a POSIX-style libc API. -//! -//! The linux_raw backend doesn't use actual libc; this just defines certain -//! types that are convenient to have defined. - -#![allow(unused_imports)] -#![allow(non_camel_case_types)] - -pub(crate) type size_t = usize; -pub(crate) use linux_raw_sys::ctypes::*; -pub(crate) use linux_raw_sys::errno::{EBADF, EINVAL}; -pub(crate) use linux_raw_sys::general::{__kernel_fd_set as fd_set, __FD_SETSIZE as FD_SETSIZE}; -pub(crate) use linux_raw_sys::ioctl::{FIONBIO, FIONREAD}; -// Import the kernel's `uid_t` and `gid_t` if they're 32-bit. -#[cfg(feature = "thread")] -pub(crate) use linux_raw_sys::general::futex_waitv; -#[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] -pub(crate) use linux_raw_sys::general::{__kernel_gid_t as gid_t, __kernel_uid_t as uid_t}; -pub(crate) use linux_raw_sys::general::{ - __kernel_pid_t as pid_t, __kernel_time64_t as time_t, __kernel_timespec as timespec, iovec, - O_CLOEXEC, O_NOCTTY, O_NONBLOCK, O_RDWR, -}; -#[cfg(feature = "system")] -pub(crate) use linux_raw_sys::system::sysinfo; - -#[cfg(feature = "fs")] -#[cfg(target_arch = "x86")] -#[cfg(test)] -pub(crate) use linux_raw_sys::general::stat64; -#[cfg(feature = "fs")] -#[cfg(test)] -pub(crate) use linux_raw_sys::general::{ - __kernel_fsid_t as fsid_t, stat, statfs64, statx, statx_timestamp, -}; - -#[cfg(feature = "event")] -#[cfg(test)] -pub(crate) use linux_raw_sys::general::epoll_event; - -#[cfg(feature = "mm")] -mod mm { - pub(crate) use linux_raw_sys::general::{MAP_HUGETLB, MAP_HUGE_SHIFT}; -} -#[cfg(feature = "mm")] -pub(crate) use mm::*; - -#[cfg(any( - feature = "fs", - all( - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) - ) -))] -pub(crate) use linux_raw_sys::general::{ - AT_FDCWD, NFS_SUPER_MAGIC, O_LARGEFILE, PROC_SUPER_MAGIC, UTIME_NOW, UTIME_OMIT, XATTR_CREATE, - XATTR_REPLACE, -}; - -pub(crate) use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, FICLONE}; -#[cfg(target_pointer_width = "32")] -pub(crate) use linux_raw_sys::ioctl::{FS_IOC32_GETFLAGS, FS_IOC32_SETFLAGS}; -#[cfg(target_pointer_width = "64")] -pub(crate) use linux_raw_sys::ioctl::{FS_IOC_GETFLAGS, FS_IOC_SETFLAGS}; - -#[cfg(feature = "io_uring")] -pub(crate) use linux_raw_sys::{general::open_how, io_uring::*}; - -#[cfg(feature = "net")] -pub(crate) use linux_raw_sys::{ - cmsg_macros::*, - general::{O_CLOEXEC as SOCK_CLOEXEC, O_NONBLOCK as SOCK_NONBLOCK}, - if_ether::*, - net::{ - __kernel_sa_family_t as sa_family_t, __kernel_sockaddr_storage as sockaddr_storage, - cmsghdr, in6_addr, in_addr, ip_mreq, ip_mreq_source, ip_mreqn, ipv6_mreq, linger, mmsghdr, - msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, AF_DECnet, - AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, - AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, - AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, - AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, AF_XDP, - IP6T_SO_ORIGINAL_DST, IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_MH, IPPROTO_ROUTING, - IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_FREEBIND, IPV6_MULTICAST_HOPS, - IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, IPV6_TCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, - IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, - IP_FREEBIND, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_RECVTOS, IP_TOS, IP_TTL, - MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_CTRUNC, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, - MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, - SCM_CREDENTIALS, SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, - SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SOL_XDP, SO_ACCEPTCONN, SO_BROADCAST, SO_COOKIE, - SO_DOMAIN, SO_ERROR, SO_INCOMING_CPU, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, - SO_ORIGINAL_DST, SO_PASSCRED, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVTIMEO_NEW, - SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, - SO_SNDBUFFORCE, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, SO_TYPE, - TCP_CONGESTION, TCP_CORK, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_NODELAY, - TCP_QUICKACK, TCP_THIN_LINEAR_TIMEOUTS, TCP_USER_TIMEOUT, - }, - netlink::*, - xdp::{ - sockaddr_xdp, xdp_desc, xdp_mmap_offsets, xdp_mmap_offsets_v1, xdp_options, - xdp_ring_offset, xdp_ring_offset_v1, xdp_statistics, xdp_statistics_v1, xdp_umem_reg, - xdp_umem_reg_v1, XDP_COPY, XDP_MMAP_OFFSETS, XDP_OPTIONS, XDP_OPTIONS_ZEROCOPY, - XDP_PGOFF_RX_RING, XDP_PGOFF_TX_RING, XDP_PKT_CONTD, XDP_RING_NEED_WAKEUP, XDP_RX_RING, - XDP_SHARED_UMEM, XDP_STATISTICS, XDP_TX_RING, XDP_UMEM_COMPLETION_RING, XDP_UMEM_FILL_RING, - XDP_UMEM_PGOFF_COMPLETION_RING, XDP_UMEM_PGOFF_FILL_RING, XDP_UMEM_REG, - XDP_UMEM_UNALIGNED_CHUNK_FLAG, XDP_USE_NEED_WAKEUP, XDP_USE_SG, XDP_ZEROCOPY, - XSK_UNALIGNED_BUF_ADDR_MASK, XSK_UNALIGNED_BUF_OFFSET_SHIFT, - }, -}; - -// Cast away bindgen's `enum` type to make these consistent with the other -// `setsockopt`/`getsockopt` level values. -#[cfg(feature = "net")] -pub(crate) const IPPROTO_IP: u32 = linux_raw_sys::net::IPPROTO_IP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_ICMP: u32 = linux_raw_sys::net::IPPROTO_ICMP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_IGMP: u32 = linux_raw_sys::net::IPPROTO_IGMP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_IPIP: u32 = linux_raw_sys::net::IPPROTO_IPIP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_TCP: u32 = linux_raw_sys::net::IPPROTO_TCP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_EGP: u32 = linux_raw_sys::net::IPPROTO_EGP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_PUP: u32 = linux_raw_sys::net::IPPROTO_PUP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_UDP: u32 = linux_raw_sys::net::IPPROTO_UDP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_IDP: u32 = linux_raw_sys::net::IPPROTO_IDP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_TP: u32 = linux_raw_sys::net::IPPROTO_TP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_DCCP: u32 = linux_raw_sys::net::IPPROTO_DCCP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_IPV6: u32 = linux_raw_sys::net::IPPROTO_IPV6 as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_RSVP: u32 = linux_raw_sys::net::IPPROTO_RSVP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_GRE: u32 = linux_raw_sys::net::IPPROTO_GRE as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_ESP: u32 = linux_raw_sys::net::IPPROTO_ESP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_AH: u32 = linux_raw_sys::net::IPPROTO_AH as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_MTP: u32 = linux_raw_sys::net::IPPROTO_MTP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_BEETPH: u32 = linux_raw_sys::net::IPPROTO_BEETPH as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_ENCAP: u32 = linux_raw_sys::net::IPPROTO_ENCAP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_PIM: u32 = linux_raw_sys::net::IPPROTO_PIM as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_COMP: u32 = linux_raw_sys::net::IPPROTO_COMP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_SCTP: u32 = linux_raw_sys::net::IPPROTO_SCTP as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_UDPLITE: u32 = linux_raw_sys::net::IPPROTO_UDPLITE as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_MPLS: u32 = linux_raw_sys::net::IPPROTO_MPLS as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_ETHERNET: u32 = linux_raw_sys::net::IPPROTO_ETHERNET as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_RAW: u32 = linux_raw_sys::net::IPPROTO_RAW as _; -#[cfg(feature = "net")] -pub(crate) const IPPROTO_MPTCP: u32 = linux_raw_sys::net::IPPROTO_MPTCP as _; - -#[cfg(any(feature = "process", feature = "runtime"))] -pub(crate) use linux_raw_sys::general::siginfo_t; - -#[cfg(any(feature = "process", feature = "runtime"))] -pub(crate) const EXIT_SUCCESS: c_int = 0; -#[cfg(any(feature = "process", feature = "runtime"))] -pub(crate) const EXIT_FAILURE: c_int = 1; -#[cfg(feature = "process")] -pub(crate) const EXIT_SIGNALED_SIGABRT: c_int = 128 + linux_raw_sys::general::SIGABRT as c_int; -#[cfg(feature = "runtime")] -pub(crate) const CLONE_CHILD_SETTID: c_int = linux_raw_sys::general::CLONE_CHILD_SETTID as c_int; - -#[cfg(feature = "process")] -pub(crate) use linux_raw_sys::{ - general::{ - CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, F_RDLCK, - F_UNLCK, F_WRLCK, O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PGID, P_PID, P_PIDFD, SEEK_CUR, - SEEK_END, SEEK_SET, - }, - ioctl::TIOCSCTTY, -}; - -#[cfg(feature = "process")] -#[cfg(target_pointer_width = "32")] -pub(crate) use linux_raw_sys::general::{flock64 as flock, F_GETLK64}; - -#[cfg(feature = "process")] -#[cfg(target_pointer_width = "64")] -pub(crate) use linux_raw_sys::general::{flock, F_GETLK}; - -#[cfg(feature = "pty")] -pub(crate) use linux_raw_sys::ioctl::TIOCGPTPEER; - -#[cfg(feature = "termios")] -pub(crate) use linux_raw_sys::{ - general::{ - cc_t, speed_t, tcflag_t, termios, termios2, winsize, B0, B1000000, B110, B115200, B1152000, - B1200, B134, B150, B1500000, B1800, B19200, B200, B2000000, B230400, B2400, B2500000, B300, - B3000000, B3500000, B38400, B4000000, B460800, B4800, B50, B500000, B57600, B576000, B600, - B75, B921600, B9600, BOTHER, BRKINT, BS0, BS1, BSDLY, CBAUD, CBAUDEX, CIBAUD, CLOCAL, - CMSPAR, CR0, CR1, CR2, CR3, CRDLY, CREAD, CRTSCTS, CS5, CS6, CS7, CS8, CSIZE, CSTOPB, ECHO, - ECHOCTL, ECHOE, ECHOK, ECHOKE, ECHONL, ECHOPRT, EXTA, EXTB, EXTPROC, FF0, FF1, FFDLY, - FLUSHO, HUPCL, IBSHIFT, ICANON, ICRNL, IEXTEN, IGNBRK, IGNCR, IGNPAR, IMAXBEL, INLCR, - INPCK, ISIG, ISTRIP, IUCLC, IUTF8, IXANY, IXOFF, IXON, NCCS, NL0, NL1, NLDLY, NOFLSH, - OCRNL, OFDEL, OFILL, OLCUC, ONLCR, ONLRET, ONOCR, OPOST, PARENB, PARMRK, PARODD, PENDIN, - TAB0, TAB1, TAB2, TAB3, TABDLY, TCIFLUSH, TCIOFF, TCIOFLUSH, TCION, TCOFLUSH, TCOOFF, - TCOON, TCSADRAIN, TCSAFLUSH, TCSANOW, TOSTOP, VDISCARD, VEOF, VEOL, VEOL2, VERASE, VINTR, - VKILL, VLNEXT, VMIN, VQUIT, VREPRINT, VSTART, VSTOP, VSUSP, VSWTC, VT0, VT1, VTDLY, VTIME, - VWERASE, XCASE, XTABS, - }, - ioctl::{ - TCFLSH, TCGETS, TCGETS2, TCSBRK, TCSETS, TCSETS2, TCSETSF2, TCSETSW2, TCXONC, TIOCEXCL, - TIOCGPGRP, TIOCGSID, TIOCGWINSZ, TIOCNXCL, TIOCSPGRP, TIOCSWINSZ, - }, -}; - -// Define our own `uid_t` and `gid_t` if the kernel's versions are not 32-bit. -#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] -pub(crate) type uid_t = u32; -#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] -pub(crate) type gid_t = u32; - -// Bindgen infers `u32` for many of these macro types which meant to be -// used with `c_int` in the C APIs, so cast them to `c_int`. - -// Convert the signal constants from `u32` to `c_int`. -pub(crate) const SIGHUP: c_int = linux_raw_sys::general::SIGHUP as _; -pub(crate) const SIGINT: c_int = linux_raw_sys::general::SIGINT as _; -pub(crate) const SIGQUIT: c_int = linux_raw_sys::general::SIGQUIT as _; -pub(crate) const SIGILL: c_int = linux_raw_sys::general::SIGILL as _; -pub(crate) const SIGTRAP: c_int = linux_raw_sys::general::SIGTRAP as _; -pub(crate) const SIGABRT: c_int = linux_raw_sys::general::SIGABRT as _; -pub(crate) const SIGBUS: c_int = linux_raw_sys::general::SIGBUS as _; -pub(crate) const SIGFPE: c_int = linux_raw_sys::general::SIGFPE as _; -pub(crate) const SIGKILL: c_int = linux_raw_sys::general::SIGKILL as _; -pub(crate) const SIGUSR1: c_int = linux_raw_sys::general::SIGUSR1 as _; -pub(crate) const SIGSEGV: c_int = linux_raw_sys::general::SIGSEGV as _; -pub(crate) const SIGUSR2: c_int = linux_raw_sys::general::SIGUSR2 as _; -pub(crate) const SIGPIPE: c_int = linux_raw_sys::general::SIGPIPE as _; -pub(crate) const SIGALRM: c_int = linux_raw_sys::general::SIGALRM as _; -pub(crate) const SIGTERM: c_int = linux_raw_sys::general::SIGTERM as _; -#[cfg(not(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" -)))] -pub(crate) const SIGSTKFLT: c_int = linux_raw_sys::general::SIGSTKFLT as _; -pub(crate) const SIGCHLD: c_int = linux_raw_sys::general::SIGCHLD as _; -pub(crate) const SIGCONT: c_int = linux_raw_sys::general::SIGCONT as _; -pub(crate) const SIGSTOP: c_int = linux_raw_sys::general::SIGSTOP as _; -pub(crate) const SIGTSTP: c_int = linux_raw_sys::general::SIGTSTP as _; -pub(crate) const SIGTTIN: c_int = linux_raw_sys::general::SIGTTIN as _; -pub(crate) const SIGTTOU: c_int = linux_raw_sys::general::SIGTTOU as _; -pub(crate) const SIGURG: c_int = linux_raw_sys::general::SIGURG as _; -pub(crate) const SIGXCPU: c_int = linux_raw_sys::general::SIGXCPU as _; -pub(crate) const SIGXFSZ: c_int = linux_raw_sys::general::SIGXFSZ as _; -pub(crate) const SIGVTALRM: c_int = linux_raw_sys::general::SIGVTALRM as _; -pub(crate) const SIGPROF: c_int = linux_raw_sys::general::SIGPROF as _; -pub(crate) const SIGWINCH: c_int = linux_raw_sys::general::SIGWINCH as _; -pub(crate) const SIGIO: c_int = linux_raw_sys::general::SIGIO as _; -pub(crate) const SIGPWR: c_int = linux_raw_sys::general::SIGPWR as _; -pub(crate) const SIGSYS: c_int = linux_raw_sys::general::SIGSYS as _; -#[cfg(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" -))] -pub(crate) const SIGEMT: c_int = linux_raw_sys::general::SIGEMT as _; - -#[cfg(feature = "stdio")] -pub(crate) const STDIN_FILENO: c_int = linux_raw_sys::general::STDIN_FILENO as _; -#[cfg(feature = "stdio")] -pub(crate) const STDOUT_FILENO: c_int = linux_raw_sys::general::STDOUT_FILENO as _; -#[cfg(feature = "stdio")] -pub(crate) const STDERR_FILENO: c_int = linux_raw_sys::general::STDERR_FILENO as _; - -pub(crate) const PIPE_BUF: usize = linux_raw_sys::general::PIPE_BUF as _; - -pub(crate) const CLOCK_MONOTONIC: c_int = linux_raw_sys::general::CLOCK_MONOTONIC as _; -pub(crate) const CLOCK_REALTIME: c_int = linux_raw_sys::general::CLOCK_REALTIME as _; -pub(crate) const CLOCK_MONOTONIC_RAW: c_int = linux_raw_sys::general::CLOCK_MONOTONIC_RAW as _; -pub(crate) const CLOCK_MONOTONIC_COARSE: c_int = - linux_raw_sys::general::CLOCK_MONOTONIC_COARSE as _; -pub(crate) const CLOCK_REALTIME_COARSE: c_int = linux_raw_sys::general::CLOCK_REALTIME_COARSE as _; -pub(crate) const CLOCK_THREAD_CPUTIME_ID: c_int = - linux_raw_sys::general::CLOCK_THREAD_CPUTIME_ID as _; -pub(crate) const CLOCK_PROCESS_CPUTIME_ID: c_int = - linux_raw_sys::general::CLOCK_PROCESS_CPUTIME_ID as _; -#[cfg(any(feature = "thread", feature = "time"))] -pub(crate) const CLOCK_BOOTTIME: c_int = linux_raw_sys::general::CLOCK_BOOTTIME as _; -#[cfg(any(feature = "thread", feature = "time"))] -pub(crate) const CLOCK_BOOTTIME_ALARM: c_int = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM as _; -#[cfg(any(feature = "thread", feature = "time"))] -pub(crate) const CLOCK_TAI: c_int = linux_raw_sys::general::CLOCK_TAI as _; -#[cfg(any(feature = "thread", feature = "time"))] -pub(crate) const CLOCK_REALTIME_ALARM: c_int = linux_raw_sys::general::CLOCK_REALTIME_ALARM as _; - -#[cfg(feature = "system")] -mod reboot_symbols { - use super::c_int; - - pub(crate) const LINUX_REBOOT_MAGIC1: c_int = linux_raw_sys::general::LINUX_REBOOT_MAGIC1 as _; - pub(crate) const LINUX_REBOOT_MAGIC2: c_int = linux_raw_sys::general::LINUX_REBOOT_MAGIC2 as _; - - pub(crate) const LINUX_REBOOT_CMD_RESTART: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_RESTART as _; - pub(crate) const LINUX_REBOOT_CMD_HALT: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_HALT as _; - pub(crate) const LINUX_REBOOT_CMD_CAD_ON: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_CAD_ON as _; - pub(crate) const LINUX_REBOOT_CMD_CAD_OFF: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_CAD_OFF as _; - pub(crate) const LINUX_REBOOT_CMD_POWER_OFF: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_POWER_OFF as _; - pub(crate) const LINUX_REBOOT_CMD_SW_SUSPEND: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_SW_SUSPEND as _; - pub(crate) const LINUX_REBOOT_CMD_KEXEC: c_int = - linux_raw_sys::general::LINUX_REBOOT_CMD_KEXEC as _; -} -#[cfg(feature = "system")] -pub(crate) use reboot_symbols::*; - -#[cfg(any( - feature = "fs", - all( - linux_raw, - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) - ) -))] -mod statx_flags { - pub(crate) use linux_raw_sys::general::{ - STATX_ALL, STATX_ATIME, STATX_BASIC_STATS, STATX_BLOCKS, STATX_BTIME, STATX_CTIME, - STATX_DIOALIGN, STATX_GID, STATX_INO, STATX_MNT_ID, STATX_MODE, STATX_MTIME, STATX_NLINK, - STATX_SIZE, STATX_TYPE, STATX_UID, - }; - - pub(crate) use linux_raw_sys::general::{ - STATX_ATTR_APPEND, STATX_ATTR_AUTOMOUNT, STATX_ATTR_COMPRESSED, STATX_ATTR_DAX, - STATX_ATTR_ENCRYPTED, STATX_ATTR_IMMUTABLE, STATX_ATTR_MOUNT_ROOT, STATX_ATTR_NODUMP, - STATX_ATTR_VERITY, - }; -} -#[cfg(any( - feature = "fs", - all( - linux_raw, - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) - ) -))] -pub(crate) use statx_flags::*; diff --git a/vendor/rustix/src/backend/linux_raw/conv.rs b/vendor/rustix/src/backend/linux_raw/conv.rs deleted file mode 100644 index 901451ae..00000000 --- a/vendor/rustix/src/backend/linux_raw/conv.rs +++ /dev/null @@ -1,1021 +0,0 @@ -//! Convert values to [`ArgReg`] and from [`RetReg`]. -//! -//! System call arguments and return values are all communicated with inline -//! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping -//! or being accidentally misused as they travel through the code, we wrap them -//! in [`ArgReg`] and [`RetReg`] structs. This file provides `From` -//! implementations and explicit conversion functions for converting values -//! into and out of these wrapper structs. -//! -//! # Safety -//! -//! Some of this code is `unsafe` in order to work with raw file descriptors, -//! and some is `unsafe` to interpret the values in a `RetReg`. -#![allow(unsafe_code)] - -use super::c; -use super::fd::{AsRawFd as _, BorrowedFd, FromRawFd as _, RawFd}; -#[cfg(any(feature = "event", feature = "runtime", feature = "system"))] -use super::io::errno::try_decode_error; -#[cfg(target_pointer_width = "64")] -use super::io::errno::try_decode_u64; -#[cfg(not(debug_assertions))] -use super::io::errno::{ - decode_c_int_infallible, decode_c_uint_infallible, decode_usize_infallible, -}; -use super::io::errno::{ - try_decode_c_int, try_decode_c_uint, try_decode_raw_fd, try_decode_usize, try_decode_void, - try_decode_void_star, -}; -use super::reg::{raw_arg, ArgNumber, ArgReg, RetReg, R0}; -#[cfg(feature = "time")] -use super::time::types::TimerfdClockId; -#[cfg(any(feature = "thread", feature = "time"))] -use crate::clockid::ClockId; -use crate::fd::OwnedFd; -use crate::ffi::CStr; -use crate::io; -#[cfg(any(feature = "process", feature = "runtime", feature = "termios"))] -use crate::pid::Pid; -#[cfg(feature = "process")] -use crate::process::Resource; -#[cfg(any(feature = "process", feature = "runtime"))] -use crate::signal::Signal; -use crate::utils::{as_mut_ptr, as_ptr}; -use core::mem::MaybeUninit; -use core::ptr::null_mut; -#[cfg(any(feature = "thread", feature = "time"))] -use linux_raw_sys::general::__kernel_clockid_t; -#[cfg(target_pointer_width = "64")] -use linux_raw_sys::general::__kernel_loff_t; -#[cfg(feature = "net")] -use linux_raw_sys::net::socklen_t; - -/// Convert `SYS_*` constants for socketcall. -#[cfg(target_arch = "x86")] -#[inline] -pub(super) fn x86_sys<'a, Num: ArgNumber>(sys: u32) -> ArgReg<'a, Num> { - pass_usize(sys as usize) -} - -/// Pass the "low" half of the endian-specific memory encoding of a `u64`, for -/// 32-bit architectures. -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) fn lo<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> { - #[cfg(target_endian = "little")] - let x = x >> 32; - #[cfg(target_endian = "big")] - let x = x & 0xffff_ffff; - - pass_usize(x as usize) -} - -/// Pass the "high" half of the endian-specific memory encoding of a `u64`, for -/// 32-bit architectures. -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) fn hi<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> { - #[cfg(target_endian = "little")] - let x = x & 0xffff_ffff; - #[cfg(target_endian = "big")] - let x = x >> 32; - - pass_usize(x as usize) -} - -/// Pass a zero, or null, argument. -#[inline] -pub(super) fn zero<'a, Num: ArgNumber>() -> ArgReg<'a, Num> { - raw_arg(null_mut()) -} - -/// Pass the `mem::size_of` of a type. -#[inline] -pub(super) fn size_of<'a, T: Sized, Num: ArgNumber>() -> ArgReg<'a, Num> { - pass_usize(core::mem::size_of::<T>()) -} - -/// Pass an arbitrary `usize` value. -/// -/// For passing pointers, use `void_star` or other functions which take a raw -/// pointer instead of casting to `usize`, so that provenance is preserved. -#[inline] -pub(super) fn pass_usize<'a, Num: ArgNumber>(t: usize) -> ArgReg<'a, Num> { - raw_arg(t as *mut _) -} - -impl<'a, Num: ArgNumber, T> From<*mut T> for ArgReg<'a, Num> { - #[inline] - fn from(c: *mut T) -> Self { - raw_arg(c.cast()) - } -} - -impl<'a, Num: ArgNumber, T> From<*const T> for ArgReg<'a, Num> { - #[inline] - fn from(c: *const T) -> Self { - let mut_ptr = c as *mut T; - raw_arg(mut_ptr.cast()) - } -} - -impl<'a, Num: ArgNumber> From<&'a CStr> for ArgReg<'a, Num> { - #[inline] - fn from(c: &'a CStr) -> Self { - let mut_ptr = c.as_ptr() as *mut u8; - raw_arg(mut_ptr.cast()) - } -} - -impl<'a, Num: ArgNumber> From<Option<&'a CStr>> for ArgReg<'a, Num> { - #[inline] - fn from(t: Option<&'a CStr>) -> Self { - raw_arg(match t { - Some(s) => { - let mut_ptr = s.as_ptr() as *mut u8; - mut_ptr.cast() - } - None => null_mut(), - }) - } -} - -/// Pass a borrowed file-descriptor argument. -impl<'a, Num: ArgNumber> From<BorrowedFd<'a>> for ArgReg<'a, Num> { - #[inline] - fn from(fd: BorrowedFd<'a>) -> Self { - // SAFETY: `BorrowedFd` ensures that the file descriptor is valid, and - // the lifetime parameter on the resulting `ArgReg` ensures that the - // result is bounded by the `BorrowedFd`'s lifetime. - unsafe { raw_fd(fd.as_raw_fd()) } - } -} - -/// Pass a raw file-descriptor argument. Most users should use [`ArgReg::from`] -/// instead, to preserve I/O safety as long as possible. -/// -/// # Safety -/// -/// `fd` must be a valid open file descriptor. -#[inline] -pub(super) unsafe fn raw_fd<'a, Num: ArgNumber>(fd: RawFd) -> ArgReg<'a, Num> { - // Use `no_fd` when passing `-1` is intended. - #[cfg(feature = "fs")] - debug_assert!(fd == crate::fs::CWD.as_raw_fd() || fd == crate::fs::ABS.as_raw_fd() || fd >= 0); - - // Don't pass the `IORING_REGISTER_FILES_SKIP` sentry value this way. - #[cfg(feature = "io_uring")] - debug_assert_ne!(fd, crate::io_uring::IORING_REGISTER_FILES_SKIP.as_raw_fd()); - - // Linux doesn't look at the high bits beyond the `c_int`, so use - // zero-extension rather than sign-extension because it's a smaller - // instruction. - let fd: c::c_int = fd; - pass_usize(fd as c::c_uint as usize) -} - -/// Deliberately pass `-1` to a file-descriptor argument, for system calls -/// like `mmap` where this indicates the argument is omitted. -#[inline] -pub(super) fn no_fd<'a, Num: ArgNumber>() -> ArgReg<'a, Num> { - pass_usize(!0_usize) -} - -#[inline] -pub(super) fn slice_just_addr<T: Sized, Num: ArgNumber>(v: &[T]) -> ArgReg<'_, Num> { - let mut_ptr = v.as_ptr() as *mut T; - raw_arg(mut_ptr.cast()) -} - -#[inline] -pub(super) fn slice_just_addr_mut<T: Sized, Num: ArgNumber>(v: &mut [T]) -> ArgReg<'_, Num> { - raw_arg(v.as_mut_ptr().cast()) -} - -#[inline] -pub(super) fn slice<T: Sized, Num0: ArgNumber, Num1: ArgNumber>( - v: &[T], -) -> (ArgReg<'_, Num0>, ArgReg<'_, Num1>) { - (slice_just_addr(v), pass_usize(v.len())) -} - -#[inline] -pub(super) fn slice_mut<T: Sized, Num0: ArgNumber, Num1: ArgNumber>( - v: &mut [T], -) -> (ArgReg<'_, Num0>, ArgReg<'_, Num1>) { - (raw_arg(v.as_mut_ptr().cast()), pass_usize(v.len())) -} - -#[inline] -pub(super) fn by_ref<T: Sized, Num: ArgNumber>(t: &T) -> ArgReg<'_, Num> { - let mut_ptr = as_ptr(t) as *mut T; - raw_arg(mut_ptr.cast()) -} - -#[inline] -pub(super) fn by_mut<T: Sized, Num: ArgNumber>(t: &mut T) -> ArgReg<'_, Num> { - raw_arg(as_mut_ptr(t).cast()) -} - -/// Convert an optional mutable reference into a `usize` for passing to a -/// syscall. -#[inline] -pub(super) fn opt_mut<T: Sized, Num: ArgNumber>(t: Option<&mut T>) -> ArgReg<'_, Num> { - // This optimizes into the equivalent of `transmute(t)`, and has the - // advantage of not requiring `unsafe`. - match t { - Some(t) => by_mut(t), - None => raw_arg(null_mut()), - } -} - -/// Convert an optional immutable reference into a `usize` for passing to a -/// syscall. -#[inline] -pub(super) fn opt_ref<T: Sized, Num: ArgNumber>(t: Option<&T>) -> ArgReg<'_, Num> { - // This optimizes into the equivalent of `transmute(t)`, and has the - // advantage of not requiring `unsafe`. - match t { - Some(t) => by_ref(t), - None => raw_arg(null_mut()), - } -} - -/// Convert a `c_int` into an `ArgReg`. -/// -/// Be sure to use `raw_fd` to pass `RawFd` values. -#[inline] -pub(super) fn c_int<'a, Num: ArgNumber>(i: c::c_int) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -/// Convert a `c_uint` into an `ArgReg`. -#[inline] -pub(super) fn c_uint<'a, Num: ArgNumber>(i: c::c_uint) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn loff_t<'a, Num: ArgNumber>(i: __kernel_loff_t) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn loff_t_from_u64<'a, Num: ArgNumber>(i: u64) -> ArgReg<'a, Num> { - // `loff_t` is signed, but syscalls which expect `loff_t` return `EINVAL` - // if it's outside the signed `i64` range, so we can silently cast. - pass_usize(i as usize) -} - -#[cfg(any(feature = "thread", feature = "time"))] -impl<'a, Num: ArgNumber> From<ClockId> for ArgReg<'a, Num> { - #[inline] - fn from(i: ClockId) -> Self { - pass_usize(i as __kernel_clockid_t as usize) - } -} - -#[cfg(feature = "time")] -impl<'a, Num: ArgNumber> From<TimerfdClockId> for ArgReg<'a, Num> { - #[inline] - fn from(i: TimerfdClockId) -> Self { - pass_usize(i as __kernel_clockid_t as usize) - } -} - -#[cfg(feature = "net")] -#[inline] -pub(super) fn socklen_t<'a, Num: ArgNumber>(i: socklen_t) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -#[cfg(any( - feature = "fs", - all( - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) - ) -))] -pub(crate) mod fs { - use super::*; - use crate::fs::{FileType, Mode, OFlags}; - #[cfg(target_pointer_width = "32")] - use linux_raw_sys::general::O_LARGEFILE; - - impl<'a, Num: ArgNumber> From<Mode> for ArgReg<'a, Num> { - #[inline] - fn from(mode: Mode) -> Self { - pass_usize(mode.bits() as usize) - } - } - - impl<'a, Num: ArgNumber> From<(Mode, FileType)> for ArgReg<'a, Num> { - #[inline] - fn from(pair: (Mode, FileType)) -> Self { - pass_usize(pair.0.as_raw_mode() as usize | pair.1.as_raw_mode() as usize) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::AtFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::AtFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::XattrFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::XattrFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::inotify::CreateFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::inotify::CreateFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::inotify::WatchFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::inotify::WatchFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::MemfdFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::MemfdFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::RenameFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::RenameFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::StatxFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::StatxFlags) -> Self { - c_uint(flags.bits()) - } - } - - #[cfg(target_pointer_width = "32")] - #[inline] - fn oflags_bits(oflags: OFlags) -> c::c_uint { - let mut bits = oflags.bits(); - // Add `O_LARGEFILE`, unless `O_PATH` is set, as Linux returns `EINVAL` - // when both are set. - if !oflags.contains(OFlags::PATH) { - bits |= O_LARGEFILE; - } - bits - } - - #[cfg(target_pointer_width = "64")] - #[inline] - const fn oflags_bits(oflags: OFlags) -> c::c_uint { - oflags.bits() - } - - impl<'a, Num: ArgNumber> From<OFlags> for ArgReg<'a, Num> { - #[inline] - fn from(oflags: OFlags) -> Self { - pass_usize(oflags_bits(oflags) as usize) - } - } - - /// Convert an `OFlags` into a `u64` for use in the `open_how` struct. - #[inline] - pub(crate) fn oflags_for_open_how(oflags: OFlags) -> u64 { - u64::from(oflags_bits(oflags)) - } - - impl<'a, Num: ArgNumber> From<crate::fs::FallocateFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::FallocateFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::Advice> for ArgReg<'a, Num> { - #[inline] - fn from(advice: crate::fs::Advice) -> Self { - c_uint(advice as c::c_uint) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::SealFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::SealFlags) -> Self { - c_uint(flags.bits()) - } - } - - impl<'a, Num: ArgNumber> From<crate::fs::Access> for ArgReg<'a, Num> { - #[inline] - fn from(access: crate::fs::Access) -> Self { - c_uint(access.bits()) - } - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::MountFlagsArg> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::MountFlagsArg) -> Self { - c_uint(flags.0) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::UnmountFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::UnmountFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::mount::FsConfigCmd> for ArgReg<'a, Num> { - #[inline] - fn from(cmd: crate::mount::FsConfigCmd) -> Self { - c_uint(cmd as c::c_uint) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::FsOpenFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::FsOpenFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::FsMountFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::FsMountFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::MountAttrFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::MountAttrFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::OpenTreeFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::OpenTreeFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::FsPickFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::FsPickFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mount")] -impl<'a, Num: ArgNumber> From<crate::backend::mount::types::MoveMountFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mount::types::MoveMountFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From<crate::io::FdFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::FdFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "pipe")] -impl<'a, Num: ArgNumber> From<crate::pipe::PipeFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::pipe::PipeFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "pipe")] -impl<'a, Num: ArgNumber> From<crate::pipe::SpliceFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::pipe::SpliceFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From<crate::io::DupFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::DupFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From<crate::io::ReadWriteFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::ReadWriteFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "process")] -impl<'a, Num: ArgNumber> From<crate::process::PidfdFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::process::PidfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "pty")] -impl<'a, Num: ArgNumber> From<crate::pty::OpenptFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::pty::OpenptFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "thread")] -impl<'a, Num: ArgNumber> From<crate::thread::UnshareFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::thread::UnshareFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "event")] -impl<'a, Num: ArgNumber> From<crate::event::EventfdFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::event::EventfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "event")] -impl<'a, Num: ArgNumber> From<crate::event::epoll::CreateFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::event::epoll::CreateFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::ProtFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::ProtFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MsyncFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::MsyncFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MremapFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::MremapFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MlockFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::MlockFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MlockAllFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::MlockAllFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MapFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::MapFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::MprotectFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::MprotectFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "mm")] -impl<'a, Num: ArgNumber> From<crate::backend::mm::types::UserfaultfdFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::mm::types::UserfaultfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "thread")] -impl<'a, Num: ArgNumber> From<crate::backend::thread::types::MembarrierCommand> - for ArgReg<'a, Num> -{ - #[inline] - fn from(cmd: crate::backend::thread::types::MembarrierCommand) -> Self { - c_uint(cmd as u32) - } -} - -#[cfg(feature = "thread")] -impl<'a, Num: ArgNumber> From<crate::thread::Cpuid> for ArgReg<'a, Num> { - #[inline] - fn from(cpuid: crate::thread::Cpuid) -> Self { - c_uint(cpuid.as_raw()) - } -} - -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> ArgReg<'a, Num> { - pass_usize(dev as usize) -} - -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> io::Result<ArgReg<'a, Num>> { - Ok(pass_usize(dev.try_into().map_err(|_err| io::Errno::INVAL)?)) -} - -/// Convert a `Resource` into a syscall argument. -#[cfg(feature = "process")] -impl<'a, Num: ArgNumber> From<Resource> for ArgReg<'a, Num> { - #[inline] - fn from(resource: Resource) -> Self { - c_uint(resource as c::c_uint) - } -} - -#[cfg(any(feature = "process", feature = "runtime", feature = "termios"))] -impl<'a, Num: ArgNumber> From<Pid> for ArgReg<'a, Num> { - #[inline] - fn from(pid: Pid) -> Self { - pass_usize(pid.as_raw_nonzero().get() as usize) - } -} - -#[cfg(feature = "process")] -#[inline] -pub(super) fn negative_pid<'a, Num: ArgNumber>(pid: Pid) -> ArgReg<'a, Num> { - pass_usize(pid.as_raw_nonzero().get().wrapping_neg() as usize) -} - -#[cfg(any(feature = "process", feature = "runtime"))] -impl<'a, Num: ArgNumber> From<Signal> for ArgReg<'a, Num> { - #[inline] - fn from(sig: Signal) -> Self { - pass_usize(sig.as_raw() as usize) - } -} - -#[cfg(feature = "io_uring")] -impl<'a, Num: ArgNumber> From<crate::io_uring::IoringEnterFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io_uring::IoringEnterFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "time")] -impl<'a, Num: ArgNumber> From<crate::time::TimerfdFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::time::TimerfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "time")] -impl<'a, Num: ArgNumber> From<crate::time::TimerfdTimerFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::time::TimerfdTimerFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "rand")] -impl<'a, Num: ArgNumber> From<crate::rand::GetRandomFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::rand::GetRandomFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<crate::net::RecvFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::net::RecvFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<crate::net::SendFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::net::SendFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<crate::net::SocketFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::net::SocketFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<crate::net::AddressFamily> for ArgReg<'a, Num> { - #[inline] - fn from(family: crate::net::AddressFamily) -> Self { - c_uint(family.0.into()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<(crate::net::SocketType, crate::net::SocketFlags)> - for ArgReg<'a, Num> -{ - #[inline] - fn from(pair: (crate::net::SocketType, crate::net::SocketFlags)) -> Self { - c_uint(pair.0 .0 | pair.1.bits()) - } -} - -#[cfg(feature = "thread")] -impl<'a, Num: ArgNumber> - From<( - crate::backend::thread::futex::Operation, - crate::thread::futex::Flags, - )> for ArgReg<'a, Num> -{ - #[inline] - fn from( - pair: ( - crate::backend::thread::futex::Operation, - crate::thread::futex::Flags, - ), - ) -> Self { - c_uint(pair.0 as u32 | pair.1.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<crate::net::SocketType> for ArgReg<'a, Num> { - #[inline] - fn from(type_: crate::net::SocketType) -> Self { - c_uint(type_.0) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<Option<crate::net::Protocol>> for ArgReg<'a, Num> { - #[inline] - fn from(protocol: Option<crate::net::Protocol>) -> Self { - c_uint(match protocol { - Some(p) => p.0.get(), - None => 0, - }) - } -} - -impl<'a, Num: ArgNumber, T> From<&'a mut MaybeUninit<T>> for ArgReg<'a, Num> { - #[inline] - fn from(t: &'a mut MaybeUninit<T>) -> Self { - raw_arg(t.as_mut_ptr().cast()) - } -} - -impl<'a, Num: ArgNumber, T> From<&'a mut [MaybeUninit<T>]> for ArgReg<'a, Num> { - #[inline] - fn from(t: &'a mut [MaybeUninit<T>]) -> Self { - raw_arg(t.as_mut_ptr().cast()) - } -} - -#[cfg(any(feature = "process", feature = "thread"))] -impl<'a, Num: ArgNumber> From<crate::ugid::Uid> for ArgReg<'a, Num> { - #[inline] - fn from(t: crate::ugid::Uid) -> Self { - c_uint(t.as_raw()) - } -} - -#[cfg(any(feature = "process", feature = "thread"))] -impl<'a, Num: ArgNumber> From<crate::ugid::Gid> for ArgReg<'a, Num> { - #[inline] - fn from(t: crate::ugid::Gid) -> Self { - c_uint(t.as_raw()) - } -} - -#[cfg(feature = "runtime")] -impl<'a, Num: ArgNumber> From<crate::runtime::How> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::runtime::How) -> Self { - c_uint(flags as u32) - } -} - -/// Convert a `usize` returned from a syscall that effectively returns `()` on -/// success. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// just returns 0 on success. -#[inline] -pub(super) unsafe fn ret(raw: RetReg<R0>) -> io::Result<()> { - try_decode_void(raw) -} - -/// Convert a `usize` returned from a syscall that doesn't return on success. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// doesn't return on success. -#[cfg(any(feature = "event", feature = "runtime", feature = "system"))] -#[inline] -pub(super) unsafe fn ret_error(raw: RetReg<R0>) -> io::Errno { - try_decode_error(raw) -} - -/// Convert a `usize` returned from a syscall that effectively always returns -/// `()`. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// always returns `()`. -#[inline] -pub(super) unsafe fn ret_infallible(raw: RetReg<R0>) { - #[cfg(debug_assertions)] - { - try_decode_void(raw).unwrap() - } - #[cfg(not(debug_assertions))] - drop(raw); -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `c_int` on success. -#[inline] -pub(super) fn ret_c_int(raw: RetReg<R0>) -> io::Result<c::c_int> { - try_decode_c_int(raw) -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `c_uint` on success. -#[inline] -pub(super) fn ret_c_uint(raw: RetReg<R0>) -> io::Result<c::c_uint> { - try_decode_c_uint(raw) -} - -/// Convert a `usize` returned from a syscall that effectively returns a `u64` -/// on success. -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn ret_u64(raw: RetReg<R0>) -> io::Result<u64> { - try_decode_u64(raw) -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `usize` on success. -#[inline] -pub(super) fn ret_usize(raw: RetReg<R0>) -> io::Result<usize> { - try_decode_usize(raw) -} - -/// Convert a `usize` returned from a syscall that effectively always -/// returns a `usize`. -/// -/// # Safety -/// -/// This function must only be used with return values from infallible -/// syscalls. -#[inline] -pub(super) unsafe fn ret_usize_infallible(raw: RetReg<R0>) -> usize { - #[cfg(debug_assertions)] - { - try_decode_usize(raw).unwrap() - } - #[cfg(not(debug_assertions))] - { - decode_usize_infallible(raw) - } -} - -/// Convert a `c_int` returned from a syscall that effectively always -/// returns a `c_int`. -/// -/// # Safety -/// -/// This function must only be used with return values from infallible -/// syscalls. -#[inline] -pub(super) unsafe fn ret_c_int_infallible(raw: RetReg<R0>) -> c::c_int { - #[cfg(debug_assertions)] - { - try_decode_c_int(raw).unwrap() - } - #[cfg(not(debug_assertions))] - { - decode_c_int_infallible(raw) - } -} - -/// Convert a `c_uint` returned from a syscall that effectively always -/// returns a `c_uint`. -/// -/// # Safety -/// -/// This function must only be used with return values from infallible -/// syscalls. -#[inline] -pub(super) unsafe fn ret_c_uint_infallible(raw: RetReg<R0>) -> c::c_uint { - #[cfg(debug_assertions)] - { - try_decode_c_uint(raw).unwrap() - } - #[cfg(not(debug_assertions))] - { - decode_c_uint_infallible(raw) - } -} - -/// Convert a `usize` returned from a syscall that effectively returns an -/// `OwnedFd` on success. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// returns an owned file descriptor. -#[inline] -pub(super) unsafe fn ret_owned_fd(raw: RetReg<R0>) -> io::Result<OwnedFd> { - let raw_fd = try_decode_raw_fd(raw)?; - Ok(crate::backend::fd::OwnedFd::from_raw_fd(raw_fd)) -} - -/// Convert the return value of `dup2` and `dup3`. -/// -/// When these functions succeed, they return the same value as their second -/// argument, so we don't construct a new `OwnedFd`. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// returns a file descriptor. -#[inline] -pub(super) unsafe fn ret_discarded_fd(raw: RetReg<R0>) -> io::Result<()> { - let _raw_fd = try_decode_raw_fd(raw)?; - Ok(()) -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `*mut c_void` on success. -#[inline] -pub(super) fn ret_void_star(raw: RetReg<R0>) -> io::Result<*mut c::c_void> { - try_decode_void_star(raw) -} diff --git a/vendor/rustix/src/backend/linux_raw/event/epoll.rs b/vendor/rustix/src/backend/linux_raw/event/epoll.rs deleted file mode 100644 index 093129db..00000000 --- a/vendor/rustix/src/backend/linux_raw/event/epoll.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `EPOLL_*` for use with [`epoll::create`]. - /// - /// [`epoll::create`]: crate::event::epoll::create - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CreateFlags: ffi::c_uint { - /// `EPOLL_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::EPOLL_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `EPOLL*` for use with [`epoll::add`]. - /// - /// [`epoll::add`]: crate::event::epoll::add - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct EventFlags: u32 { - /// `EPOLLIN` - const IN = linux_raw_sys::general::EPOLLIN as u32; - - /// `EPOLLOUT` - const OUT = linux_raw_sys::general::EPOLLOUT as u32; - - /// `EPOLLPRI` - const PRI = linux_raw_sys::general::EPOLLPRI as u32; - - /// `EPOLLERR` - const ERR = linux_raw_sys::general::EPOLLERR as u32; - - /// `EPOLLHUP` - const HUP = linux_raw_sys::general::EPOLLHUP as u32; - - /// `EPOLLRDNORM` - const RDNORM = linux_raw_sys::general::EPOLLRDNORM as u32; - - /// `EPOLLRDBAND` - const RDBAND = linux_raw_sys::general::EPOLLRDBAND as u32; - - /// `EPOLLWRNORM` - const WRNORM = linux_raw_sys::general::EPOLLWRNORM as u32; - - /// `EPOLLWRBAND` - const WRBAND = linux_raw_sys::general::EPOLLWRBAND as u32; - - /// `EPOLLMSG` - const MSG = linux_raw_sys::general::EPOLLMSG as u32; - - /// `EPOLLRDHUP` - const RDHUP = linux_raw_sys::general::EPOLLRDHUP as u32; - - /// `EPOLLET` - const ET = linux_raw_sys::general::EPOLLET as u32; - - /// `EPOLLONESHOT` - const ONESHOT = linux_raw_sys::general::EPOLLONESHOT as u32; - - /// `EPOLLWAKEUP` - const WAKEUP = linux_raw_sys::general::EPOLLWAKEUP as u32; - - /// `EPOLLEXCLUSIVE` - const EXCLUSIVE = linux_raw_sys::general::EPOLLEXCLUSIVE as u32; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/event/mod.rs b/vendor/rustix/src/backend/linux_raw/event/mod.rs deleted file mode 100644 index 605de253..00000000 --- a/vendor/rustix/src/backend/linux_raw/event/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod epoll; -pub(crate) mod poll_fd; -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs deleted file mode 100644 index 9de43f26..00000000 --- a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::fd::{AsFd, BorrowedFd}; -use bitflags::bitflags; - -bitflags! { - /// `POLL*` flags for use with [`poll`]. - /// - /// [`poll`]: crate::event::poll - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PollFlags: u16 { - /// `POLLIN` - const IN = linux_raw_sys::general::POLLIN as u16; - /// `POLLPRI` - const PRI = linux_raw_sys::general::POLLPRI as u16; - /// `POLLOUT` - const OUT = linux_raw_sys::general::POLLOUT as u16; - /// `POLLRDNORM` - const RDNORM = linux_raw_sys::general::POLLRDNORM as u16; - /// `POLLWRNORM` - const WRNORM = linux_raw_sys::general::POLLWRNORM as u16; - /// `POLLRDBAND` - const RDBAND = linux_raw_sys::general::POLLRDBAND as u16; - /// `POLLWRBAND` - const WRBAND = linux_raw_sys::general::POLLWRBAND as u16; - /// `POLLERR` - const ERR = linux_raw_sys::general::POLLERR as u16; - /// `POLLHUP` - const HUP = linux_raw_sys::general::POLLHUP as u16; - /// `POLLNVAL` - const NVAL = linux_raw_sys::general::POLLNVAL as u16; - /// `POLLRDHUP` - const RDHUP = linux_raw_sys::general::POLLRDHUP as u16; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `struct pollfd`—File descriptor and flags for use with [`poll`]. -/// -/// [`poll`]: crate::event::poll -#[doc(alias = "pollfd")] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct PollFd<'fd> { - pub(crate) fd: BorrowedFd<'fd>, - pub(crate) events: u16, - pub(crate) revents: u16, -} - -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.fd = fd.as_fd(); - } - - /// Clears the ready events. - #[inline] - pub fn clear_revents(&mut self) { - self.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 { - fd, - events: events.bits(), - revents: 0, - } - } - - /// 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.revents).unwrap() - } -} - -impl<'fd> AsFd for PollFd<'fd> { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.fd.as_fd() - } -} diff --git a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs deleted file mode 100644 index 8a4e24bd..00000000 --- a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs +++ /dev/null @@ -1,358 +0,0 @@ -//! linux_raw syscalls supporting `rustix::event`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{ - by_ref, c_int, c_uint, opt_mut, opt_ref, pass_usize, ret, ret_c_int, ret_error, ret_owned_fd, - ret_usize, size_of, slice_mut, zero, -}; -use crate::event::{epoll, EventfdFlags, FdSetElement, PollFd, Timespec}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use core::ptr::null_mut; -use linux_raw_sys::general::{kernel_sigset_t, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}; - -#[inline] -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: Option<&Timespec>) -> io::Result<usize> { - let (fds_addr_mut, fds_len) = slice_mut(fds); - - #[cfg(target_pointer_width = "32")] - unsafe { - // If we don't have Linux 5.1, and the timeout fits in a - // `__kernel_old_timespec`, use plain `ppoll`. - // - // We do this unconditionally, rather than trying `ppoll_time64` and - // falling back on `Errno::NOSYS`, because seccomp configurations will - // sometimes abort the process on syscalls they don't recognize. - #[cfg(not(feature = "linux_5_1"))] - { - use linux_raw_sys::general::__kernel_old_timespec; - - // If we don't have a timeout, or if we can convert the timeout to - // a `__kernel_old_timespec`, the use `__NR_ppoll`. - fn convert(timeout: &Timespec) -> Option<__kernel_old_timespec> { - Some(__kernel_old_timespec { - tv_sec: timeout.tv_sec.try_into().ok()?, - tv_nsec: timeout.tv_nsec.try_into().ok()?, - }) - } - let old_timeout = if let Some(timeout) = timeout { - match convert(timeout) { - // Could not convert timeout. - None => None, - // Could convert timeout. Ok! - Some(old_timeout) => Some(Some(old_timeout)), - } - } else { - // No timeout. Ok! - Some(None) - }; - if let Some(mut old_timeout) = old_timeout { - // Call `ppoll`. - // - // Linux's `ppoll` mutates the timeout argument. Our public - // interface does not do this, because it's not portable to other - // platforms, so we create a temporary value to hide this behavior. - return ret_usize(syscall!( - __NR_ppoll, - fds_addr_mut, - fds_len, - opt_mut(old_timeout.as_mut()), - zero(), - size_of::<kernel_sigset_t, _>() - )); - } - } - - // We either have Linux 5.1 or the timeout didn't fit in - // `__kernel_old_timespec` so `__NR_ppoll_time64` will either - // succeed or fail due to our having no other options. - - // Call `ppoll_time64`. - // - // Linux's `ppoll_time64` mutates the timeout argument. Our public - // interface does not do this, because it's not portable to other - // platforms, so we create a temporary value to hide this behavior. - ret_usize(syscall!( - __NR_ppoll_time64, - fds_addr_mut, - fds_len, - opt_mut(timeout.copied().as_mut()), - zero(), - size_of::<kernel_sigset_t, _>() - )) - } - - #[cfg(target_pointer_width = "64")] - unsafe { - // Call `ppoll`. - // - // Linux's `ppoll` mutates the timeout argument. Our public interface - // does not do this, because it's not portable to other platforms, so - // we create a temporary value to hide this behavior. - ret_usize(syscall!( - __NR_ppoll, - fds_addr_mut, - fds_len, - opt_mut(timeout.copied().as_mut()), - zero(), - size_of::<kernel_sigset_t, _>() - )) - } -} - -pub(crate) unsafe fn select( - nfds: i32, - readfds: Option<&mut [FdSetElement]>, - writefds: Option<&mut [FdSetElement]>, - exceptfds: Option<&mut [FdSetElement]>, - timeout: Option<&crate::timespec::Timespec>, -) -> io::Result<i32> { - let len = crate::event::fd_set_num_elements_for_bitvector(nfds); - - let readfds = match readfds { - Some(readfds) => { - assert!(readfds.len() >= len); - readfds.as_mut_ptr() - } - None => null_mut(), - }; - let writefds = match writefds { - Some(writefds) => { - assert!(writefds.len() >= len); - writefds.as_mut_ptr() - } - None => null_mut(), - }; - let exceptfds = match exceptfds { - Some(exceptfds) => { - assert!(exceptfds.len() >= len); - exceptfds.as_mut_ptr() - } - None => null_mut(), - }; - - #[cfg(target_pointer_width = "32")] - { - // If we don't have Linux 5.1, and the timeout fits in a - // `__kernel_old_timespec`, use plain `pselect6`. - // - // We do this unconditionally, rather than trying `pselect6_time64` and - // falling back on `Errno::NOSYS`, because seccomp configurations will - // sometimes abort the process on syscalls they don't recognize. - #[cfg(not(feature = "linux_5_1"))] - { - use linux_raw_sys::general::__kernel_old_timespec; - - // If we don't have a timeout, or if we can convert the timeout to - // a `__kernel_old_timespec`, the use `__NR_pselect6`. - fn convert(timeout: &Timespec) -> Option<__kernel_old_timespec> { - Some(__kernel_old_timespec { - tv_sec: timeout.tv_sec.try_into().ok()?, - tv_nsec: timeout.tv_nsec.try_into().ok()?, - }) - } - let old_timeout = if let Some(timeout) = timeout { - match convert(timeout) { - // Could not convert timeout. - None => None, - // Could convert timeout. Ok! - Some(old_timeout) => Some(Some(old_timeout)), - } - } else { - // No timeout. Ok! - Some(None) - }; - if let Some(mut old_timeout) = old_timeout { - // Call `pselect6`. - // - // Linux's `pselect6` mutates the timeout argument. Our public - // interface does not do this, because it's not portable to other - // platforms, so we create a temporary value to hide this behavior. - return ret_c_int(syscall!( - __NR_pselect6, - c_int(nfds), - readfds, - writefds, - exceptfds, - opt_mut(old_timeout.as_mut()), - zero() - )); - } - } - - // We either have Linux 5.1 or the timeout didn't fit in - // `__kernel_old_timespec` so `__NR_pselect6_time64` will either - // succeed or fail due to our having no other options. - - // Call `pselect6_time64`. - // - // Linux's `pselect6_time64` mutates the timeout argument. Our public - // interface does not do this, because it's not portable to other - // platforms, so we create a temporary value to hide this behavior. - ret_c_int(syscall!( - __NR_pselect6_time64, - c_int(nfds), - readfds, - writefds, - exceptfds, - opt_mut(timeout.copied().as_mut()), - zero() - )) - } - - #[cfg(target_pointer_width = "64")] - { - // Call `pselect6`. - // - // Linux's `pselect6` mutates the timeout argument. Our public interface - // does not do this, because it's not portable to other platforms, so we - // create a temporary value to hide this behavior. - ret_c_int(syscall!( - __NR_pselect6, - c_int(nfds), - readfds, - writefds, - exceptfds, - opt_mut(timeout.copied().as_mut()), - zero() - )) - } -} - -#[inline] -pub(crate) fn epoll_create(flags: epoll::CreateFlags) -> io::Result<OwnedFd> { - // SAFETY: `__NR_epoll_create1` doesn't access any user memory. - unsafe { ret_owned_fd(syscall_readonly!(__NR_epoll_create1, flags)) } -} - -#[inline] -pub(crate) fn epoll_add( - epfd: BorrowedFd<'_>, - fd: BorrowedFd<'_>, - event: &epoll::Event, -) -> io::Result<()> { - // SAFETY: `__NR_epoll_ctl` with `EPOLL_CTL_ADD` doesn't modify any user - // memory, and it only reads from `event`. - unsafe { - ret(syscall_readonly!( - __NR_epoll_ctl, - epfd, - c_uint(EPOLL_CTL_ADD), - fd, - by_ref(event) - )) - } -} - -#[inline] -pub(crate) fn epoll_mod( - epfd: BorrowedFd<'_>, - fd: BorrowedFd<'_>, - event: &epoll::Event, -) -> io::Result<()> { - // SAFETY: `__NR_epoll_ctl` with `EPOLL_CTL_MOD` doesn't modify any user - // memory, and it only reads from `event`. - unsafe { - ret(syscall_readonly!( - __NR_epoll_ctl, - epfd, - c_uint(EPOLL_CTL_MOD), - fd, - by_ref(event) - )) - } -} - -#[inline] -pub(crate) fn epoll_del(epfd: BorrowedFd<'_>, fd: BorrowedFd<'_>) -> io::Result<()> { - // SAFETY: `__NR_epoll_ctl` with `EPOLL_CTL_DEL` doesn't access any user - // memory. - unsafe { - ret(syscall_readonly!( - __NR_epoll_ctl, - epfd, - c_uint(EPOLL_CTL_DEL), - fd, - zero() - )) - } -} - -#[inline] -pub(crate) unsafe fn epoll_wait( - epfd: BorrowedFd<'_>, - events: (*mut crate::event::epoll::Event, usize), - timeout: Option<&Timespec>, -) -> io::Result<usize> { - // If we don't have Linux 5.1, and the timeout fits in an `i32`, use plain - // `epoll_pwait`. - // - // We do this unconditionally, rather than trying `epoll_pwait2` and - // falling back on `Errno::NOSYS`, because seccomp configurations will - // sometimes abort the process on syscalls they don't recognize. - #[cfg(not(feature = "linux_5_11"))] - { - // If we don't have a timeout, or if we can convert the timeout to an - // `i32`, the use `__NR_epoll_pwait`. - let old_timeout = if let Some(timeout) = timeout { - // Try to convert the timeout; if this is `Some`, we're ok! - timeout.as_c_int_millis() - } else { - // No timeout. Ok! - Some(-1) - }; - if let Some(old_timeout) = old_timeout { - // Call `epoll_pwait`. - return ret_usize(syscall!( - __NR_epoll_pwait, - epfd, - events.0, - pass_usize(events.1), - c_int(old_timeout), - zero() - )); - } - } - - // Call `epoll_pwait2`. - // - // We either have Linux 5.1 or the timeout didn't fit in an `i32`, so - // `__NR_epoll_pwait2` will either succeed or fail due to our having no - // other options. - ret_usize(syscall!( - __NR_epoll_pwait2, - epfd, - events.0, - pass_usize(events.1), - opt_ref(timeout), - zero() - )) -} - -#[inline] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } -} - -#[inline] -pub(crate) fn pause() { - unsafe { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - let error = ret_error(syscall_readonly!( - __NR_ppoll, - zero(), - zero(), - zero(), - zero() - )); - - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - let error = ret_error(syscall_readonly!(__NR_pause)); - - debug_assert_eq!(error, io::Errno::INTR); - } -} diff --git a/vendor/rustix/src/backend/linux_raw/event/types.rs b/vendor/rustix/src/backend/linux_raw/event/types.rs deleted file mode 100644 index 9d320dfe..00000000 --- a/vendor/rustix/src/backend/linux_raw/event/types.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `EFD_*` flags for use with [`eventfd`]. - /// - /// [`eventfd`]: crate::event::eventfd - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct EventfdFlags: ffi::c_uint { - /// `EFD_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::EFD_CLOEXEC; - /// `EFD_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::EFD_NONBLOCK; - /// `EFD_SEMAPHORE` - const SEMAPHORE = linux_raw_sys::general::EFD_SEMAPHORE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/fs/dir.rs b/vendor/rustix/src/backend/linux_raw/fs/dir.rs deleted file mode 100644 index 31ebc543..00000000 --- a/vendor/rustix/src/backend/linux_raw/fs/dir.rs +++ /dev/null @@ -1,373 +0,0 @@ -use crate::fd::{AsFd, BorrowedFd, OwnedFd}; -use crate::ffi::{CStr, CString}; -use crate::fs::{ - fcntl_getfl, fstat, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, Stat, StatFs, StatVfs, -}; -use crate::io; -#[cfg(feature = "process")] -use crate::process::fchdir; -use crate::utils::as_ptr; -use alloc::borrow::ToOwned as _; -use alloc::vec::Vec; -use core::fmt; -use core::mem::size_of; -use linux_raw_sys::general::{linux_dirent64, SEEK_SET}; - -/// `DIR*` -pub struct Dir { - /// The `OwnedFd` that we read directory entries from. - fd: OwnedFd, - - /// Have we seen any errors in this iteration? - any_errors: bool, - - /// Should we rewind the stream on the next iteration? - rewind: bool, - - /// The buffer for `linux_dirent64` entries. - buf: Vec<u8>, - - /// Where we are in the buffer. - pos: usize, -} - -impl Dir { - /// Take ownership of `fd` and construct a `Dir` that reads entries from - /// the given directory file descriptor. - #[inline] - pub fn new<Fd: Into<OwnedFd>>(fd: Fd) -> io::Result<Self> { - Self::_new(fd.into()) - } - - #[inline] - fn _new(fd: OwnedFd) -> io::Result<Self> { - Ok(Self { - fd, - any_errors: false, - rewind: false, - buf: Vec::new(), - pos: 0, - }) - } - - /// Borrow `fd` and construct a `Dir` that reads entries from the given - /// directory file descriptor. - #[inline] - pub fn read_from<Fd: AsFd>(fd: Fd) -> io::Result<Self> { - Self::_read_from(fd.as_fd()) - } - - #[inline] - fn _read_from(fd: BorrowedFd<'_>) -> io::Result<Self> { - let flags = fcntl_getfl(fd)?; - let fd_for_dir = openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; - - Ok(Self { - fd: fd_for_dir, - any_errors: false, - rewind: false, - buf: Vec::new(), - pos: 0, - }) - } - - /// `rewinddir(self)` - #[inline] - pub fn rewind(&mut self) { - self.any_errors = false; - self.rewind = true; - self.pos = self.buf.len(); - } - - /// `seekdir(self, offset)` - /// - /// This function is only available on 64-bit platforms because it's - /// implemented using [`libc::seekdir`] which only supports offsets that - /// fit in a `c_long`. - /// - /// [`libc::seekdir`]: https://docs.rs/libc/*/arm-unknown-linux-gnueabihf/libc/fn.seekdir.html - // In the linux_raw backend here, we don't use `libc::seekdir` and don't - // have this limitation, but it's a goal of rustix to support the same API - // on both the linux_raw and libc backends. - #[cfg(target_pointer_width = "64")] - #[cfg_attr(docsrs, doc(cfg(target_pointer_width = "64")))] - #[doc(alias = "seekdir")] - #[inline] - pub fn seek(&mut self, offset: i64) -> io::Result<()> { - self.any_errors = false; - self.rewind = false; - self.pos = self.buf.len(); - match io::retry_on_intr(|| { - crate::backend::fs::syscalls::_seek(self.fd.as_fd(), offset, SEEK_SET) - }) { - Ok(_) => Ok(()), - Err(err) => { - self.any_errors = true; - Err(err) - } - } - } - - /// `readdir(self)`, where `None` means the end of the directory. - pub fn read(&mut self) -> Option<io::Result<DirEntry>> { - // If we've seen errors, don't continue to try to read anything - // further. - if self.any_errors { - return None; - } - - // If a rewind was requested, seek to the beginning. - if self.rewind { - self.rewind = false; - match io::retry_on_intr(|| { - crate::backend::fs::syscalls::_seek(self.fd.as_fd(), 0, SEEK_SET) - }) { - Ok(_) => (), - Err(err) => { - self.any_errors = true; - return Some(Err(err)); - } - } - } - - // Compute linux_dirent64 field offsets. - let z = linux_dirent64 { - d_ino: 0_u64, - d_off: 0_i64, - d_type: 0_u8, - d_reclen: 0_u16, - d_name: Default::default(), - }; - let base = as_ptr(&z) as usize; - let offsetof_d_reclen = (as_ptr(&z.d_reclen) as usize) - base; - let offsetof_d_name = (as_ptr(&z.d_name) as usize) - base; - let offsetof_d_ino = (as_ptr(&z.d_ino) as usize) - base; - let offsetof_d_off = (as_ptr(&z.d_off) as usize) - base; - let offsetof_d_type = (as_ptr(&z.d_type) as usize) - base; - - // Test if we need more entries, and if so, read more. - if self.buf.len() - self.pos < size_of::<linux_dirent64>() { - match self.read_more()? { - Ok(()) => (), - Err(err) => return Some(Err(err)), - } - } - - // We successfully read an entry. Extract the fields. - let pos = self.pos; - - // Do an unaligned u16 load. - let d_reclen = u16::from_ne_bytes([ - self.buf[pos + offsetof_d_reclen], - self.buf[pos + offsetof_d_reclen + 1], - ]); - assert!(self.buf.len() - pos >= d_reclen as usize); - self.pos += d_reclen as usize; - - // Read the NUL-terminated name from the `d_name` field. Without - // `unsafe`, we need to scan for the NUL twice: once to obtain a size - // for the slice, and then once within `CStr::from_bytes_with_nul`. - let name_start = pos + offsetof_d_name; - let name_len = self.buf[name_start..] - .iter() - .position(|x| *x == b'\0') - .unwrap(); - let name = CStr::from_bytes_with_nul(&self.buf[name_start..][..=name_len]).unwrap(); - let name = name.to_owned(); - assert!(name.as_bytes().len() <= self.buf.len() - name_start); - - // Do an unaligned `u64` load for `d_ino`. - let d_ino = u64::from_ne_bytes([ - self.buf[pos + offsetof_d_ino], - self.buf[pos + offsetof_d_ino + 1], - self.buf[pos + offsetof_d_ino + 2], - self.buf[pos + offsetof_d_ino + 3], - self.buf[pos + offsetof_d_ino + 4], - self.buf[pos + offsetof_d_ino + 5], - self.buf[pos + offsetof_d_ino + 6], - self.buf[pos + offsetof_d_ino + 7], - ]); - - // Do an unaligned `i64` load for `d_off`. - let d_off = i64::from_ne_bytes([ - self.buf[pos + offsetof_d_off], - self.buf[pos + offsetof_d_off + 1], - self.buf[pos + offsetof_d_off + 2], - self.buf[pos + offsetof_d_off + 3], - self.buf[pos + offsetof_d_off + 4], - self.buf[pos + offsetof_d_off + 5], - self.buf[pos + offsetof_d_off + 6], - self.buf[pos + offsetof_d_off + 7], - ]); - - let d_type = self.buf[pos + offsetof_d_type]; - - // Check that our types correspond to the `linux_dirent64` types. - let _ = linux_dirent64 { - d_ino, - d_off, - d_type, - d_reclen, - d_name: Default::default(), - }; - - Some(Ok(DirEntry { - d_ino, - d_off, - d_type, - name, - })) - } - - #[must_use] - fn read_more(&mut self) -> Option<io::Result<()>> { - // The first few times we're called, we allocate a relatively small - // buffer, because many directories are small. If we're called more, - // use progressively larger allocations, up to a fixed maximum. - // - // The specific sizes and policy here have not been tuned in detail yet - // and may need to be adjusted. In doing so, we should be careful to - // avoid unbounded buffer growth. This buffer only exists to share the - // cost of a `getdents` call over many entries, so if it gets too big, - // cache and heap usage will outweigh the benefit. And ultimately, - // directories can contain more entries than we can allocate contiguous - // memory for, so we'll always need to cap the size at some point. - if self.buf.len() < 1024 * size_of::<linux_dirent64>() { - self.buf.reserve(32 * size_of::<linux_dirent64>()); - } - self.buf.resize(self.buf.capacity(), 0); - let nread = match io::retry_on_intr(|| { - crate::backend::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) - }) { - Ok(nread) => nread, - Err(io::Errno::NOENT) => { - self.any_errors = true; - return None; - } - Err(err) => { - self.any_errors = true; - return Some(Err(err)); - } - }; - self.buf.resize(nread, 0); - self.pos = 0; - if nread == 0 { - None - } else { - Some(Ok(())) - } - } - - /// `fstat(self)` - #[inline] - pub fn stat(&self) -> io::Result<Stat> { - fstat(&self.fd) - } - - /// `fstatfs(self)` - #[inline] - pub fn statfs(&self) -> io::Result<StatFs> { - fstatfs(&self.fd) - } - - /// `fstatvfs(self)` - #[inline] - pub fn statvfs(&self) -> io::Result<StatVfs> { - fstatvfs(&self.fd) - } - - /// `fchdir(self)` - #[cfg(feature = "process")] - #[cfg_attr(docsrs, doc(cfg(feature = "process")))] - #[inline] - pub fn chdir(&self) -> io::Result<()> { - fchdir(&self.fd) - } -} - -impl Iterator for Dir { - type Item = io::Result<DirEntry>; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - Self::read(self) - } -} - -impl fmt::Debug for Dir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Dir").field("fd", &self.fd).finish() - } -} - -/// `struct dirent` -#[derive(Debug)] -pub struct DirEntry { - d_ino: u64, - d_type: u8, - d_off: i64, - name: CString, -} - -impl DirEntry { - /// Returns the file name of this directory entry. - #[inline] - pub fn file_name(&self) -> &CStr { - &self.name - } - - /// Returns the “offset” of this directory entry. This is not a true - /// numerical offset but an opaque cookie that identifies a position in the - /// given stream. - #[inline] - pub fn offset(&self) -> i64 { - self.d_off - } - - /// Returns the type of this directory entry. - #[inline] - pub fn file_type(&self) -> FileType { - FileType::from_dirent_d_type(self.d_type) - } - - /// Return the inode number of this directory entry. - #[inline] - pub fn ino(&self) -> u64 { - self.d_ino - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn dir_iterator_handles_io_errors() { - // create a dir, keep the FD, then delete the dir - let tmp = tempfile::tempdir().unwrap(); - let fd = crate::fs::openat( - crate::fs::CWD, - tmp.path(), - crate::fs::OFlags::RDONLY | crate::fs::OFlags::CLOEXEC, - crate::fs::Mode::empty(), - ) - .unwrap(); - - let file_fd = crate::fs::openat( - &fd, - tmp.path().join("test.txt"), - crate::fs::OFlags::WRONLY | crate::fs::OFlags::CREATE, - crate::fs::Mode::RWXU, - ) - .unwrap(); - - let mut dir = Dir::read_from(&fd).unwrap(); - - // Reach inside the `Dir` and replace its directory with a file, which - // will cause the subsequent `getdents64` to fail. - crate::io::dup2(&file_fd, &mut dir.fd).unwrap(); - - assert!(matches!(dir.next(), Some(Err(_)))); - assert!(dir.next().is_none()); - } -} diff --git a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs deleted file mode 100644 index eb13d910..00000000 --- a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! inotify support for working with inotify objects. - -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `IN_*` for use with [`inotify::init`]. - /// - /// [`inotify::init`]: crate::fs::inotify::init - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CreateFlags: ffi::c_uint { - /// `IN_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::IN_CLOEXEC; - /// `IN_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::IN_NONBLOCK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `IN*` for use with [`inotify::add_watch`]. - /// - /// [`inotify::add_watch`]: crate::fs::inotify::add_watch - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WatchFlags: ffi::c_uint { - /// `IN_ACCESS` - const ACCESS = linux_raw_sys::general::IN_ACCESS; - /// `IN_ATTRIB` - const ATTRIB = linux_raw_sys::general::IN_ATTRIB; - /// `IN_CLOSE_NOWRITE` - const CLOSE_NOWRITE = linux_raw_sys::general::IN_CLOSE_NOWRITE; - /// `IN_CLOSE_WRITE` - const CLOSE_WRITE = linux_raw_sys::general::IN_CLOSE_WRITE; - /// `IN_CREATE` - const CREATE = linux_raw_sys::general::IN_CREATE; - /// `IN_DELETE` - const DELETE = linux_raw_sys::general::IN_DELETE; - /// `IN_DELETE_SELF` - const DELETE_SELF = linux_raw_sys::general::IN_DELETE_SELF; - /// `IN_MODIFY` - const MODIFY = linux_raw_sys::general::IN_MODIFY; - /// `IN_MOVE_SELF` - const MOVE_SELF = linux_raw_sys::general::IN_MOVE_SELF; - /// `IN_MOVED_FROM` - const MOVED_FROM = linux_raw_sys::general::IN_MOVED_FROM; - /// `IN_MOVED_TO` - const MOVED_TO = linux_raw_sys::general::IN_MOVED_TO; - /// `IN_OPEN` - const OPEN = linux_raw_sys::general::IN_OPEN; - - /// `IN_CLOSE` - const CLOSE = linux_raw_sys::general::IN_CLOSE; - /// `IN_MOVE` - const MOVE = linux_raw_sys::general::IN_MOVE; - /// `IN_ALL_EVENTS` - const ALL_EVENTS = linux_raw_sys::general::IN_ALL_EVENTS; - - /// `IN_DONT_FOLLOW` - const DONT_FOLLOW = linux_raw_sys::general::IN_DONT_FOLLOW; - /// `IN_EXCL_UNLINK` - const EXCL_UNLINK = linux_raw_sys::general::IN_EXCL_UNLINK; - /// `IN_MASK_ADD` - const MASK_ADD = linux_raw_sys::general::IN_MASK_ADD; - /// `IN_MASK_CREATE` - const MASK_CREATE = linux_raw_sys::general::IN_MASK_CREATE; - /// `IN_ONESHOT` - const ONESHOT = linux_raw_sys::general::IN_ONESHOT; - /// `IN_ONLYDIR` - const ONLYDIR = linux_raw_sys::general::IN_ONLYDIR; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `IN*` for use with [`inotify::Reader`]. - /// - /// [`inotify::Reader`]: crate::fs::inotify::InotifyReader - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReadFlags: ffi::c_uint { - /// `IN_ACCESS` - const ACCESS = linux_raw_sys::general::IN_ACCESS; - /// `IN_ATTRIB` - const ATTRIB = linux_raw_sys::general::IN_ATTRIB; - /// `IN_CLOSE_NOWRITE` - const CLOSE_NOWRITE = linux_raw_sys::general::IN_CLOSE_NOWRITE; - /// `IN_CLOSE_WRITE` - const CLOSE_WRITE = linux_raw_sys::general::IN_CLOSE_WRITE; - /// `IN_CREATE` - const CREATE = linux_raw_sys::general::IN_CREATE; - /// `IN_DELETE` - const DELETE = linux_raw_sys::general::IN_DELETE; - /// `IN_DELETE_SELF` - const DELETE_SELF = linux_raw_sys::general::IN_DELETE_SELF; - /// `IN_MODIFY` - const MODIFY = linux_raw_sys::general::IN_MODIFY; - /// `IN_MOVE_SELF` - const MOVE_SELF = linux_raw_sys::general::IN_MOVE_SELF; - /// `IN_MOVED_FROM` - const MOVED_FROM = linux_raw_sys::general::IN_MOVED_FROM; - /// `IN_MOVED_TO` - const MOVED_TO = linux_raw_sys::general::IN_MOVED_TO; - /// `IN_OPEN` - const OPEN = linux_raw_sys::general::IN_OPEN; - - /// `IN_IGNORED` - const IGNORED = linux_raw_sys::general::IN_IGNORED; - /// `IN_ISDIR` - const ISDIR = linux_raw_sys::general::IN_ISDIR; - /// `IN_Q_OVERFLOW` - const QUEUE_OVERFLOW = linux_raw_sys::general::IN_Q_OVERFLOW; - /// `IN_UNMOUNT` - const UNMOUNT = linux_raw_sys::general::IN_UNMOUNT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/fs/makedev.rs b/vendor/rustix/src/backend/linux_raw/fs/makedev.rs deleted file mode 100644 index 284ba2f1..00000000 --- a/vendor/rustix/src/backend/linux_raw/fs/makedev.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::fs::Dev; - -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - ((u64::from(maj) & 0xffff_f000_u64) << 32) - | ((u64::from(maj) & 0x0000_0fff_u64) << 8) - | ((u64::from(min) & 0xffff_ff00_u64) << 12) - | (u64::from(min) & 0x0000_00ff_u64) -} - -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 -} - -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 -} diff --git a/vendor/rustix/src/backend/linux_raw/fs/mod.rs b/vendor/rustix/src/backend/linux_raw/fs/mod.rs deleted file mode 100644 index 9f53c5db..00000000 --- a/vendor/rustix/src/backend/linux_raw/fs/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[cfg(feature = "alloc")] -pub(crate) mod dir; -pub mod inotify; -pub(crate) mod makedev; -pub(crate) mod syscalls; -pub(crate) mod types; - -// TODO: Fix linux-raw-sys to define ioctl codes for sparc. -#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] -pub(crate) const EXT4_IOC_RESIZE_FS: u32 = 0x8008_6610; - -#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] -pub(crate) use linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS; diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs deleted file mode 100644 index 872dd8e3..00000000 --- a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs +++ /dev/null @@ -1,1722 +0,0 @@ -//! linux_raw syscalls supporting `rustix::fs`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -use crate::backend::conv::fs::oflags_for_open_how; -#[cfg(any( - not(feature = "linux_4_11"), - target_arch = "aarch64", - target_arch = "riscv64", - target_arch = "mips", - target_arch = "mips32r6", -))] -use crate::backend::conv::zero; -use crate::backend::conv::{ - by_ref, c_int, c_uint, dev_t, opt_mut, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, - ret_infallible, ret_owned_fd, ret_usize, size_of, slice, slice_mut, -}; -#[cfg(target_pointer_width = "64")] -use crate::backend::conv::{loff_t, loff_t_from_u64, ret_u64}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::ffi::CStr; -#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] -use crate::fs::CWD; -use crate::fs::{ - inotify, Access, Advice, AtFlags, FallocateFlags, FileType, FlockOperation, Fsid, Gid, - MemfdFlags, Mode, OFlags, RenameFlags, ResolveFlags, SealFlags, SeekFrom, Stat, StatFs, - StatVfs, StatVfsMountFlags, Statx, StatxFlags, Timestamps, Uid, XattrFlags, -}; -use crate::io; -use core::mem::MaybeUninit; -use core::num::NonZeroU64; -#[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] -use linux_raw_sys::general::stat as linux_stat64; -use linux_raw_sys::general::{ - open_how, AT_EACCESS, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_NOFOLLOW, F_ADD_SEALS, F_GETFL, - F_GET_SEALS, F_SETFL, SEEK_CUR, SEEK_DATA, SEEK_END, SEEK_HOLE, SEEK_SET, STATX__RESERVED, -}; -#[cfg(target_pointer_width = "32")] -use { - crate::backend::conv::{hi, lo, slice_just_addr}, - linux_raw_sys::general::stat64 as linux_stat64, - linux_raw_sys::general::timespec as __kernel_old_timespec, -}; - -#[inline] -pub(crate) fn open(path: &CStr, flags: OFlags, mode: Mode) -> io::Result<OwnedFd> { - // Always enable support for large files. - let flags = flags | OFlags::LARGEFILE; - - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - { - openat(CWD, path, flags, mode) - } - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_open, path, flags, mode)) - } -} - -#[inline] -pub(crate) fn openat( - dirfd: BorrowedFd<'_>, - path: &CStr, - flags: OFlags, - mode: Mode, -) -> io::Result<OwnedFd> { - // Always enable support for large files. - let flags = flags | OFlags::LARGEFILE; - - unsafe { ret_owned_fd(syscall_readonly!(__NR_openat, dirfd, path, flags, mode)) } -} - -#[inline] -pub(crate) fn openat2( - dirfd: BorrowedFd<'_>, - path: &CStr, - mut flags: OFlags, - mode: Mode, - resolve: ResolveFlags, -) -> io::Result<OwnedFd> { - // Enable support for large files, but not with `O_PATH` because - // `openat2` doesn't like those flags together. - if !flags.contains(OFlags::PATH) { - flags |= OFlags::from_bits_retain(c::O_LARGEFILE); - } - - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_openat2, - dirfd, - path, - by_ref(&open_how { - flags: oflags_for_open_how(flags), - mode: u64::from(mode.bits()), - resolve: resolve.bits(), - }), - size_of::<open_how, _>() - )) - } -} - -#[inline] -pub(crate) fn chmod(path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fchmodat, - raw_fd(AT_FDCWD), - path, - mode - )) - } -} - -#[inline] -pub(crate) fn chmodat( - dirfd: BorrowedFd<'_>, - path: &CStr, - mode: Mode, - flags: AtFlags, -) -> io::Result<()> { - if flags == AtFlags::SYMLINK_NOFOLLOW { - return Err(io::Errno::OPNOTSUPP); - } - if !flags.is_empty() { - return Err(io::Errno::INVAL); - } - unsafe { ret(syscall_readonly!(__NR_fchmodat, dirfd, path, mode)) } -} - -#[inline] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fchmod, fd, mode)) } -} - -#[inline] -pub(crate) fn chownat( - dirfd: BorrowedFd<'_>, - path: &CStr, - owner: Option<Uid>, - group: Option<Gid>, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(syscall_readonly!( - __NR_fchownat, - dirfd, - path, - c_uint(ow), - c_uint(gr), - flags - )) - } -} - -#[inline] -pub(crate) fn chown(path: &CStr, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - // Most architectures have a `chown` syscall. - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(syscall_readonly!(__NR_chown, path, c_uint(ow), c_uint(gr))) - } - - // Aarch64 and RISC-V don't, so use `fchownat`. - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(syscall_readonly!( - __NR_fchownat, - raw_fd(AT_FDCWD), - path, - c_uint(ow), - c_uint(gr), - zero() - )) - } -} - -#[inline] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); - ret(syscall_readonly!(__NR_fchown, fd, c_uint(ow), c_uint(gr))) - } -} - -#[inline] -pub(crate) fn mknodat( - dirfd: BorrowedFd<'_>, - path: &CStr, - file_type: FileType, - mode: Mode, - dev: u64, -) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_mknodat, - dirfd, - path, - (mode, file_type), - dev_t(dev)? - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_mknodat, - dirfd, - path, - (mode, file_type), - dev_t(dev) - )) - } -} - -#[inline] -pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result<u64> { - let (whence, offset) = match pos { - SeekFrom::Start(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (SEEK_SET, pos as i64) - } - SeekFrom::End(offset) => (SEEK_END, offset), - SeekFrom::Current(offset) => (SEEK_CUR, offset), - SeekFrom::Data(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (SEEK_DATA, pos as i64) - } - SeekFrom::Hole(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (SEEK_HOLE, pos as i64) - } - }; - _seek(fd, offset, whence) -} - -#[inline] -pub(crate) fn _seek(fd: BorrowedFd<'_>, offset: i64, whence: c::c_uint) -> io::Result<u64> { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::<u64>::uninit(); - ret(syscall!( - __NR__llseek, - fd, - // Don't use the hi/lo functions here because Linux's llseek - // takes its 64-bit argument differently from everything else. - pass_usize((offset >> 32) as usize), - pass_usize(offset as usize), - &mut result, - c_uint(whence) - ))?; - Ok(result.assume_init()) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_u64(syscall_readonly!( - __NR_lseek, - fd, - loff_t(offset), - c_uint(whence) - )) - } -} - -#[inline] -pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result<u64> { - _seek(fd, 0, SEEK_CUR).map(|x| x as u64) -} - -#[inline] -pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/sys32.c?h=v6.13#n89> - #[cfg(all( - target_pointer_width = "32", - any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc" - ), - ))] - unsafe { - ret(syscall_readonly!( - __NR_ftruncate64, - fd, - zero(), - hi(length), - lo(length) - )) - } - #[cfg(all( - target_pointer_width = "32", - not(any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc" - )), - ))] - unsafe { - ret(syscall_readonly!( - __NR_ftruncate64, - fd, - hi(length), - lo(length) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_ftruncate, - fd, - loff_t_from_u64(length) - )) - } -} - -#[inline] -pub(crate) fn fallocate( - fd: BorrowedFd<'_>, - mode: FallocateFlags, - offset: u64, - len: u64, -) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_fallocate, - fd, - mode, - hi(offset), - lo(offset), - hi(len), - lo(len) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fallocate, - fd, - mode, - loff_t_from_u64(offset), - loff_t_from_u64(len) - )) - } -} - -#[inline] -pub(crate) fn fadvise( - fd: BorrowedFd<'_>, - pos: u64, - len: Option<NonZeroU64>, - advice: Advice, -) -> io::Result<()> { - let len = match len { - None => 0, - Some(len) => len.get(), - }; - - // On ARM, the arguments are reordered so that the `len` and `pos` argument - // pairs are aligned. And ARM has a custom syscall code for this. - #[cfg(target_arch = "arm")] - unsafe { - ret(syscall_readonly!( - __NR_arm_fadvise64_64, - fd, - advice, - hi(pos), - lo(pos), - hi(len), - lo(len) - )) - } - - // On powerpc, the arguments are reordered as on ARM. - #[cfg(target_arch = "powerpc")] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64_64, - fd, - advice, - hi(pos), - lo(pos), - hi(len), - lo(len) - )) - } - - // On mips, the arguments are not reordered, and padding is inserted - // instead to ensure alignment. - #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64, - fd, - zero(), - hi(pos), - lo(pos), - hi(len), - lo(len), - advice - )) - } - - // For all other 32-bit architectures, use `fadvise64_64` so that we get a - // 64-bit length. - #[cfg(all( - target_pointer_width = "32", - not(any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc" - )), - ))] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64_64, - fd, - hi(pos), - lo(pos), - hi(len), - lo(len), - advice - )) - } - - // On 64-bit architectures, use `fadvise64` which is sufficient. - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64, - fd, - loff_t_from_u64(pos), - loff_t_from_u64(len), - advice - )) - } -} - -#[inline] -pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fsync, fd)) } -} - -#[inline] -pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fdatasync, fd)) } -} - -#[inline] -pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_flock, - fd, - c_uint(operation as c::c_uint) - )) - } -} - -#[inline] -pub(crate) fn syncfs(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_syncfs, fd)) } -} - -#[inline] -pub(crate) fn sync() { - unsafe { ret_infallible(syscall_readonly!(__NR_sync)) } -} - -#[inline] -pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> { - // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use - // `statx`. - // - // And, some old platforms don't support `statx`, and some fail with a - // confusing error code, so we call `crate::fs::statx` to handle that. If - // `statx` isn't available, fall back to the buggy system call. - #[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ))] - { - match crate::fs::statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => fstat_old(fd), - Err(err) => Err(err), - } - } - - #[cfg(all( - target_pointer_width = "64", - not(target_arch = "mips64"), - not(target_arch = "mips64r6") - ))] - unsafe { - let mut result = MaybeUninit::<Stat>::uninit(); - ret(syscall!(__NR_fstat, fd, &mut result))?; - Ok(result.assume_init()) - } -} - -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6", -))] -fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { - let mut result = MaybeUninit::<linux_stat64>::uninit(); - - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - unsafe { - ret(syscall!(__NR_fstat, fd, &mut result))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!(__NR_fstat64, fd, &mut result))?; - stat_to_stat(result.assume_init()) - } -} - -#[inline] -pub(crate) fn stat(path: &CStr) -> io::Result<Stat> { - // See the comments in `fstat` about using `crate::fs::statx` here. - #[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ))] - { - match crate::fs::statx( - crate::fs::CWD, - path, - AtFlags::empty(), - StatxFlags::BASIC_STATS, - ) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => stat_old(path), - Err(err) => Err(err), - } - } - - #[cfg(all( - target_pointer_width = "64", - not(target_arch = "mips64"), - not(target_arch = "mips64r6"), - ))] - unsafe { - let mut result = MaybeUninit::<Stat>::uninit(); - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - path, - &mut result, - c_uint(0) - ))?; - Ok(result.assume_init()) - } -} - -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" -))] -fn stat_old(path: &CStr) -> io::Result<Stat> { - let mut result = MaybeUninit::<linux_stat64>::uninit(); - - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - unsafe { - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - path, - &mut result, - c_uint(0) - ))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_fstatat64, - raw_fd(AT_FDCWD), - path, - &mut result, - c_uint(0) - ))?; - stat_to_stat(result.assume_init()) - } -} - -#[inline] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { - // See the comments in `fstat` about using `crate::fs::statx` here. - #[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ))] - { - match crate::fs::statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(dirfd, path, flags), - Err(err) => Err(err), - } - } - - #[cfg(all( - target_pointer_width = "64", - not(target_arch = "mips64"), - not(target_arch = "mips64r6"), - ))] - unsafe { - let mut result = MaybeUninit::<Stat>::uninit(); - ret(syscall!(__NR_newfstatat, dirfd, path, &mut result, flags))?; - Ok(result.assume_init()) - } -} - -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" -))] -fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { - let mut result = MaybeUninit::<linux_stat64>::uninit(); - - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - unsafe { - ret(syscall!(__NR_newfstatat, dirfd, path, &mut result, flags))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!(__NR_fstatat64, dirfd, path, &mut result, flags))?; - stat_to_stat(result.assume_init()) - } -} - -#[inline] -pub(crate) fn lstat(path: &CStr) -> io::Result<Stat> { - // See the comments in `fstat` about using `crate::fs::statx` here. - #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] - { - match crate::fs::statx( - crate::fs::CWD, - path, - AtFlags::SYMLINK_NOFOLLOW, - StatxFlags::BASIC_STATS, - ) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => lstat_old(path), - Err(err) => Err(err), - } - } - - #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] - unsafe { - let mut result = MaybeUninit::<Stat>::uninit(); - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - path, - &mut result, - c_uint(AT_SYMLINK_NOFOLLOW) - ))?; - Ok(result.assume_init()) - } -} - -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn lstat_old(path: &CStr) -> io::Result<Stat> { - let mut result = MaybeUninit::<linux_stat64>::uninit(); - - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - unsafe { - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - path, - &mut result, - c_uint(AT_SYMLINK_NOFOLLOW) - ))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_fstatat64, - raw_fd(AT_FDCWD), - path, - &mut result, - c_uint(AT_SYMLINK_NOFOLLOW) - ))?; - stat_to_stat(result.assume_init()) - } -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" -))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { - Ok(Stat { - st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor), - st_mode: x.stx_mode.into(), - st_nlink: x.stx_nlink.into(), - st_uid: x.stx_uid.into(), - st_gid: x.stx_gid.into(), - st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor), - st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: x.stx_blksize.into(), - st_blocks: x.stx_blocks.into(), - st_atime: i64::from(x.stx_atime.tv_sec), - st_atime_nsec: x.stx_atime.tv_nsec.into(), - st_mtime: i64::from(x.stx_mtime.tv_sec), - st_mtime_nsec: x.stx_mtime.tv_nsec.into(), - st_ctime: i64::from(x.stx_ctime.tv_sec), - st_ctime_nsec: x.stx_ctime.tv_nsec.into(), - st_ino: x.stx_ino.into(), - }) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -#[cfg(target_pointer_width = "32")] -fn stat_to_stat(s64: linux_raw_sys::general::stat64) -> io::Result<Stat> { - Ok(Stat { - st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime: i64::from(s64.st_atime.to_signed()), - st_atime_nsec: s64 - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime: i64::from(s64.st_mtime.to_signed()), - st_mtime_nsec: s64 - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime: i64::from(s64.st_ctime.to_signed()), - st_ctime_nsec: s64 - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, - }) -} - -/// Convert from a Linux `stat` value to rustix's `Stat`. -#[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] -fn stat_to_stat(s: linux_raw_sys::general::stat) -> io::Result<Stat> { - Ok(Stat { - st_dev: s.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mode: s.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_nlink: s.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_uid: s.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_gid: s.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_rdev: s.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_size: s.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: s.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blocks: s.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime: i64::from(s.st_atime.to_signed()), - st_atime_nsec: s - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime: i64::from(s.st_mtime.to_signed()), - st_mtime_nsec: s - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime: i64::from(s.st_ctime.to_signed()), - st_ctime_nsec: s - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ino: s.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, - }) -} - -#[inline] -pub(crate) fn statx( - dirfd: BorrowedFd<'_>, - path: &CStr, - flags: AtFlags, - mask: StatxFlags, -) -> io::Result<Statx> { - // If a future Linux kernel adds more fields to `struct statx` and users - // passing flags unknown to rustix in `StatxFlags`, we could end up - // writing outside of the buffer. To prevent this possibility, we mask off - // any flags that we don't know about. - // - // This includes `STATX__RESERVED`, which has a value that we know, but - // which could take on arbitrary new meaning in the future. Linux currently - // rejects this flag with `EINVAL`, so we do the same. - // - // This doesn't rely on `STATX_ALL` because [it's deprecated] and already - // doesn't represent all the known flags. - // - // [it's deprecated]: https://patchwork.kernel.org/project/linux-fsdevel/patch/20200505095915.11275-7-mszeredi@redhat.com/ - if (mask.bits() & STATX__RESERVED) == STATX__RESERVED { - return Err(io::Errno::INVAL); - } - let mask = mask & StatxFlags::all(); - - unsafe { - let mut statx_buf = MaybeUninit::<Statx>::uninit(); - ret(syscall!( - __NR_statx, - dirfd, - path, - flags, - mask, - &mut statx_buf - ))?; - Ok(statx_buf.assume_init()) - } -} - -#[cfg(not(feature = "linux_4_11"))] -#[inline] -pub(crate) fn is_statx_available() -> bool { - unsafe { - // Call `statx` with null pointers so that if it fails for any reason - // other than `EFAULT`, we know it's not supported. This can use - // "readonly" because we don't pass it a buffer to mutate. - matches!( - ret(syscall_readonly!( - __NR_statx, - raw_fd(AT_FDCWD), - zero(), - zero(), - zero(), - zero() - )), - Err(io::Errno::FAULT) - ) - } -} - -#[inline] -pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result<StatFs> { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::<StatFs>::uninit(); - ret(syscall!( - __NR_fstatfs64, - fd, - size_of::<StatFs, _>(), - &mut result - ))?; - Ok(result.assume_init()) - } - - #[cfg(target_pointer_width = "64")] - unsafe { - let mut result = MaybeUninit::<StatFs>::uninit(); - ret(syscall!(__NR_fstatfs, fd, &mut result))?; - Ok(result.assume_init()) - } -} - -#[inline] -pub(crate) fn fstatvfs(fd: BorrowedFd<'_>) -> io::Result<StatVfs> { - // Linux doesn't have an `fstatvfs` syscall; we have to do `fstatfs` and - // translate the fields as best we can. - let statfs = fstatfs(fd)?; - - Ok(statfs_to_statvfs(statfs)) -} - -#[inline] -pub(crate) fn statfs(path: &CStr) -> io::Result<StatFs> { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::<StatFs>::uninit(); - ret(syscall!( - __NR_statfs64, - path, - size_of::<StatFs, _>(), - &mut result - ))?; - Ok(result.assume_init()) - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut result = MaybeUninit::<StatFs>::uninit(); - ret(syscall!(__NR_statfs, path, &mut result))?; - Ok(result.assume_init()) - } -} - -#[inline] -pub(crate) fn statvfs(path: &CStr) -> io::Result<StatVfs> { - // Linux doesn't have a `statvfs` syscall; we have to do `statfs` and - // translate the fields as best we can. - let statfs = statfs(path)?; - - Ok(statfs_to_statvfs(statfs)) -} - -fn statfs_to_statvfs(statfs: StatFs) -> StatVfs { - let Fsid { val } = Fsid { - val: statfs.f_fsid.val, - }; - let [f_fsid_val0, f_fsid_val1]: [i32; 2] = val; - - StatVfs { - f_bsize: statfs.f_bsize as u64, - f_frsize: if statfs.f_frsize != 0 { - statfs.f_frsize - } else { - statfs.f_bsize - } as u64, - f_blocks: statfs.f_blocks as u64, - f_bfree: statfs.f_bfree as u64, - f_bavail: statfs.f_bavail as u64, - f_files: statfs.f_files as u64, - f_ffree: statfs.f_ffree as u64, - f_favail: statfs.f_ffree as u64, - f_fsid: u64::from(f_fsid_val0 as u32) | (u64::from(f_fsid_val1 as u32) << 32), - f_flag: StatVfsMountFlags::from_bits_retain(statfs.f_flags as u64), - f_namemax: statfs.f_namelen as u64, - } -} - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { - ret_usize(syscall!( - __NR_readlinkat, - raw_fd(AT_FDCWD), - path, - buf_addr_mut, - buf_len - )) - } -} - -#[inline] -pub(crate) unsafe fn readlinkat( - dirfd: BorrowedFd<'_>, - path: &CStr, - buf: (*mut u8, usize), -) -> io::Result<usize> { - ret_usize(syscall!( - __NR_readlinkat, - dirfd, - path, - buf.0, - pass_usize(buf.1) - )) -} - -#[inline] -pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result<OFlags> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFL))) - .map(OFlags::from_bits_retain) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFL))).map(OFlags::from_bits_retain) - } -} - -#[inline] -pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { - // Always enable support for large files. - let flags = flags | OFlags::from_bits_retain(c::O_LARGEFILE); - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFL), flags)) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!(__NR_fcntl, fd, c_uint(F_SETFL), flags)) - } -} - -#[inline] -pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result<SealFlags> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GET_SEALS))) - .map(|seals| SealFlags::from_bits_retain(seals as u32)) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GET_SEALS))) - .map(|seals| SealFlags::from_bits_retain(seals as u32)) - } -} - -#[inline] -pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(F_ADD_SEALS), - seals - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(F_ADD_SEALS), - seals - )) - } -} - -#[inline] -pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { - #[cfg(target_pointer_width = "64")] - use linux_raw_sys::general::{flock, F_SETLK, F_SETLKW}; - #[cfg(target_pointer_width = "32")] - use linux_raw_sys::general::{flock64 as flock, F_SETLK64 as F_SETLK, F_SETLKW64 as F_SETLKW}; - use linux_raw_sys::general::{F_RDLCK, F_UNLCK, F_WRLCK}; - - let (cmd, l_type) = match operation { - FlockOperation::LockShared => (F_SETLKW, F_RDLCK), - FlockOperation::LockExclusive => (F_SETLKW, F_WRLCK), - FlockOperation::Unlock => (F_SETLKW, F_UNLCK), - FlockOperation::NonBlockingLockShared => (F_SETLK, F_RDLCK), - FlockOperation::NonBlockingLockExclusive => (F_SETLK, F_WRLCK), - FlockOperation::NonBlockingUnlock => (F_SETLK, F_UNLCK), - }; - - let lock = flock { - l_type: l_type as _, - - // When `l_len` is zero, this locks all the bytes from - // `l_whence`/`l_start` to the end of the file, even as the - // file grows dynamically. - l_whence: SEEK_SET as _, - l_start: 0, - l_len: 0, - - // Unused. - l_pid: 0, - }; - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(cmd), - by_ref(&lock) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(cmd), - by_ref(&lock) - )) - } -} - -#[inline] -pub(crate) fn rename(old_path: &CStr, new_path: &CStr) -> io::Result<()> { - #[cfg(target_arch = "riscv64")] - unsafe { - ret(syscall_readonly!( - __NR_renameat2, - raw_fd(AT_FDCWD), - old_path, - raw_fd(AT_FDCWD), - new_path, - c_uint(0) - )) - } - #[cfg(not(target_arch = "riscv64"))] - unsafe { - ret(syscall_readonly!( - __NR_renameat, - raw_fd(AT_FDCWD), - old_path, - raw_fd(AT_FDCWD), - new_path - )) - } -} - -#[inline] -pub(crate) fn renameat( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, -) -> io::Result<()> { - #[cfg(target_arch = "riscv64")] - unsafe { - ret(syscall_readonly!( - __NR_renameat2, - old_dirfd, - old_path, - new_dirfd, - new_path, - c_uint(0) - )) - } - #[cfg(not(target_arch = "riscv64"))] - unsafe { - ret(syscall_readonly!( - __NR_renameat, - old_dirfd, - old_path, - new_dirfd, - new_path - )) - } -} - -#[inline] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_renameat2, - old_dirfd, - old_path, - new_dirfd, - new_path, - flags - )) - } -} - -#[inline] -pub(crate) fn unlink(path: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_unlinkat, - raw_fd(AT_FDCWD), - path, - c_uint(0) - )) - } -} - -#[inline] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_unlinkat, dirfd, path, flags)) } -} - -#[inline] -pub(crate) fn rmdir(path: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_unlinkat, - raw_fd(AT_FDCWD), - path, - c_uint(AT_REMOVEDIR) - )) - } -} - -#[inline] -pub(crate) fn link(old_path: &CStr, new_path: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_linkat, - raw_fd(AT_FDCWD), - old_path, - raw_fd(AT_FDCWD), - new_path, - c_uint(0) - )) - } -} - -#[inline] -pub(crate) fn linkat( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_linkat, - old_dirfd, - old_path, - new_dirfd, - new_path, - flags - )) - } -} - -#[inline] -pub(crate) fn symlink(old_path: &CStr, new_path: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_symlinkat, - old_path, - raw_fd(AT_FDCWD), - new_path - )) - } -} - -#[inline] -pub(crate) fn symlinkat(old_path: &CStr, dirfd: BorrowedFd<'_>, new_path: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_symlinkat, old_path, dirfd, new_path)) } -} - -#[inline] -pub(crate) fn mkdir(path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_mkdirat, - raw_fd(AT_FDCWD), - path, - mode - )) - } -} - -#[inline] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_mkdirat, dirfd, path, mode)) } -} - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn getdents(fd: BorrowedFd<'_>, dirent: &mut [u8]) -> io::Result<usize> { - let (dirent_addr_mut, dirent_len) = slice_mut(dirent); - - unsafe { ret_usize(syscall!(__NR_getdents64, fd, dirent_addr_mut, dirent_len)) } -} - -#[inline] -pub(crate) fn getdents_uninit( - fd: BorrowedFd<'_>, - dirent: &mut [MaybeUninit<u8>], -) -> io::Result<usize> { - let (dirent_addr_mut, dirent_len) = slice_mut(dirent); - - unsafe { ret_usize(syscall!(__NR_getdents64, fd, dirent_addr_mut, dirent_len)) } -} - -#[inline] -pub(crate) fn utimensat( - dirfd: BorrowedFd<'_>, - path: &CStr, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - _utimensat(dirfd, Some(path), times, flags) -} - -#[inline] -fn _utimensat( - dirfd: BorrowedFd<'_>, - path: Option<&CStr>, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - // `utimensat_time64` was introduced in Linux 5.1. The old `utimensat` - // syscall is not y2038-compatible on 32-bit architectures. - #[cfg(target_pointer_width = "32")] - unsafe { - match ret(syscall_readonly!( - __NR_utimensat_time64, - dirfd, - path, - by_ref(times), - flags - )) { - Err(io::Errno::NOSYS) => _utimensat_old(dirfd, path, times, flags), - otherwise => otherwise, - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_utimensat, - dirfd, - path, - by_ref(times), - flags - )) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn _utimensat_old( - dirfd: BorrowedFd<'_>, - path: Option<&CStr>, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - // See the comments in `clock_gettime_via_syscall` about emulation. - let old_times = [ - __kernel_old_timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_access - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - __kernel_old_timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_modification - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - ]; - // The length of the array is fixed and not passed into the syscall. - let old_times_addr = slice_just_addr(&old_times); - ret(syscall_readonly!( - __NR_utimensat, - dirfd, - path, - old_times_addr, - flags - )) -} - -#[inline] -pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { - _utimensat(fd, None, times, AtFlags::empty()) -} - -#[inline] -pub(crate) fn access(path: &CStr, access: Access) -> io::Result<()> { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - { - accessat_noflags(CWD, path, access) - } - - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - ret(syscall_readonly!(__NR_access, path, access)) - } -} - -pub(crate) fn accessat( - dirfd: BorrowedFd<'_>, - path: &CStr, - access: Access, - flags: AtFlags, -) -> io::Result<()> { - if !flags - .difference(AtFlags::EACCESS | AtFlags::SYMLINK_NOFOLLOW) - .is_empty() - { - return Err(io::Errno::INVAL); - } - - // Linux's `faccessat` syscall doesn't have a flags argument, so if we have - // any flags, use the newer `faccessat2` introduced in Linux 5.8 which - // does. Unless we're on Android where using newer system calls can cause - // seccomp to abort the process. - #[cfg(not(target_os = "android"))] - if !flags.is_empty() { - unsafe { - match ret(syscall_readonly!( - __NR_faccessat2, - dirfd, - path, - access, - flags - )) { - Ok(()) => return Ok(()), - Err(io::Errno::NOSYS) => {} - Err(other) => return Err(other), - } - } - } - - // Linux's `faccessat` doesn't have a flags parameter. If we have - // `AT_EACCESS` and we're not setuid or setgid, we can emulate it. - if flags.is_empty() - || (flags.bits() == AT_EACCESS - && crate::backend::ugid::syscalls::getuid() - == crate::backend::ugid::syscalls::geteuid() - && crate::backend::ugid::syscalls::getgid() - == crate::backend::ugid::syscalls::getegid()) - { - return accessat_noflags(dirfd, path, access); - } - - Err(io::Errno::NOSYS) -} - -#[inline] -fn accessat_noflags(dirfd: BorrowedFd<'_>, path: &CStr, access: Access) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_faccessat, dirfd, path, access)) } -} - -#[inline] -pub(crate) fn copy_file_range( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: usize, -) -> io::Result<usize> { - unsafe { - ret_usize(syscall!( - __NR_copy_file_range, - fd_in, - opt_mut(off_in), - fd_out, - opt_mut(off_out), - pass_usize(len), - c_uint(0) - )) - } -} - -#[inline] -pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_memfd_create, name, flags)) } -} - -#[inline] -pub(crate) fn sendfile( - out_fd: BorrowedFd<'_>, - in_fd: BorrowedFd<'_>, - offset: Option<&mut u64>, - count: usize, -) -> io::Result<usize> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall!( - __NR_sendfile64, - out_fd, - in_fd, - opt_mut(offset), - pass_usize(count) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_sendfile, - out_fd, - in_fd, - opt_mut(offset), - pass_usize(count) - )) - } -} - -#[inline] -pub(crate) fn inotify_init1(flags: inotify::CreateFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_inotify_init1, flags)) } -} - -#[inline] -pub(crate) fn inotify_add_watch( - infd: BorrowedFd<'_>, - path: &CStr, - flags: inotify::WatchFlags, -) -> io::Result<i32> { - unsafe { ret_c_int(syscall_readonly!(__NR_inotify_add_watch, infd, path, flags)) } -} - -#[inline] -pub(crate) fn inotify_rm_watch(infd: BorrowedFd<'_>, wfd: i32) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_inotify_rm_watch, infd, c_int(wfd))) } -} - -#[inline] -pub(crate) unsafe fn getxattr( - path: &CStr, - name: &CStr, - value: (*mut u8, usize), -) -> io::Result<usize> { - ret_usize(syscall!( - __NR_getxattr, - path, - name, - value.0, - pass_usize(value.1) - )) -} - -#[inline] -pub(crate) unsafe fn lgetxattr( - path: &CStr, - name: &CStr, - value: (*mut u8, usize), -) -> io::Result<usize> { - ret_usize(syscall!( - __NR_lgetxattr, - path, - name, - value.0, - pass_usize(value.1) - )) -} - -#[inline] -pub(crate) unsafe fn fgetxattr( - fd: BorrowedFd<'_>, - name: &CStr, - value: (*mut u8, usize), -) -> io::Result<usize> { - ret_usize(syscall!( - __NR_fgetxattr, - fd, - name, - value.0, - pass_usize(value.1) - )) -} - -#[inline] -pub(crate) fn setxattr( - path: &CStr, - name: &CStr, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - let (value_addr, value_len) = slice(value); - unsafe { - ret(syscall_readonly!( - __NR_setxattr, - path, - name, - value_addr, - value_len, - flags - )) - } -} - -#[inline] -pub(crate) fn lsetxattr( - path: &CStr, - name: &CStr, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - let (value_addr, value_len) = slice(value); - unsafe { - ret(syscall_readonly!( - __NR_lsetxattr, - path, - name, - value_addr, - value_len, - flags - )) - } -} - -#[inline] -pub(crate) fn fsetxattr( - fd: BorrowedFd<'_>, - name: &CStr, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - let (value_addr, value_len) = slice(value); - unsafe { - ret(syscall_readonly!( - __NR_fsetxattr, - fd, - name, - value_addr, - value_len, - flags - )) - } -} - -#[inline] -pub(crate) unsafe fn listxattr(path: &CStr, list: (*mut u8, usize)) -> io::Result<usize> { - ret_usize(syscall!(__NR_listxattr, path, list.0, pass_usize(list.1))) -} - -#[inline] -pub(crate) unsafe fn llistxattr(path: &CStr, list: (*mut u8, usize)) -> io::Result<usize> { - ret_usize(syscall!(__NR_llistxattr, path, list.0, pass_usize(list.1))) -} - -#[inline] -pub(crate) unsafe fn flistxattr(fd: BorrowedFd<'_>, list: (*mut u8, usize)) -> io::Result<usize> { - ret_usize(syscall!(__NR_flistxattr, fd, list.0, pass_usize(list.1))) -} - -#[inline] -pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_removexattr, path, name)) } -} - -#[inline] -pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_lremovexattr, path, name)) } -} - -#[inline] -pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fremovexattr, fd, name)) } -} - -// Some linux_raw_sys structs have unsigned types for values which are -// interpreted as signed. This defines a utility or casting to the -// same-sized signed type. -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" -))] -mod to_signed { - pub(super) trait ToSigned { - type Signed; - fn to_signed(self) -> Self::Signed; - } - impl ToSigned for u32 { - type Signed = i32; - - fn to_signed(self) -> Self::Signed { - self as _ - } - } - impl ToSigned for i32 { - type Signed = i32; - - fn to_signed(self) -> Self::Signed { - self - } - } - impl ToSigned for u64 { - type Signed = i64; - - fn to_signed(self) -> Self::Signed { - self as _ - } - } - impl ToSigned for i64 { - type Signed = i64; - - fn to_signed(self) -> Self::Signed { - self - } - } -} -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" -))] -use to_signed::*; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - assert_eq_size!(linux_raw_sys::general::__kernel_loff_t, u64); - assert_eq_align!(linux_raw_sys::general::__kernel_loff_t, u64); - - // Assert that `Timestamps` has the expected layout. - assert_eq_size!([linux_raw_sys::general::__kernel_timespec; 2], Timestamps); - assert_eq_align!([linux_raw_sys::general::__kernel_timespec; 2], Timestamps); - } -} diff --git a/vendor/rustix/src/backend/linux_raw/fs/types.rs b/vendor/rustix/src/backend/linux_raw/fs/types.rs deleted file mode 100644 index ce6461c3..00000000 --- a/vendor/rustix/src/backend/linux_raw/fs/types.rs +++ /dev/null @@ -1,848 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `*_OK` constants for use with [`accessat`]. - /// - /// [`accessat`]: fn.accessat.html - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Access: ffi::c_uint { - /// `R_OK` - const READ_OK = linux_raw_sys::general::R_OK; - - /// `W_OK` - const WRITE_OK = linux_raw_sys::general::W_OK; - - /// `X_OK` - const EXEC_OK = linux_raw_sys::general::X_OK; - - /// `F_OK` - const EXISTS = linux_raw_sys::general::F_OK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` - /// functions. - /// - /// [`openat`]: crate::fs::openat - /// [`statat`]: crate::fs::statat - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct AtFlags: ffi::c_uint { - /// `AT_SYMLINK_NOFOLLOW` - const SYMLINK_NOFOLLOW = linux_raw_sys::general::AT_SYMLINK_NOFOLLOW; - - /// `AT_EACCESS` - const EACCESS = linux_raw_sys::general::AT_EACCESS; - - /// `AT_REMOVEDIR` - const REMOVEDIR = linux_raw_sys::general::AT_REMOVEDIR; - - /// `AT_SYMLINK_FOLLOW` - const SYMLINK_FOLLOW = linux_raw_sys::general::AT_SYMLINK_FOLLOW; - - /// `AT_NO_AUTOMOUNT` - const NO_AUTOMOUNT = linux_raw_sys::general::AT_NO_AUTOMOUNT; - - /// `AT_EMPTY_PATH` - const EMPTY_PATH = linux_raw_sys::general::AT_EMPTY_PATH; - - /// `AT_STATX_SYNC_AS_STAT` - const STATX_SYNC_AS_STAT = linux_raw_sys::general::AT_STATX_SYNC_AS_STAT; - - /// `AT_STATX_FORCE_SYNC` - const STATX_FORCE_SYNC = linux_raw_sys::general::AT_STATX_FORCE_SYNC; - - /// `AT_STATX_DONT_SYNC` - const STATX_DONT_SYNC = linux_raw_sys::general::AT_STATX_DONT_SYNC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. - /// - /// [`openat`]: crate::fs::openat - /// [`chmodat`]: crate::fs::chmodat - /// [`fchmod`]: crate::fs::fchmod - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Mode: RawMode { - /// `S_IRWXU` - const RWXU = linux_raw_sys::general::S_IRWXU; - - /// `S_IRUSR` - const RUSR = linux_raw_sys::general::S_IRUSR; - - /// `S_IWUSR` - const WUSR = linux_raw_sys::general::S_IWUSR; - - /// `S_IXUSR` - const XUSR = linux_raw_sys::general::S_IXUSR; - - /// `S_IRWXG` - const RWXG = linux_raw_sys::general::S_IRWXG; - - /// `S_IRGRP` - const RGRP = linux_raw_sys::general::S_IRGRP; - - /// `S_IWGRP` - const WGRP = linux_raw_sys::general::S_IWGRP; - - /// `S_IXGRP` - const XGRP = linux_raw_sys::general::S_IXGRP; - - /// `S_IRWXO` - const RWXO = linux_raw_sys::general::S_IRWXO; - - /// `S_IROTH` - const ROTH = linux_raw_sys::general::S_IROTH; - - /// `S_IWOTH` - const WOTH = linux_raw_sys::general::S_IWOTH; - - /// `S_IXOTH` - const XOTH = linux_raw_sys::general::S_IXOTH; - - /// `S_ISUID` - const SUID = linux_raw_sys::general::S_ISUID; - - /// `S_ISGID` - const SGID = linux_raw_sys::general::S_ISGID; - - /// `S_ISVTX` - const SVTX = linux_raw_sys::general::S_ISVTX; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -impl Mode { - /// Construct a `Mode` from the mode bits of the `st_mode` field of a - /// `Mode`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - Self::from_bits_truncate(st_mode & !linux_raw_sys::general::S_IFMT) - } - - /// Construct an `st_mode` value from a `Mode`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - self.bits() - } -} - -impl From<RawMode> for Mode { - /// Support conversions from raw mode values to `Mode`. - /// - /// ``` - /// use rustix::fs::{Mode, RawMode}; - /// assert_eq!(Mode::from(0o700), Mode::RWXU); - /// ``` - #[inline] - fn from(st_mode: RawMode) -> Self { - Self::from_raw_mode(st_mode) - } -} - -impl From<Mode> for RawMode { - /// Support conversions from `Mode` to raw mode values. - /// - /// ``` - /// use rustix::fs::{Mode, RawMode}; - /// assert_eq!(RawMode::from(Mode::RWXU), 0o700); - /// ``` - #[inline] - fn from(mode: Mode) -> Self { - mode.as_raw_mode() - } -} - -bitflags! { - /// `O_*` constants for use with [`openat`]. - /// - /// [`openat`]: crate::fs::openat - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct OFlags: ffi::c_uint { - /// `O_ACCMODE` - const ACCMODE = linux_raw_sys::general::O_ACCMODE; - - /// Similar to `ACCMODE`, but just includes the read/write flags, and - /// no other flags. - /// - /// On some platforms, `PATH` may be included in `ACCMODE`, when - /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `PATH` may mean that the read/write - /// bits don't have their usual meaning. - const RWMODE = linux_raw_sys::general::O_RDONLY | - linux_raw_sys::general::O_WRONLY | - linux_raw_sys::general::O_RDWR; - - /// `O_APPEND` - const APPEND = linux_raw_sys::general::O_APPEND; - - /// `O_CREAT` - #[doc(alias = "CREAT")] - const CREATE = linux_raw_sys::general::O_CREAT; - - /// `O_DIRECTORY` - const DIRECTORY = linux_raw_sys::general::O_DIRECTORY; - - /// `O_DSYNC` - const DSYNC = linux_raw_sys::general::O_SYNC; - - /// `O_EXCL` - const EXCL = linux_raw_sys::general::O_EXCL; - - /// `O_FSYNC` - const FSYNC = linux_raw_sys::general::O_SYNC; - - /// `O_NOFOLLOW` - const NOFOLLOW = linux_raw_sys::general::O_NOFOLLOW; - - /// `O_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - - /// `O_RDONLY` - const RDONLY = linux_raw_sys::general::O_RDONLY; - - /// `O_WRONLY` - const WRONLY = linux_raw_sys::general::O_WRONLY; - - /// `O_RDWR` - /// - /// This is not equal to `RDONLY | WRONLY`. It's a distinct flag. - const RDWR = linux_raw_sys::general::O_RDWR; - - /// `O_NOCTTY` - const NOCTTY = linux_raw_sys::general::O_NOCTTY; - - /// `O_RSYNC` - const RSYNC = linux_raw_sys::general::O_SYNC; - - /// `O_SYNC` - const SYNC = linux_raw_sys::general::O_SYNC; - - /// `O_TRUNC` - const TRUNC = linux_raw_sys::general::O_TRUNC; - - /// `O_PATH` - const PATH = linux_raw_sys::general::O_PATH; - - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - - /// `O_TMPFILE` - const TMPFILE = linux_raw_sys::general::O_TMPFILE; - - /// `O_NOATIME` - const NOATIME = linux_raw_sys::general::O_NOATIME; - - /// `O_DIRECT` - const DIRECT = linux_raw_sys::general::O_DIRECT; - - /// `O_LARGEFILE` - /// - /// Rustix and/or libc will automatically set this flag when - /// appropriate in the [`rustix::fs::open`] family of functions, so - /// typical users do not need to care about it. It may be reported in - /// the return of `fcntl_getfl`, though. - const LARGEFILE = linux_raw_sys::general::O_LARGEFILE; - - /// `O_ASYNC`, `FASYNC` - /// - /// This flag can't be used with the [`rustix::fs::open`] family of - /// functions, use [`rustix::fs::fcntl_setfl`] instead. - const ASYNC = linux_raw_sys::general::FASYNC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `RESOLVE_*` constants for use with [`openat2`]. - /// - /// [`openat2`]: crate::fs::openat2 - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ResolveFlags: u64 { - /// `RESOLVE_NO_XDEV` - const NO_XDEV = linux_raw_sys::general::RESOLVE_NO_XDEV as u64; - - /// `RESOLVE_NO_MAGICLINKS` - const NO_MAGICLINKS = linux_raw_sys::general::RESOLVE_NO_MAGICLINKS as u64; - - /// `RESOLVE_NO_SYMLINKS` - const NO_SYMLINKS = linux_raw_sys::general::RESOLVE_NO_SYMLINKS as u64; - - /// `RESOLVE_BENEATH` - const BENEATH = linux_raw_sys::general::RESOLVE_BENEATH as u64; - - /// `RESOLVE_IN_ROOT` - const IN_ROOT = linux_raw_sys::general::RESOLVE_IN_ROOT as u64; - - /// `RESOLVE_CACHED` (since Linux 5.12) - const CACHED = linux_raw_sys::general::RESOLVE_CACHED as u64; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `RENAME_*` constants for use with [`renameat_with`]. - /// - /// [`renameat_with`]: crate::fs::renameat_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RenameFlags: ffi::c_uint { - /// `RENAME_EXCHANGE` - const EXCHANGE = linux_raw_sys::general::RENAME_EXCHANGE; - - /// `RENAME_NOREPLACE` - const NOREPLACE = linux_raw_sys::general::RENAME_NOREPLACE; - - /// `RENAME_WHITEOUT` - const WHITEOUT = linux_raw_sys::general::RENAME_WHITEOUT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. -/// -/// [`mknodat`]: crate::fs::mknodat -/// [`Stat`]: crate::fs::Stat -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum FileType { - /// `S_IFREG` - RegularFile = linux_raw_sys::general::S_IFREG as isize, - - /// `S_IFDIR` - Directory = linux_raw_sys::general::S_IFDIR as isize, - - /// `S_IFLNK` - Symlink = linux_raw_sys::general::S_IFLNK as isize, - - /// `S_IFIFO` - #[doc(alias = "IFO")] - Fifo = linux_raw_sys::general::S_IFIFO as isize, - - /// `S_IFSOCK` - Socket = linux_raw_sys::general::S_IFSOCK as isize, - - /// `S_IFCHR` - CharacterDevice = linux_raw_sys::general::S_IFCHR as isize, - - /// `S_IFBLK` - BlockDevice = linux_raw_sys::general::S_IFBLK as isize, - - /// An unknown filesystem object. - Unknown, -} - -impl FileType { - /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of - /// a `Stat`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - match st_mode & linux_raw_sys::general::S_IFMT { - linux_raw_sys::general::S_IFREG => Self::RegularFile, - linux_raw_sys::general::S_IFDIR => Self::Directory, - linux_raw_sys::general::S_IFLNK => Self::Symlink, - linux_raw_sys::general::S_IFIFO => Self::Fifo, - linux_raw_sys::general::S_IFSOCK => Self::Socket, - linux_raw_sys::general::S_IFCHR => Self::CharacterDevice, - linux_raw_sys::general::S_IFBLK => Self::BlockDevice, - _ => Self::Unknown, - } - } - - /// Construct an `st_mode` value from a `FileType`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - match self { - Self::RegularFile => linux_raw_sys::general::S_IFREG, - Self::Directory => linux_raw_sys::general::S_IFDIR, - Self::Symlink => linux_raw_sys::general::S_IFLNK, - Self::Fifo => linux_raw_sys::general::S_IFIFO, - Self::Socket => linux_raw_sys::general::S_IFSOCK, - Self::CharacterDevice => linux_raw_sys::general::S_IFCHR, - Self::BlockDevice => linux_raw_sys::general::S_IFBLK, - Self::Unknown => linux_raw_sys::general::S_IFMT, - } - } - - /// Construct a `FileType` from the `d_type` field of a `c::dirent`. - #[inline] - pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { - match d_type as u32 { - linux_raw_sys::general::DT_REG => Self::RegularFile, - linux_raw_sys::general::DT_DIR => Self::Directory, - linux_raw_sys::general::DT_LNK => Self::Symlink, - linux_raw_sys::general::DT_SOCK => Self::Socket, - linux_raw_sys::general::DT_FIFO => Self::Fifo, - linux_raw_sys::general::DT_CHR => Self::CharacterDevice, - linux_raw_sys::general::DT_BLK => Self::BlockDevice, - // linux_raw_sys::general::DT_UNKNOWN | - _ => Self::Unknown, - } - } -} - -/// `POSIX_FADV_*` constants for use with [`fadvise`]. -/// -/// [`fadvise`]: crate::fs::fadvise -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum Advice { - /// `POSIX_FADV_NORMAL` - Normal = linux_raw_sys::general::POSIX_FADV_NORMAL, - - /// `POSIX_FADV_SEQUENTIAL` - Sequential = linux_raw_sys::general::POSIX_FADV_SEQUENTIAL, - - /// `POSIX_FADV_RANDOM` - Random = linux_raw_sys::general::POSIX_FADV_RANDOM, - - /// `POSIX_FADV_NOREUSE` - NoReuse = linux_raw_sys::general::POSIX_FADV_NOREUSE, - - /// `POSIX_FADV_WILLNEED` - WillNeed = linux_raw_sys::general::POSIX_FADV_WILLNEED, - - /// `POSIX_FADV_DONTNEED` - DontNeed = linux_raw_sys::general::POSIX_FADV_DONTNEED, -} - -bitflags! { - /// `MFD_*` constants for use with [`memfd_create`]. - /// - /// [`memfd_create`]: crate::fs::memfd_create - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MemfdFlags: ffi::c_uint { - /// `MFD_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::MFD_CLOEXEC; - - /// `MFD_ALLOW_SEALING` - const ALLOW_SEALING = linux_raw_sys::general::MFD_ALLOW_SEALING; - - /// `MFD_HUGETLB` (since Linux 4.14) - const HUGETLB = linux_raw_sys::general::MFD_HUGETLB; - - /// `MFD_NOEXEC_SEAL` (since Linux 6.3) - const NOEXEC_SEAL = linux_raw_sys::general::MFD_NOEXEC_SEAL; - /// `MFD_EXEC` (since Linux 6.3) - const EXEC = linux_raw_sys::general::MFD_EXEC; - - /// `MFD_HUGE_64KB` - const HUGE_64KB = linux_raw_sys::general::MFD_HUGE_64KB; - /// `MFD_HUGE_512KB` - const HUGE_512KB = linux_raw_sys::general::MFD_HUGE_512KB; - /// `MFD_HUGE_1MB` - const HUGE_1MB = linux_raw_sys::general::MFD_HUGE_1MB; - /// `MFD_HUGE_2MB` - const HUGE_2MB = linux_raw_sys::general::MFD_HUGE_2MB; - /// `MFD_HUGE_8MB` - const HUGE_8MB = linux_raw_sys::general::MFD_HUGE_8MB; - /// `MFD_HUGE_16MB` - const HUGE_16MB = linux_raw_sys::general::MFD_HUGE_16MB; - /// `MFD_HUGE_32MB` - const HUGE_32MB = linux_raw_sys::general::MFD_HUGE_32MB; - /// `MFD_HUGE_256MB` - const HUGE_256MB = linux_raw_sys::general::MFD_HUGE_256MB; - /// `MFD_HUGE_512MB` - const HUGE_512MB = linux_raw_sys::general::MFD_HUGE_512MB; - /// `MFD_HUGE_1GB` - const HUGE_1GB = linux_raw_sys::general::MFD_HUGE_1GB; - /// `MFD_HUGE_2GB` - const HUGE_2GB = linux_raw_sys::general::MFD_HUGE_2GB; - /// `MFD_HUGE_16GB` - const HUGE_16GB = linux_raw_sys::general::MFD_HUGE_16GB; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and - /// [`fcntl_get_seals`]. - /// - /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals - /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SealFlags: u32 { - /// `F_SEAL_SEAL` - const SEAL = linux_raw_sys::general::F_SEAL_SEAL; - /// `F_SEAL_SHRINK` - const SHRINK = linux_raw_sys::general::F_SEAL_SHRINK; - /// `F_SEAL_GROW` - const GROW = linux_raw_sys::general::F_SEAL_GROW; - /// `F_SEAL_WRITE` - const WRITE = linux_raw_sys::general::F_SEAL_WRITE; - /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) - const FUTURE_WRITE = linux_raw_sys::general::F_SEAL_FUTURE_WRITE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `FALLOC_FL_*` constants for use with [`fallocate`]. - /// - /// [`fallocate`]: crate::fs::fallocate - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FallocateFlags: u32 { - /// `FALLOC_FL_KEEP_SIZE` - const KEEP_SIZE = linux_raw_sys::general::FALLOC_FL_KEEP_SIZE; - /// `FALLOC_FL_PUNCH_HOLE` - const PUNCH_HOLE = linux_raw_sys::general::FALLOC_FL_PUNCH_HOLE; - /// `FALLOC_FL_NO_HIDE_STALE` - const NO_HIDE_STALE = linux_raw_sys::general::FALLOC_FL_NO_HIDE_STALE; - /// `FALLOC_FL_COLLAPSE_RANGE` - const COLLAPSE_RANGE = linux_raw_sys::general::FALLOC_FL_COLLAPSE_RANGE; - /// `FALLOC_FL_ZERO_RANGE` - const ZERO_RANGE = linux_raw_sys::general::FALLOC_FL_ZERO_RANGE; - /// `FALLOC_FL_INSERT_RANGE` - const INSERT_RANGE = linux_raw_sys::general::FALLOC_FL_INSERT_RANGE; - /// `FALLOC_FL_UNSHARE_RANGE` - const UNSHARE_RANGE = linux_raw_sys::general::FALLOC_FL_UNSHARE_RANGE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `ST_*` constants for use with [`StatVfs`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct StatVfsMountFlags: u64 { - /// `ST_MANDLOCK` - const MANDLOCK = linux_raw_sys::general::MS_MANDLOCK as u64; - - /// `ST_NOATIME` - const NOATIME = linux_raw_sys::general::MS_NOATIME as u64; - - /// `ST_NODEV` - const NODEV = linux_raw_sys::general::MS_NODEV as u64; - - /// `ST_NODIRATIME` - const NODIRATIME = linux_raw_sys::general::MS_NODIRATIME as u64; - - /// `ST_NOEXEC` - const NOEXEC = linux_raw_sys::general::MS_NOEXEC as u64; - - /// `ST_NOSUID` - const NOSUID = linux_raw_sys::general::MS_NOSUID as u64; - - /// `ST_RDONLY` - const RDONLY = linux_raw_sys::general::MS_RDONLY as u64; - - /// `ST_RELATIME` - const RELATIME = linux_raw_sys::general::MS_RELATIME as u64; - - /// `ST_SYNCHRONOUS` - const SYNCHRONOUS = linux_raw_sys::general::MS_SYNCHRONOUS as u64; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `LOCK_*` constants for use with [`flock`] and [`fcntl_lock`]. -/// -/// [`flock`]: crate::fs::flock -/// [`fcntl_lock`]: crate::fs::fcntl_lock -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(u32)] -pub enum FlockOperation { - /// `LOCK_SH` - LockShared = linux_raw_sys::general::LOCK_SH, - /// `LOCK_EX` - LockExclusive = linux_raw_sys::general::LOCK_EX, - /// `LOCK_UN` - Unlock = linux_raw_sys::general::LOCK_UN, - /// `LOCK_SH | LOCK_NB` - NonBlockingLockShared = linux_raw_sys::general::LOCK_SH | linux_raw_sys::general::LOCK_NB, - /// `LOCK_EX | LOCK_NB` - NonBlockingLockExclusive = linux_raw_sys::general::LOCK_EX | linux_raw_sys::general::LOCK_NB, - /// `LOCK_UN | LOCK_NB` - NonBlockingUnlock = linux_raw_sys::general::LOCK_UN | linux_raw_sys::general::LOCK_NB, -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -// On 32-bit with `struct stat64` and mips64 with `struct stat`, Linux's -// `st_mtime` and friends are 32-bit, so we use our own struct, populated from -// `statx` where possible, to avoid the y2038 bug. -#[cfg(any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" -))] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -pub struct Stat { - pub st_dev: u64, - pub st_mode: u32, - pub st_nlink: u32, - pub st_uid: u32, - pub st_gid: u32, - pub st_rdev: u64, - pub st_size: i64, - pub st_blksize: u32, - pub st_blocks: u64, - pub st_atime: i64, - pub st_atime_nsec: u32, - pub st_mtime: i64, - pub st_mtime_nsec: u32, - pub st_ctime: i64, - pub st_ctime_nsec: u32, - pub st_ino: u64, -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -#[cfg(target_arch = "x86_64")] -pub struct Stat { - pub st_dev: ffi::c_ulong, - pub st_ino: ffi::c_ulong, - pub st_nlink: ffi::c_ulong, - pub st_mode: ffi::c_uint, - pub st_uid: ffi::c_uint, - pub st_gid: ffi::c_uint, - pub(crate) __pad0: ffi::c_uint, - pub st_rdev: ffi::c_ulong, - pub st_size: ffi::c_long, - pub st_blksize: ffi::c_long, - pub st_blocks: ffi::c_long, - pub st_atime: ffi::c_long, - pub st_atime_nsec: ffi::c_ulong, - pub st_mtime: ffi::c_long, - pub st_mtime_nsec: ffi::c_ulong, - pub st_ctime: ffi::c_long, - pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused: [ffi::c_long; 3], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -#[cfg(target_arch = "aarch64")] -pub struct Stat { - pub st_dev: ffi::c_ulong, - pub st_ino: ffi::c_ulong, - pub st_mode: ffi::c_uint, - pub st_nlink: ffi::c_uint, - pub st_uid: ffi::c_uint, - pub st_gid: ffi::c_uint, - pub st_rdev: ffi::c_ulong, - pub(crate) __pad1: ffi::c_ulong, - pub st_size: ffi::c_long, - pub st_blksize: ffi::c_int, - pub(crate) __pad2: ffi::c_int, - pub st_blocks: ffi::c_long, - pub st_atime: ffi::c_long, - pub st_atime_nsec: ffi::c_ulong, - pub st_mtime: ffi::c_long, - pub st_mtime_nsec: ffi::c_ulong, - pub st_ctime: ffi::c_long, - pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused4: ffi::c_uint, - pub(crate) __unused5: ffi::c_uint, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -#[cfg(target_arch = "riscv64")] -pub struct Stat { - pub st_dev: ffi::c_ulong, - pub st_ino: ffi::c_ulong, - pub st_mode: ffi::c_uint, - pub st_nlink: ffi::c_uint, - pub st_uid: ffi::c_uint, - pub st_gid: ffi::c_uint, - pub st_rdev: ffi::c_ulong, - pub(crate) __pad1: ffi::c_ulong, - pub st_size: ffi::c_long, - pub st_blksize: ffi::c_int, - pub(crate) __pad2: ffi::c_int, - pub st_blocks: ffi::c_long, - pub st_atime: ffi::c_long, - pub st_atime_nsec: ffi::c_ulong, - pub st_mtime: ffi::c_long, - pub st_mtime_nsec: ffi::c_ulong, - pub st_ctime: ffi::c_long, - pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused4: ffi::c_uint, - pub(crate) __unused5: ffi::c_uint, -} -// This follows `stat`. powerpc64 defines a `stat64` but it's not used. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -#[cfg(target_arch = "powerpc64")] -pub struct Stat { - pub st_dev: ffi::c_ulong, - pub st_ino: ffi::c_ulong, - pub st_nlink: ffi::c_ulong, - pub st_mode: ffi::c_uint, - pub st_uid: ffi::c_uint, - pub st_gid: ffi::c_uint, - pub st_rdev: ffi::c_ulong, - pub st_size: ffi::c_long, - pub st_blksize: ffi::c_ulong, - pub st_blocks: ffi::c_ulong, - pub st_atime: ffi::c_long, - pub st_atime_nsec: ffi::c_ulong, - pub st_mtime: ffi::c_long, - pub st_mtime_nsec: ffi::c_ulong, - pub st_ctime: ffi::c_long, - pub st_ctime_nsec: ffi::c_ulong, - pub(crate) __unused4: ffi::c_ulong, - pub(crate) __unused5: ffi::c_ulong, - pub(crate) __unused6: ffi::c_ulong, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -#[cfg(target_arch = "s390x")] -pub struct Stat { - pub st_dev: ffi::c_ulong, - pub st_ino: ffi::c_ulong, - pub st_nlink: ffi::c_ulong, - pub st_mode: ffi::c_uint, - pub st_uid: ffi::c_uint, - pub st_gid: ffi::c_uint, - pub(crate) __pad1: ffi::c_uint, - pub st_rdev: ffi::c_ulong, - pub st_size: ffi::c_long, // Linux has `c_ulong` but we make it signed. - pub st_atime: ffi::c_long, - pub st_atime_nsec: ffi::c_ulong, - pub st_mtime: ffi::c_long, - pub st_mtime_nsec: ffi::c_ulong, - pub st_ctime: ffi::c_long, - pub st_ctime_nsec: ffi::c_ulong, - pub st_blksize: ffi::c_ulong, - pub st_blocks: ffi::c_long, - pub(crate) __unused: [ffi::c_ulong; 3], -} - -/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. -/// -/// [`statfs`]: crate::fs::statfs -/// [`fstatfs`]: crate::fs::fstatfs -#[allow(clippy::module_name_repetitions)] -#[repr(C)] -#[cfg_attr(target_arch = "arm", repr(packed(4)))] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -pub struct StatFs { - pub f_type: FsWord, - #[cfg(not(any(target_arch = "arm", target_arch = "s390x")))] - pub f_bsize: ffi::c_long, - #[cfg(any(target_arch = "arm", target_arch = "s390x"))] - pub f_bsize: ffi::c_uint, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_fsid: Fsid, - #[cfg(not(any(target_arch = "arm", target_arch = "s390x")))] - pub f_namelen: ffi::c_long, - #[cfg(any(target_arch = "arm", target_arch = "s390x"))] - pub f_namelen: ffi::c_uint, - #[cfg(not(any(target_arch = "arm", target_arch = "s390x")))] - pub f_frsize: ffi::c_long, - #[cfg(any(target_arch = "arm", target_arch = "s390x"))] - pub f_frsize: ffi::c_uint, - #[cfg(not(any(target_arch = "arm", target_arch = "s390x")))] - pub f_flags: ffi::c_long, - #[cfg(any(target_arch = "arm", target_arch = "s390x"))] - pub f_flags: ffi::c_uint, - #[cfg(not(target_arch = "s390x"))] - pub(crate) f_spare: [ffi::c_long; 4], - #[cfg(target_arch = "s390x")] - pub(crate) f_spare: [ffi::c_uint; 5], -} - -/// `fsid_t` for use with [`StatFs`]. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -pub struct Fsid { - pub(crate) val: [ffi::c_int; 2], -} - -/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`]. -/// -/// [`statvfs`]: crate::fs::statvfs -/// [`fstatvfs`]: crate::fs::fstatvfs -#[allow(missing_docs)] -pub struct StatVfs { - pub f_bsize: u64, - pub f_frsize: u64, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_favail: u64, - pub f_fsid: u64, - pub f_flag: StatVfsMountFlags, - pub f_namemax: u64, -} - -/// `mode_t` -pub type RawMode = ffi::c_uint; - -/// `dev_t` -// Within the kernel the `dev_t` is 32-bit, but userspace uses a 64-bit field. -pub type Dev = u64; - -/// `__fsword_t` -#[cfg(not(any( - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "s390x" -)))] -pub type FsWord = ffi::c_long; - -/// `__fsword_t` -#[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] -pub type FsWord = i64; - -/// `__fsword_t` -#[cfg(target_arch = "s390x")] -pub type FsWord = u32; diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs deleted file mode 100644 index 4ddf6df5..00000000 --- a/vendor/rustix/src/backend/linux_raw/io/errno.rs +++ /dev/null @@ -1,552 +0,0 @@ -//! 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/9799919799/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§ion=2 -/// [illumos]: https://illumos.org/man/3C/errno -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Error-Codes.html -#[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", feature = "system"))] -#[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 deleted file mode 100644 index 9477b9b9..00000000 --- a/vendor/rustix/src/backend/linux_raw/io/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index f40dfe5e..00000000 --- a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs +++ /dev/null @@ -1,364 +0,0 @@ -//! 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", - target_arch = "powerpc" - ), -))] -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 as _, BorrowedFd, OwnedFd, RawFd}; -use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags}; -use crate::ioctl::{IoctlOutput, Opcode}; -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, usize)) -> io::Result<usize> { - ret_usize(syscall!(__NR_read, fd, buf.0, pass_usize(buf.1))) -} - -#[inline] -pub(crate) unsafe fn pread( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - pos: u64, -) -> io::Result<usize> { - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/sys32.c?h=v6.13#n70> - #[cfg(all( - target_pointer_width = "32", - any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc" - ), - ))] - { - ret_usize(syscall!( - __NR_pread64, - fd, - buf.0, - pass_usize(buf.1), - zero(), - hi(pos), - lo(pos) - )) - } - #[cfg(all( - target_pointer_width = "32", - not(any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc" - )), - ))] - { - ret_usize(syscall!( - __NR_pread64, - fd, - buf.0, - pass_usize(buf.1), - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - ret_usize(syscall!( - __NR_pread64, - fd, - buf.0, - pass_usize(buf.1), - 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://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/sys32.c?h=v6.13#n76> - #[cfg(all( - target_pointer_width = "32", - any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc" - ), - ))] - 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", - target_arch = "powerpc" - )), - ))] - 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(); -} - -#[cfg(feature = "try_close")] -#[inline] -pub(crate) unsafe fn try_close(fd: RawFd) -> io::Result<()> { - ret(syscall_readonly!(__NR_close, raw_fd(fd))) -} - -#[inline] -pub(crate) unsafe fn ioctl( - fd: BorrowedFd<'_>, - request: Opcode, - 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: Opcode, - arg: *mut c::c_void, -) -> io::Result<IoctlOutput> { - ret_c_int(syscall_readonly!(__NR_ioctl, fd, c_uint(request), arg)) -} - -#[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 deleted file mode 100644 index 533f9732..00000000 --- a/vendor/rustix/src/backend/linux_raw/io/types.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::ffi; -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: ffi::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: ffi::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: ffi::c_uint { - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/io_uring/mod.rs b/vendor/rustix/src/backend/linux_raw/io_uring/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/linux_raw/io_uring/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs deleted file mode 100644 index 3e61b7aa..00000000 --- a/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! linux_raw syscalls supporting `rustix::io_uring`. -//! -//! # Safety -//! -//! See the `rustix::backend::syscalls` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{by_mut, c_uint, pass_usize, ret_c_uint, ret_owned_fd}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterFlags, IoringRegisterOp}; -use core::ffi::c_void; - -#[inline] -pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> { - unsafe { - ret_owned_fd(syscall!( - __NR_io_uring_setup, - c_uint(entries), - by_mut(params) - )) - } -} - -#[inline] -pub(crate) unsafe fn io_uring_register( - fd: BorrowedFd<'_>, - opcode: IoringRegisterOp, - arg: *const c_void, - nr_args: u32, -) -> io::Result<u32> { - ret_c_uint(syscall_readonly!( - __NR_io_uring_register, - fd, - c_uint(opcode as u32), - arg, - c_uint(nr_args) - )) -} - -#[inline] -pub(crate) unsafe fn io_uring_register_with( - fd: BorrowedFd<'_>, - opcode: IoringRegisterOp, - flags: IoringRegisterFlags, - arg: *const c_void, - nr_args: u32, -) -> io::Result<u32> { - ret_c_uint(syscall_readonly!( - __NR_io_uring_register, - fd, - c_uint((opcode as u32) | bitflags_bits!(flags)), - arg, - c_uint(nr_args) - )) -} - -#[inline] -pub(crate) unsafe fn io_uring_enter( - fd: BorrowedFd<'_>, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - arg: *const c_void, - size: usize, -) -> io::Result<u32> { - // This is not `_readonly` because `io_uring_enter` waits for I/O to - // complete, and I/O could involve writing to memory buffers, which - // could be a side effect depended on by the caller. - ret_c_uint(syscall!( - __NR_io_uring_enter, - fd, - c_uint(to_submit), - c_uint(min_complete), - flags, - arg, - pass_usize(size) - )) -} diff --git a/vendor/rustix/src/backend/linux_raw/mm/mod.rs b/vendor/rustix/src/backend/linux_raw/mm/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/mm/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs deleted file mode 100644 index 84881906..00000000 --- a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs +++ /dev/null @@ -1,239 +0,0 @@ -//! linux_raw syscalls supporting `rustix::io`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::types::{ - Advice, MapFlags, MlockAllFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags, - UserfaultfdFlags, -}; -use crate::backend::c; -#[cfg(target_pointer_width = "64")] -use crate::backend::conv::loff_t_from_u64; -use crate::backend::conv::{c_uint, no_fd, pass_usize, ret, ret_owned_fd, ret_void_star}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::ffi::c_void; -use crate::io; -use linux_raw_sys::general::{MAP_ANONYMOUS, MREMAP_FIXED}; - -#[inline] -pub(crate) fn madvise(addr: *mut c_void, len: usize, advice: Advice) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_madvise, - addr, - pass_usize(len), - c_uint(advice as c::c_uint) - )) - } -} - -#[inline] -pub(crate) unsafe fn msync(addr: *mut c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - ret(syscall!(__NR_msync, addr, pass_usize(len), flags)) -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn mmap( - addr: *mut c_void, - length: usize, - prot: ProtFlags, - flags: MapFlags, - fd: BorrowedFd<'_>, - offset: u64, -) -> io::Result<*mut c_void> { - #[cfg(target_pointer_width = "32")] - { - ret_void_star(syscall!( - __NR_mmap2, - addr, - pass_usize(length), - prot, - flags, - fd, - (offset / 4096) - .try_into() - .map(pass_usize) - .map_err(|_| io::Errno::INVAL)? - )) - } - #[cfg(target_pointer_width = "64")] - { - ret_void_star(syscall!( - __NR_mmap, - addr, - pass_usize(length), - prot, - flags, - fd, - loff_t_from_u64(offset) - )) - } -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn mmap_anonymous( - addr: *mut c_void, - length: usize, - prot: ProtFlags, - flags: MapFlags, -) -> io::Result<*mut c_void> { - #[cfg(target_pointer_width = "32")] - { - ret_void_star(syscall!( - __NR_mmap2, - addr, - pass_usize(length), - prot, - c_uint(flags.bits() | MAP_ANONYMOUS), - no_fd(), - pass_usize(0) - )) - } - #[cfg(target_pointer_width = "64")] - { - ret_void_star(syscall!( - __NR_mmap, - addr, - pass_usize(length), - prot, - c_uint(flags.bits() | MAP_ANONYMOUS), - no_fd(), - loff_t_from_u64(0) - )) - } -} - -#[inline] -pub(crate) unsafe fn mprotect( - ptr: *mut c_void, - len: usize, - flags: MprotectFlags, -) -> io::Result<()> { - ret(syscall!(__NR_mprotect, ptr, pass_usize(len), flags)) -} - -/// # Safety -/// -/// `munmap` is primarily unsafe due to the `addr` parameter, as anything -/// working with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn munmap(addr: *mut c_void, length: usize) -> io::Result<()> { - ret(syscall!(__NR_munmap, addr, pass_usize(length))) -} - -/// # Safety -/// -/// `mremap` is primarily unsafe due to the `old_address` parameter, as -/// anything working with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn mremap( - old_address: *mut c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, -) -> io::Result<*mut c_void> { - ret_void_star(syscall!( - __NR_mremap, - old_address, - pass_usize(old_size), - pass_usize(new_size), - flags - )) -} - -/// # Safety -/// -/// `mremap_fixed` is primarily unsafe due to the `old_address` and -/// `new_address` parameters, as anything working with memory pointed to by raw -/// pointers is unsafe. -#[inline] -pub(crate) unsafe fn mremap_fixed( - old_address: *mut c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, - new_address: *mut c_void, -) -> io::Result<*mut c_void> { - ret_void_star(syscall!( - __NR_mremap, - old_address, - pass_usize(old_size), - pass_usize(new_size), - c_uint(flags.bits() | MREMAP_FIXED), - new_address - )) -} - -/// # Safety -/// -/// `mlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn mlock(addr: *mut c_void, length: usize) -> io::Result<()> { - ret(syscall!(__NR_mlock, addr, pass_usize(length))) -} - -/// # Safety -/// -/// `mlock_with` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn mlock_with( - addr: *mut c_void, - length: usize, - flags: MlockFlags, -) -> io::Result<()> { - ret(syscall!(__NR_mlock2, addr, pass_usize(length), flags)) -} - -/// # Safety -/// -/// `munlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn munlock(addr: *mut c_void, length: usize) -> io::Result<()> { - ret(syscall!(__NR_munlock, addr, pass_usize(length))) -} - -#[inline] -pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { - ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags)) -} - -/// Locks all pages mapped into the address space of the calling process. -/// -/// This includes the pages of the code, data, and stack segment, as well as -/// shared libraries, user space kernel data, shared memory, and memory-mapped -/// files. All mapped pages are guaranteed to be resident in RAM when the call -/// returns successfully; the pages are guaranteed to stay in RAM until later -/// unlocked. -#[inline] -pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> { - // When `mlockall` is used with `MCL_ONFAULT | MCL_FUTURE`, the ordering - // of `mlockall` with respect to arbitrary loads may be significant, - // because if a load happens and evokes a fault before the `mlockall`, - // the memory doesn't get locked, but if the load and therefore - // the fault happens after, then the memory does get locked. - // - // So to be conservative in this regard, we use `syscall` instead of - // `syscall_readonly` - unsafe { ret(syscall!(__NR_mlockall, flags)) } -} - -/// Unlocks all pages mapped into the address space of the calling process. -#[inline] -pub(crate) fn munlockall() -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_munlockall)) } -} diff --git a/vendor/rustix/src/backend/linux_raw/mm/types.rs b/vendor/rustix/src/backend/linux_raw/mm/types.rs deleted file mode 100644 index c6806fc4..00000000 --- a/vendor/rustix/src/backend/linux_raw/mm/types.rs +++ /dev/null @@ -1,297 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `PROT_*` flags for use with [`mmap`]. - /// - /// For `PROT_NONE`, use `ProtFlags::empty()`. - /// - /// [`mmap`]: crate::mm::mmap - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ProtFlags: u32 { - /// `PROT_READ` - const READ = linux_raw_sys::general::PROT_READ; - /// `PROT_WRITE` - const WRITE = linux_raw_sys::general::PROT_WRITE; - /// `PROT_EXEC` - const EXEC = linux_raw_sys::general::PROT_EXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `PROT_*` flags for use with [`mprotect`]. - /// - /// For `PROT_NONE`, use `MprotectFlags::empty()`. - /// - /// [`mprotect`]: crate::mm::mprotect - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MprotectFlags: u32 { - /// `PROT_READ` - const READ = linux_raw_sys::general::PROT_READ; - /// `PROT_WRITE` - const WRITE = linux_raw_sys::general::PROT_WRITE; - /// `PROT_EXEC` - const EXEC = linux_raw_sys::general::PROT_EXEC; - /// `PROT_GROWSUP` - const GROWSUP = linux_raw_sys::general::PROT_GROWSUP; - /// `PROT_GROWSDOWN` - const GROWSDOWN = linux_raw_sys::general::PROT_GROWSDOWN; - /// `PROT_SEM` - const SEM = linux_raw_sys::general::PROT_SEM; - /// `PROT_BTI` - #[cfg(target_arch = "aarch64")] - const BTI = linux_raw_sys::general::PROT_BTI; - /// `PROT_MTE` - #[cfg(target_arch = "aarch64")] - const MTE = linux_raw_sys::general::PROT_MTE; - /// `PROT_SAO` - #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] - const SAO = linux_raw_sys::general::PROT_SAO; - /// `PROT_ADI` - #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] - const ADI = linux_raw_sys::general::PROT_ADI; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MAP_*` flags for use with [`mmap`]. - /// - /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. - /// - /// [`mmap`]: crate::mm::mmap - /// [`mmap_anonymous`]: crates::mm::mmap_anonymous - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MapFlags: u32 { - /// `MAP_SHARED` - const SHARED = linux_raw_sys::general::MAP_SHARED; - /// `MAP_SHARED_VALIDATE` (since Linux 4.15) - const SHARED_VALIDATE = linux_raw_sys::general::MAP_SHARED_VALIDATE; - /// `MAP_PRIVATE` - const PRIVATE = linux_raw_sys::general::MAP_PRIVATE; - /// `MAP_DENYWRITE` - const DENYWRITE = linux_raw_sys::general::MAP_DENYWRITE; - /// `MAP_FIXED` - const FIXED = linux_raw_sys::general::MAP_FIXED; - /// `MAP_FIXED_NOREPLACE` (since Linux 4.17) - const FIXED_NOREPLACE = linux_raw_sys::general::MAP_FIXED_NOREPLACE; - /// `MAP_GROWSDOWN` - const GROWSDOWN = linux_raw_sys::general::MAP_GROWSDOWN; - /// `MAP_HUGETLB` - const HUGETLB = linux_raw_sys::general::MAP_HUGETLB; - /// `MAP_HUGE_2MB` (since Linux 3.8) - const HUGE_2MB = linux_raw_sys::general::MAP_HUGE_2MB; - /// `MAP_HUGE_1GB` (since Linux 3.8) - const HUGE_1GB = linux_raw_sys::general::MAP_HUGE_1GB; - /// `MAP_LOCKED` - const LOCKED = linux_raw_sys::general::MAP_LOCKED; - /// `MAP_NORESERVE` - const NORESERVE = linux_raw_sys::general::MAP_NORESERVE; - /// `MAP_POPULATE` - const POPULATE = linux_raw_sys::general::MAP_POPULATE; - /// `MAP_STACK` - const STACK = linux_raw_sys::general::MAP_STACK; - /// `MAP_SYNC` (since Linux 4.15) - #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6", target_arch = "mips64", target_arch = "mips64r6")))] - const SYNC = linux_raw_sys::general::MAP_SYNC; - /// `MAP_UNINITIALIZED` - #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6", target_arch = "mips64", target_arch = "mips64r6")))] - const UNINITIALIZED = linux_raw_sys::general::MAP_UNINITIALIZED; - /// `MAP_DROPPABLE` - const DROPPABLE = linux_raw_sys::general::MAP_DROPPABLE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MREMAP_*` flags for use with [`mremap`]. - /// - /// For `MREMAP_FIXED`, see [`mremap_fixed`]. - /// - /// [`mremap`]: crate::mm::mremap - /// [`mremap_fixed`]: crate::mm::mremap_fixed - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MremapFlags: u32 { - /// `MREMAP_MAYMOVE` - const MAYMOVE = linux_raw_sys::general::MREMAP_MAYMOVE; - /// `MREMAP_DONTUNMAP` (since Linux 5.7) - const DONTUNMAP = linux_raw_sys::general::MREMAP_DONTUNMAP; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MS_*` flags for use with [`msync`]. - /// - /// [`msync`]: crate::mm::msync - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MsyncFlags: u32 { - /// `MS_SYNC`—Requests an update and waits for it to complete. - const SYNC = linux_raw_sys::general::MS_SYNC; - /// `MS_ASYNC`—Specifies that an update be scheduled, but the call - /// returns immediately. - const ASYNC = linux_raw_sys::general::MS_ASYNC; - /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same - /// file (so that they can be updated with the fresh values just - /// written). - const INVALIDATE = linux_raw_sys::general::MS_INVALIDATE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MLOCK_*` flags for use with [`mlock_with`]. - /// - /// [`mlock_with`]: crate::mm::mlock_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MlockFlags: u32 { - /// `MLOCK_ONFAULT` - const ONFAULT = linux_raw_sys::general::MLOCK_ONFAULT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `POSIX_MADV_*` constants for use with [`madvise`]. -/// -/// [`madvise`]: crate::mm::madvise -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -#[non_exhaustive] -pub enum Advice { - /// `POSIX_MADV_NORMAL` - Normal = linux_raw_sys::general::MADV_NORMAL, - - /// `POSIX_MADV_SEQUENTIAL` - Sequential = linux_raw_sys::general::MADV_SEQUENTIAL, - - /// `POSIX_MADV_RANDOM` - Random = linux_raw_sys::general::MADV_RANDOM, - - /// `POSIX_MADV_WILLNEED` - WillNeed = linux_raw_sys::general::MADV_WILLNEED, - - /// `MADV_DONTNEED` - LinuxDontNeed = linux_raw_sys::general::MADV_DONTNEED, - - /// `MADV_FREE` (since Linux 4.5) - LinuxFree = linux_raw_sys::general::MADV_FREE, - /// `MADV_REMOVE` - LinuxRemove = linux_raw_sys::general::MADV_REMOVE, - /// `MADV_DONTFORK` - LinuxDontFork = linux_raw_sys::general::MADV_DONTFORK, - /// `MADV_DOFORK` - LinuxDoFork = linux_raw_sys::general::MADV_DOFORK, - /// `MADV_HWPOISON` - LinuxHwPoison = linux_raw_sys::general::MADV_HWPOISON, - /// `MADV_SOFT_OFFLINE` - #[cfg(not(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )))] - LinuxSoftOffline = linux_raw_sys::general::MADV_SOFT_OFFLINE, - /// `MADV_MERGEABLE` - LinuxMergeable = linux_raw_sys::general::MADV_MERGEABLE, - /// `MADV_UNMERGEABLE` - LinuxUnmergeable = linux_raw_sys::general::MADV_UNMERGEABLE, - /// `MADV_HUGEPAGE` - LinuxHugepage = linux_raw_sys::general::MADV_HUGEPAGE, - /// `MADV_NOHUGEPAGE` - LinuxNoHugepage = linux_raw_sys::general::MADV_NOHUGEPAGE, - /// `MADV_DONTDUMP` (since Linux 3.4) - LinuxDontDump = linux_raw_sys::general::MADV_DONTDUMP, - /// `MADV_DODUMP` (since Linux 3.4) - LinuxDoDump = linux_raw_sys::general::MADV_DODUMP, - /// `MADV_WIPEONFORK` (since Linux 4.14) - LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK, - /// `MADV_KEEPONFORK` (since Linux 4.14) - LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK, - /// `MADV_COLD` (since Linux 5.4) - LinuxCold = linux_raw_sys::general::MADV_COLD, - /// `MADV_PAGEOUT` (since Linux 5.4) - LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT, - /// `MADV_POPULATE_READ` (since Linux 5.14) - LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ, - /// `MADV_POPULATE_WRITE` (since Linux 5.14) - LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE, - /// `MADV_DONTNEED_LOCKED` (since Linux 5.18) - LinuxDontneedLocked = linux_raw_sys::general::MADV_DONTNEED_LOCKED, -} - -#[allow(non_upper_case_globals)] -impl Advice { - /// `POSIX_MADV_DONTNEED` - /// - /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because Linux's - /// `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See `LinuxDontNeed` - /// for the Linux behavior. - pub const DontNeed: Self = Self::Normal; -} - -bitflags! { - /// `O_*` flags for use with [`userfaultfd`]. - /// - /// [`userfaultfd`]: crate::mm::userfaultfd - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UserfaultfdFlags: ffi::c_uint { - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - /// `O_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MCL_*` flags for use with [`mlockall`]. - /// - /// [`mlockall`]: crate::mm::mlockall - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MlockAllFlags: u32 { - /// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark all - /// current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`) mappings - /// to lock pages when they are faulted in. When used with - /// `MCL_CURRENT`, all present pages are locked, but `mlockall` will - /// not fault in non-present pages. When used with `MCL_FUTURE`, all - /// future mappings will be marked to lock pages when they are faulted - /// in, but they will not be populated by the lock when the mapping is - /// created. `MCL_ONFAULT` must be used with either `MCL_CURRENT` or - /// `MCL_FUTURE` or both. - const ONFAULT = linux_raw_sys::general::MCL_ONFAULT; - /// Lock all pages which will become mapped into the address space of - /// the process in the future. These could be, for instance, new pages - /// required by a growing heap and stack as well as new memory-mapped - /// files or shared memory regions. - const FUTURE = linux_raw_sys::general::MCL_FUTURE; - /// Lock all pages which are currently mapped into the address space of - /// the process. - const CURRENT = linux_raw_sys::general::MCL_CURRENT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/mod.rs b/vendor/rustix/src/backend/linux_raw/mod.rs deleted file mode 100644 index 581dcc97..00000000 --- a/vendor/rustix/src/backend/linux_raw/mod.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! The linux_raw backend. -//! -//! This makes Linux syscalls directly, without going through libc. -//! -//! # Safety -//! -//! These files performs raw system calls, and sometimes passes them -//! uninitialized memory buffers. The signatures in this module are currently -//! manually maintained and must correspond with the signatures of the actual -//! Linux syscalls. -//! -//! Some of this could be auto-generated from the Linux header file -//! <linux/syscalls.h>, but we often need more information than it provides, -//! such as which pointers are array slices, out parameters, or in-out -//! parameters, which integers are owned or borrowed file descriptors, etc. - -#[macro_use] -mod arch; -mod conv; -mod reg; -#[cfg(any(feature = "time", feature = "thread", target_arch = "x86"))] -mod vdso; -#[cfg(any(feature = "time", feature = "thread", target_arch = "x86"))] -mod vdso_wrappers; - -#[cfg(feature = "event")] -pub(crate) mod event; -#[cfg(any( - feature = "fs", - all( - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) - ) -))] -pub(crate) mod fs; -pub(crate) mod io; -#[cfg(feature = "io_uring")] -pub(crate) mod io_uring; -#[cfg(feature = "mm")] -pub(crate) mod mm; -#[cfg(feature = "mount")] -pub(crate) mod mount; -#[cfg(feature = "net")] -pub(crate) mod net; -#[cfg(any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", -))] -pub(crate) mod param; -#[cfg(feature = "pipe")] -pub(crate) mod pipe; -#[cfg(feature = "process")] -pub(crate) mod process; -#[cfg(feature = "pty")] -pub(crate) mod pty; -#[cfg(feature = "rand")] -pub(crate) mod rand; -#[cfg(feature = "runtime")] -pub(crate) mod runtime; -#[cfg(feature = "shm")] -pub(crate) mod shm; -#[cfg(feature = "system")] -pub(crate) mod system; -#[cfg(feature = "termios")] -pub(crate) mod termios; -#[cfg(feature = "thread")] -pub(crate) mod thread; -#[cfg(feature = "time")] -pub(crate) mod time; - -// Re-export the maybe-polyfill `core::os::fd`. -pub(crate) use crate::maybe_polyfill::os::fd; - -// The linux_raw backend doesn't use actual libc, so we define selected -// libc-like definitions in a module called `c`. -pub(crate) mod c; - -// Private modules used by multiple public modules. -#[cfg(any(feature = "process", feature = "runtime"))] -pub(crate) mod pid; -#[cfg(any(feature = "process", feature = "thread"))] -pub(crate) mod prctl; -#[cfg(any( - feature = "fs", - feature = "process", - feature = "thread", - all( - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "time", - target_arch = "x86", - ) - ) -))] -pub(crate) mod ugid; - -/// The maximum number of buffers that can be passed into a vectored I/O system -/// call on the current platform. -const MAX_IOV: usize = linux_raw_sys::general::UIO_MAXIOV as usize; diff --git a/vendor/rustix/src/backend/linux_raw/mount/mod.rs b/vendor/rustix/src/backend/linux_raw/mount/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/mount/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/mount/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mount/syscalls.rs deleted file mode 100644 index 6fc69240..00000000 --- a/vendor/rustix/src/backend/linux_raw/mount/syscalls.rs +++ /dev/null @@ -1,237 +0,0 @@ -//! linux_raw syscalls supporting `rustix::mount`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{ret, ret_owned_fd, slice, zero}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::ffi::CStr; -use crate::io; - -#[inline] -pub(crate) fn mount( - source: Option<&CStr>, - target: &CStr, - file_system_type: Option<&CStr>, - flags: super::types::MountFlagsArg, - data: Option<&CStr>, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_mount, - source, - target, - file_system_type, - flags, - data - )) - } -} - -#[inline] -pub(crate) fn unmount(target: &CStr, flags: super::types::UnmountFlags) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_umount2, target, flags)) } -} - -#[inline] -pub(crate) fn fsopen(fs_name: &CStr, flags: super::types::FsOpenFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_fsopen, fs_name, flags)) } -} - -#[inline] -pub(crate) fn fsmount( - fs_fd: BorrowedFd<'_>, - flags: super::types::FsMountFlags, - attr_flags: super::types::MountAttrFlags, -) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_fsmount, fs_fd, flags, attr_flags)) } -} - -#[inline] -pub(crate) fn move_mount( - from_dfd: BorrowedFd<'_>, - from_pathname: &CStr, - to_dfd: BorrowedFd<'_>, - to_pathname: &CStr, - flags: super::types::MoveMountFlags, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_move_mount, - from_dfd, - from_pathname, - to_dfd, - to_pathname, - flags - )) - } -} - -#[inline] -pub(crate) fn open_tree( - dfd: BorrowedFd<'_>, - filename: &CStr, - flags: super::types::OpenTreeFlags, -) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_open_tree, dfd, filename, flags)) } -} - -#[inline] -pub(crate) fn fspick( - dfd: BorrowedFd<'_>, - path: &CStr, - flags: super::types::FsPickFlags, -) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_fspick, dfd, path, flags)) } -} - -#[inline] -pub(crate) fn fsconfig_set_flag(fs_fd: BorrowedFd<'_>, key: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::SetFlag, - key, - zero(), - zero() - )) - } -} - -#[inline] -pub(crate) fn fsconfig_set_string( - fs_fd: BorrowedFd<'_>, - key: &CStr, - value: &CStr, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::SetString, - key, - value, - zero() - )) - } -} - -#[inline] -pub(crate) fn fsconfig_set_binary( - fs_fd: BorrowedFd<'_>, - key: &CStr, - value: &[u8], -) -> io::Result<()> { - let (value_addr, value_len) = slice(value); - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::SetBinary, - key, - value_addr, - value_len - )) - } -} - -#[inline] -pub(crate) fn fsconfig_set_fd( - fs_fd: BorrowedFd<'_>, - key: &CStr, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::SetFd, - key, - zero(), - fd - )) - } -} - -#[inline] -pub(crate) fn fsconfig_set_path( - fs_fd: BorrowedFd<'_>, - key: &CStr, - path: &CStr, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::SetPath, - key, - path, - fd - )) - } -} - -#[inline] -pub(crate) fn fsconfig_set_path_empty( - fs_fd: BorrowedFd<'_>, - key: &CStr, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::SetPathEmpty, - key, - cstr!(""), - fd - )) - } -} - -#[inline] -pub(crate) fn fsconfig_create(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::Create, - zero(), - zero(), - zero() - )) - } -} - -#[inline] -pub(crate) fn fsconfig_reconfigure(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::Reconfigure, - zero(), - zero(), - zero() - )) - } -} - -#[inline] -pub(crate) fn fsconfig_create_excl(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fsconfig, - fs_fd, - super::types::FsConfigCmd::CreateExclusive, - zero(), - zero(), - zero() - )) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/mount/types.rs b/vendor/rustix/src/backend/linux_raw/mount/types.rs deleted file mode 100644 index 548b74ed..00000000 --- a/vendor/rustix/src/backend/linux_raw/mount/types.rs +++ /dev/null @@ -1,335 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `MS_*` constants for use with [`mount`]. - /// - /// [`mount`]: crate::mount::mount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MountFlags: ffi::c_uint { - /// `MS_BIND` - const BIND = linux_raw_sys::general::MS_BIND; - - /// `MS_DIRSYNC` - const DIRSYNC = linux_raw_sys::general::MS_DIRSYNC; - - /// `MS_LAZYTIME` - const LAZYTIME = linux_raw_sys::general::MS_LAZYTIME; - - /// `MS_MANDLOCK` - #[doc(alias = "MANDLOCK")] - const PERMIT_MANDATORY_FILE_LOCKING = linux_raw_sys::general::MS_MANDLOCK; - - /// `MS_NOATIME` - const NOATIME = linux_raw_sys::general::MS_NOATIME; - - /// `MS_NODEV` - const NODEV = linux_raw_sys::general::MS_NODEV; - - /// `MS_NODIRATIME` - const NODIRATIME = linux_raw_sys::general::MS_NODIRATIME; - - /// `MS_NOEXEC` - const NOEXEC = linux_raw_sys::general::MS_NOEXEC; - - /// `MS_NOSUID` - const NOSUID = linux_raw_sys::general::MS_NOSUID; - - /// `MS_RDONLY` - const RDONLY = linux_raw_sys::general::MS_RDONLY; - - /// `MS_REC` - const REC = linux_raw_sys::general::MS_REC; - - /// `MS_RELATIME` - const RELATIME = linux_raw_sys::general::MS_RELATIME; - - /// `MS_SILENT` - const SILENT = linux_raw_sys::general::MS_SILENT; - - /// `MS_STRICTATIME` - const STRICTATIME = linux_raw_sys::general::MS_STRICTATIME; - - /// `MS_SYNCHRONOUS` - const SYNCHRONOUS = linux_raw_sys::general::MS_SYNCHRONOUS; - - /// `MS_NOSYMFOLLOW` - const NOSYMFOLLOW = linux_raw_sys::general::MS_NOSYMFOLLOW; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MNT_*` constants for use with [`unmount`]. - /// - /// [`unmount`]: crate::mount::unmount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UnmountFlags: ffi::c_uint { - /// `MNT_FORCE` - const FORCE = linux_raw_sys::general::MNT_FORCE; - /// `MNT_DETACH` - const DETACH = linux_raw_sys::general::MNT_DETACH; - /// `MNT_EXPIRE` - const EXPIRE = linux_raw_sys::general::MNT_EXPIRE; - /// `UMOUNT_NOFOLLOW` - const NOFOLLOW = linux_raw_sys::general::UMOUNT_NOFOLLOW; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `FSOPEN_*` constants for use with [`fsopen`]. - /// - /// [`fsopen`]: crate::mount::fsopen - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FsOpenFlags: ffi::c_uint { - /// `FSOPEN_CLOEXEC` - const FSOPEN_CLOEXEC = linux_raw_sys::general::FSOPEN_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `FSMOUNT_*` constants for use with [`fsmount`]. - /// - /// [`fsmount`]: crate::mount::fsmount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FsMountFlags: ffi::c_uint { - /// `FSMOUNT_CLOEXEC` - const FSMOUNT_CLOEXEC = linux_raw_sys::general::FSMOUNT_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `FSCONFIG_*` constants for use with the `fsconfig` syscall. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub(crate) enum FsConfigCmd { - /// `FSCONFIG_SET_FLAG` - SetFlag = linux_raw_sys::general::fsconfig_command::FSCONFIG_SET_FLAG as u32, - - /// `FSCONFIG_SET_STRING` - SetString = linux_raw_sys::general::fsconfig_command::FSCONFIG_SET_STRING as u32, - - /// `FSCONFIG_SET_BINARY` - SetBinary = linux_raw_sys::general::fsconfig_command::FSCONFIG_SET_BINARY as u32, - - /// `FSCONFIG_SET_PATH` - SetPath = linux_raw_sys::general::fsconfig_command::FSCONFIG_SET_PATH as u32, - - /// `FSCONFIG_SET_PATH_EMPTY` - SetPathEmpty = linux_raw_sys::general::fsconfig_command::FSCONFIG_SET_PATH_EMPTY as u32, - - /// `FSCONFIG_SET_FD` - SetFd = linux_raw_sys::general::fsconfig_command::FSCONFIG_SET_FD as u32, - - /// `FSCONFIG_CMD_CREATE` - Create = linux_raw_sys::general::fsconfig_command::FSCONFIG_CMD_CREATE as u32, - - /// `FSCONFIG_CMD_RECONFIGURE` - Reconfigure = linux_raw_sys::general::fsconfig_command::FSCONFIG_CMD_RECONFIGURE as u32, - - /// `FSCONFIG_CMD_CREATE_EXCL` (since Linux 6.6) - CreateExclusive = linux_raw_sys::general::fsconfig_command::FSCONFIG_CMD_CREATE_EXCL as u32, -} - -bitflags! { - /// `MOUNT_ATTR_*` constants for use with [`fsmount`]. - /// - /// [`fsmount`]: crate::mount::fsmount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MountAttrFlags: ffi::c_uint { - /// `MOUNT_ATTR_RDONLY` - const MOUNT_ATTR_RDONLY = linux_raw_sys::general::MOUNT_ATTR_RDONLY; - - /// `MOUNT_ATTR_NOSUID` - const MOUNT_ATTR_NOSUID = linux_raw_sys::general::MOUNT_ATTR_NOSUID; - - /// `MOUNT_ATTR_NODEV` - const MOUNT_ATTR_NODEV = linux_raw_sys::general::MOUNT_ATTR_NODEV; - - /// `MOUNT_ATTR_NOEXEC` - const MOUNT_ATTR_NOEXEC = linux_raw_sys::general::MOUNT_ATTR_NOEXEC; - - /// `MOUNT_ATTR__ATIME` - const MOUNT_ATTR__ATIME = linux_raw_sys::general::MOUNT_ATTR__ATIME; - - /// `MOUNT_ATTR_RELATIME` - const MOUNT_ATTR_RELATIME = linux_raw_sys::general::MOUNT_ATTR_RELATIME; - - /// `MOUNT_ATTR_NOATIME` - const MOUNT_ATTR_NOATIME = linux_raw_sys::general::MOUNT_ATTR_NOATIME; - - /// `MOUNT_ATTR_STRICTATIME` - const MOUNT_ATTR_STRICTATIME = linux_raw_sys::general::MOUNT_ATTR_STRICTATIME; - - /// `MOUNT_ATTR_NODIRATIME` - const MOUNT_ATTR_NODIRATIME = linux_raw_sys::general::MOUNT_ATTR_NODIRATIME; - - /// `MOUNT_ATTR_NOUSER` - const MOUNT_ATTR_IDMAP = linux_raw_sys::general::MOUNT_ATTR_IDMAP; - - /// `MOUNT_ATTR__ATIME_FLAGS` - const MOUNT_ATTR_NOSYMFOLLOW = linux_raw_sys::general::MOUNT_ATTR_NOSYMFOLLOW; - - /// `MOUNT_ATTR__ATIME_FLAGS` - const MOUNT_ATTR_SIZE_VER0 = linux_raw_sys::general::MOUNT_ATTR_SIZE_VER0; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MOVE_MOUNT_*` constants for use with [`move_mount`]. - /// - /// [`move_mount`]: crate::mount::move_mount - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MoveMountFlags: ffi::c_uint { - /// `MOVE_MOUNT_F_EMPTY_PATH` - const MOVE_MOUNT_F_SYMLINKS = linux_raw_sys::general::MOVE_MOUNT_F_SYMLINKS; - - /// `MOVE_MOUNT_F_AUTOMOUNTS` - const MOVE_MOUNT_F_AUTOMOUNTS = linux_raw_sys::general::MOVE_MOUNT_F_AUTOMOUNTS; - - /// `MOVE_MOUNT_F_EMPTY_PATH` - const MOVE_MOUNT_F_EMPTY_PATH = linux_raw_sys::general::MOVE_MOUNT_F_EMPTY_PATH; - - /// `MOVE_MOUNT_T_SYMLINKS` - const MOVE_MOUNT_T_SYMLINKS = linux_raw_sys::general::MOVE_MOUNT_T_SYMLINKS; - - /// `MOVE_MOUNT_T_AUTOMOUNTS` - const MOVE_MOUNT_T_AUTOMOUNTS = linux_raw_sys::general::MOVE_MOUNT_T_AUTOMOUNTS; - - /// `MOVE_MOUNT_T_EMPTY_PATH` - const MOVE_MOUNT_T_EMPTY_PATH = linux_raw_sys::general::MOVE_MOUNT_T_EMPTY_PATH; - - /// `MOVE_MOUNT__MASK` - const MOVE_MOUNT_SET_GROUP = linux_raw_sys::general::MOVE_MOUNT_SET_GROUP; - - /// `MOVE_MOUNT_BENEATH` (since Linux 6.5) - const MOVE_MOUNT_BENEATH = linux_raw_sys::general::MOVE_MOUNT_BENEATH; - - /// `MOVE_MOUNT__MASK` - const MOVE_MOUNT__MASK = linux_raw_sys::general::MOVE_MOUNT__MASK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `OPENTREE_*` constants for use with [`open_tree`]. - /// - /// [`open_tree`]: crate::mount::open_tree - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct OpenTreeFlags: ffi::c_uint { - /// `OPENTREE_CLONE` - const OPEN_TREE_CLONE = linux_raw_sys::general::OPEN_TREE_CLONE; - - /// `OPENTREE_CLOEXEC` - const OPEN_TREE_CLOEXEC = linux_raw_sys::general::OPEN_TREE_CLOEXEC; - - /// `AT_EMPTY_PATH` - const AT_EMPTY_PATH = linux_raw_sys::general::AT_EMPTY_PATH; - - /// `AT_NO_AUTOMOUNT` - const AT_NO_AUTOMOUNT = linux_raw_sys::general::AT_NO_AUTOMOUNT; - - /// `AT_RECURSIVE` - const AT_RECURSIVE = linux_raw_sys::general::AT_RECURSIVE; - - /// `AT_SYMLINK_NOFOLLOW` - const AT_SYMLINK_NOFOLLOW = linux_raw_sys::general::AT_SYMLINK_NOFOLLOW; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `FSPICK_*` constants for use with [`fspick`]. - /// - /// [`fspick`]: crate::mount::fspick - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FsPickFlags: ffi::c_uint { - /// `FSPICK_CLOEXEC` - const FSPICK_CLOEXEC = linux_raw_sys::general::FSPICK_CLOEXEC; - - /// `FSPICK_SYMLINK_NOFOLLOW` - const FSPICK_SYMLINK_NOFOLLOW = linux_raw_sys::general::FSPICK_SYMLINK_NOFOLLOW; - - /// `FSPICK_NO_AUTOMOUNT` - const FSPICK_NO_AUTOMOUNT = linux_raw_sys::general::FSPICK_NO_AUTOMOUNT; - - /// `FSPICK_EMPTY_PATH` - const FSPICK_EMPTY_PATH = linux_raw_sys::general::FSPICK_EMPTY_PATH; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MS_*` constants for use with [`mount_change`]. - /// - /// [`mount_change`]: crate::mount::mount_change - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MountPropagationFlags: ffi::c_uint { - /// `MS_SILENT` - const SILENT = linux_raw_sys::general::MS_SILENT; - /// `MS_SHARED` - const SHARED = linux_raw_sys::general::MS_SHARED; - /// `MS_PRIVATE` - const PRIVATE = linux_raw_sys::general::MS_PRIVATE; - /// Mark a mount as a downstream of its current peer group. - /// - /// Mount and unmount events propagate from the upstream peer group - /// into the downstream. - /// - /// In Linux documentation, this flag is named `MS_SLAVE`, and the - /// concepts of “upstream” and “downstream” are called - /// “master” and “slave”. - #[doc(alias = "SLAVE")] - const DOWNSTREAM = linux_raw_sys::general::MS_SLAVE; - /// `MS_UNBINDABLE` - const UNBINDABLE = linux_raw_sys::general::MS_UNBINDABLE; - /// `MS_REC` - const REC = linux_raw_sys::general::MS_REC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub(crate) struct InternalMountFlags: ffi::c_uint { - const REMOUNT = linux_raw_sys::general::MS_REMOUNT; - const MOVE = linux_raw_sys::general::MS_MOVE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[repr(transparent)] -pub(crate) struct MountFlagsArg(pub(crate) ffi::c_uint); diff --git a/vendor/rustix/src/backend/linux_raw/net/addr.rs b/vendor/rustix/src/backend/linux_raw/net/addr.rs deleted file mode 100644 index 7138b571..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/addr.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! Socket address utilities. -//! -//! # Safety -//! -//! This file uses `CStr::from_bytes_with_nul_unchecked` on a string it knows -//! to be NUL-terminated. -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::ffi::CStr; -use crate::net::addr::SocketAddrLen; -use crate::net::AddressFamily; -use crate::{io, path}; -use core::cmp::Ordering; -use core::hash::{Hash, Hasher}; -use core::{fmt, slice}; -#[cfg(feature = "alloc")] -use {crate::ffi::CString, alloc::borrow::Cow, alloc::vec::Vec}; - -/// `struct sockaddr_un` -#[derive(Clone)] -#[doc(alias = "sockaddr_un")] -pub struct SocketAddrUnix { - pub(crate) unix: c::sockaddr_un, - len: c::socklen_t, -} - -impl SocketAddrUnix { - /// Construct a new Unix-domain address from a filesystem path. - #[inline] - pub fn new<P: path::Arg>(path: P) -> io::Result<Self> { - path.into_with_c_str(Self::_new) - } - - #[inline] - fn _new(path: &CStr) -> io::Result<Self> { - let mut unix = Self::init(); - let mut bytes = path.to_bytes_with_nul(); - if bytes.len() > unix.sun_path.len() { - bytes = path.to_bytes(); // without NUL - if bytes.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - } - for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = bitcast!(*b); - } - let len = offsetof_sun_path() + bytes.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) - } - - /// Construct a new abstract Unix-domain address from a byte slice. - #[inline] - pub fn new_abstract_name(name: &[u8]) -> io::Result<Self> { - let mut unix = Self::init(); - let id = &mut unix.sun_path[1..]; - - // SAFETY: Convert `&mut [c_char]` to `&mut [u8]`. - let id = unsafe { slice::from_raw_parts_mut(id.as_mut_ptr().cast::<u8>(), id.len()) }; - - if let Some(id) = id.get_mut(..name.len()) { - id.copy_from_slice(name); - let len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) - } else { - Err(io::Errno::NAMETOOLONG) - } - } - - /// Construct a new unnamed address. - /// - /// The kernel will assign an abstract Unix-domain address to the socket - /// when you call [`bind`][crate::net::bind]. You can inspect the assigned - /// name with [`getsockname`][crate::net::getsockname]. - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://www.man7.org/linux/man-pages/man7/unix.7.html - #[inline] - pub fn new_unnamed() -> Self { - Self { - unix: Self::init(), - len: offsetof_sun_path() as SocketAddrLen, - } - } - - const fn init() -> c::sockaddr_un { - c::sockaddr_un { - sun_family: c::AF_UNIX as _, - sun_path: [0; 108], - } - } - - /// For a filesystem path address, return the path. - #[inline] - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - pub fn path(&self) -> Option<Cow<'_, CStr>> { - let bytes = self.bytes()?; - if !bytes.is_empty() && bytes[0] != 0 { - if self.unix.sun_path.len() == bytes.len() { - // SAFETY: There are no NULs contained in bytes. - unsafe { Self::path_with_termination(bytes) } - } else { - // SAFETY: `from_bytes_with_nul_unchecked` since the string is - // NUL-terminated. - Some(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }.into()) - } - } else { - None - } - } - - /// If the `sun_path` field is not NUL-terminated, terminate it. - /// - /// SAFETY: The input `bytes` must not contain any NULs. - #[cfg(feature = "alloc")] - #[cold] - unsafe fn path_with_termination(bytes: &[u8]) -> Option<Cow<'_, CStr>> { - let mut owned = Vec::with_capacity(bytes.len() + 1); - owned.extend_from_slice(bytes); - owned.push(b'\0'); - // SAFETY: `from_vec_with_nul_unchecked` since the string is - // NUL-terminated and `bytes` does not contain any NULs. - Some(Cow::Owned( - CString::from_vec_with_nul_unchecked(owned).into(), - )) - } - - /// For a filesystem path address, return the path as a byte sequence, - /// excluding the NUL terminator. - #[inline] - pub fn path_bytes(&self) -> Option<&[u8]> { - let bytes = self.bytes()?; - if !bytes.is_empty() && bytes[0] != 0 { - if self.unix.sun_path.len() == self.len() - offsetof_sun_path() { - // There is no NUL terminator. - Some(bytes) - } else { - // Remove the NUL terminator. - Some(&bytes[..bytes.len() - 1]) - } - } else { - None - } - } - - /// For an abstract address, return the identifier. - #[inline] - pub fn abstract_name(&self) -> Option<&[u8]> { - if let [0, bytes @ ..] = self.bytes()? { - Some(bytes) - } else { - None - } - } - - /// `true` if the socket address is unnamed. - #[inline] - pub fn is_unnamed(&self) -> bool { - self.bytes() == Some(&[]) - } - - #[inline] - pub(crate) fn addr_len(&self) -> SocketAddrLen { - bitcast!(self.len) - } - - #[inline] - pub(crate) fn len(&self) -> usize { - self.addr_len() as usize - } - - #[inline] - fn bytes(&self) -> Option<&[u8]> { - let len = self.len(); - if len != 0 { - let bytes = &self.unix.sun_path[..len - offsetof_sun_path()]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. - Some(unsafe { slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len()) }) - } else { - None - } - } -} - -impl PartialEq for SocketAddrUnix { - #[inline] - fn eq(&self, other: &Self) -> bool { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) - } -} - -impl Eq for SocketAddrUnix {} - -impl PartialOrd for SocketAddrUnix { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for SocketAddrUnix { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].cmp(&other.unix.sun_path[..other_len]) - } -} - -impl Hash for SocketAddrUnix { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - let self_len = self.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].hash(state) - } -} - -impl fmt::Debug for SocketAddrUnix { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "alloc")] - if let Some(path) = self.path() { - return path.fmt(f); - } - if let Some(bytes) = self.path_bytes() { - if let Ok(s) = core::str::from_utf8(bytes) { - return s.fmt(f); - } - return bytes.fmt(f); - } - if let Some(name) = self.abstract_name() { - return name.fmt(f); - } - "(unnamed)".fmt(f) - } -} - -/// `struct sockaddr_storage` -/// -/// This type is guaranteed to be large enough to hold any encoded socket -/// address. -#[repr(transparent)] -#[derive(Copy, Clone)] -#[doc(alias = "sockaddr_storage")] -pub struct SocketAddrStorage(c::sockaddr_storage); - -// SAFETY: Bindgen adds a union with a raw pointer for alignment but it's never -// used. `sockaddr_storage` is just a bunch of bytes and it doesn't hold -// pointers. -unsafe impl Send for SocketAddrStorage {} - -// SAFETY: Same as with `Send`. -unsafe impl Sync for SocketAddrStorage {} - -impl SocketAddrStorage { - /// Return a socket addr storage initialized to all zero bytes. The - /// `sa_family` is set to [`AddressFamily::UNSPEC`]. - pub fn zeroed() -> Self { - assert_eq!(c::AF_UNSPEC, 0); - // SAFETY: `sockaddr_storage` is meant to be zero-initializable. - unsafe { core::mem::zeroed() } - } - - /// Return the `sa_family` of this socket address. - pub fn family(&self) -> AddressFamily { - // SAFETY: `self.0` is a `sockaddr_storage` so it has enough space. - unsafe { - AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family( - crate::utils::as_ptr(&self.0).cast::<c::sockaddr>(), - )) - } - } - - /// Clear the `sa_family` of this socket address to - /// [`AddressFamily::UNSPEC`]. - pub fn clear_family(&mut self) { - // SAFETY: `self.0` is a `sockaddr_storage` so it has enough space. - unsafe { - crate::backend::net::read_sockaddr::initialize_family_to_unspec( - crate::utils::as_mut_ptr(&mut self.0).cast::<c::sockaddr>(), - ) - } - } -} - -/// Return the offset of the `sun_path` field of `sockaddr_un`. -#[inline] -pub(crate) fn offsetof_sun_path() -> usize { - let z = c::sockaddr_un { - sun_family: 0_u16, - sun_path: [0; 108], - }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) -} diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs deleted file mode 100644 index 169954f2..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub(crate) mod addr; -pub(crate) mod msghdr; -pub(crate) mod netdevice; -pub(crate) mod read_sockaddr; -pub(crate) mod send_recv; -pub(crate) mod sockopt; -pub(crate) mod syscalls; -pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs deleted file mode 100644 index 0343e18c..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs +++ /dev/null @@ -1,125 +0,0 @@ -//! Utilities for dealing with message headers. -//! -//! These take closures rather than returning a `c::msghdr` directly because -//! the message headers may reference stack-local data. - -#![allow(unsafe_code)] - -use crate::backend::c; - -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::addr::SocketAddrArg; -use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrBuf}; - -use core::ptr::null_mut; - -fn msg_iov_len(len: usize) -> c::size_t { - // This cast cannot overflow. - len as c::size_t -} - -fn msg_control_len(len: usize) -> c::size_t { - // Same as above. - len as c::size_t -} - -/// Create a message header intended to receive a datagram. -/// -/// # Safety -/// -/// If `f` dereferences the pointers in the `msghdr`, it must do so only within -/// the bounds indicated by the associated lengths in the `msghdr`. -/// -/// And, if `f` returns `Ok`, it must have updated the `msg_controllen` field -/// of the `msghdr` to indicate how many bytes it initialized. -pub(crate) unsafe fn with_recv_msghdr<R>( - name: &mut SocketAddrBuf, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - f: impl FnOnce(&mut c::msghdr) -> io::Result<R>, -) -> io::Result<R> { - control.clear(); - - let mut msghdr = c::msghdr { - msg_name: name.storage.as_mut_ptr().cast(), - msg_namelen: bitcast!(name.len), - msg_iov: iov.as_mut_ptr().cast(), - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - }; - - let res = f(&mut msghdr); - - // Reset the control length. - if res.is_ok() { - // SAFETY: `f` returned `Ok`, so our safety condition requires `f` to - // have initialized `msg_controllen` bytes. - control.set_control_len(msghdr.msg_controllen as usize); - } - - name.len = bitcast!(msghdr.msg_namelen); - - res -} - -/// Create a message header intended to send without an address. -/// -/// The returned `msghdr` will contain raw pointers to the memory -/// referenced by `iov` and `control`. -pub(crate) fn noaddr_msghdr( - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, -) -> c::msghdr { - c::msghdr { - msg_name: null_mut(), - msg_namelen: 0, - msg_iov: iov.as_ptr() as _, - msg_iovlen: msg_iov_len(iov.len()), - msg_control: control.as_control_ptr().cast(), - msg_controllen: msg_control_len(control.control_len()), - msg_flags: 0, - } -} - -/// Create a message header intended to send with the specified address. -/// -/// This creates a `c::msghdr` and calls a function `f` on it. The `msghdr`'s -/// raw pointers may point to temporaries, so this function should avoid -/// storing the pointers anywhere that would outlive the function call. -/// -/// # Safety -/// -/// If `f` dereferences the pointers in the `msghdr`, it must do so only within -/// the bounds indicated by the associated lengths in the `msghdr`. -pub(crate) unsafe fn with_msghdr<R>( - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - f: impl FnOnce(&c::msghdr) -> R, -) -> R { - addr.with_sockaddr(|addr_ptr, addr_len| { - // Pass a reference to the `c::msghdr` instead of passing it by value - // because it may contain pointers to temporary objects that won't live - // beyond the call to `with_sockaddr`. - let mut msghdr = noaddr_msghdr(iov, control); - msghdr.msg_name = addr_ptr as _; - msghdr.msg_namelen = bitcast!(addr_len); - - f(&msghdr) - }) -} - -/// Create a zero-initialized message header struct value. -pub(crate) fn zero_msghdr() -> c::msghdr { - c::msghdr { - msg_name: null_mut(), - msg_namelen: 0, - msg_iov: null_mut(), - msg_iovlen: 0, - msg_control: null_mut(), - msg_controllen: 0, - msg_flags: 0, - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/netdevice.rs b/vendor/rustix/src/backend/linux_raw/net/netdevice.rs deleted file mode 100644 index d3c2a964..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/netdevice.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! Wrappers for netdevice ioctls. - -#![allow(unsafe_code)] - -use crate::backend::io::syscalls::ioctl; -use crate::fd::BorrowedFd; -use crate::io; -use core::ptr::addr_of_mut; -use core::{slice, str}; -use linux_raw_sys::ctypes::c_char; -use linux_raw_sys::ioctl::SIOCGIFINDEX; -#[cfg(feature = "alloc")] -use linux_raw_sys::ioctl::SIOCGIFNAME; -use linux_raw_sys::net::{ifreq, ifreq__bindgen_ty_1, ifreq__bindgen_ty_2, IFNAMSIZ}; -#[cfg(feature = "alloc")] -use {alloc::borrow::ToOwned, alloc::string::String}; - -pub(crate) fn name_to_index(fd: BorrowedFd<'_>, if_name: &str) -> io::Result<u32> { - let if_name_bytes = if_name.as_bytes(); - if if_name_bytes.len() >= IFNAMSIZ as usize { - return Err(io::Errno::NODEV); - } - if if_name_bytes.contains(&0) { - return Err(io::Errno::NODEV); - } - - // SAFETY: Convert `&[u8]` to `&[c_char]`. - let if_name_bytes = unsafe { - slice::from_raw_parts(if_name_bytes.as_ptr().cast::<c_char>(), if_name_bytes.len()) - }; - - let mut ifreq = ifreq { - ifr_ifrn: ifreq__bindgen_ty_1 { ifrn_name: [0; 16] }, - ifr_ifru: ifreq__bindgen_ty_2 { ifru_ivalue: 0 }, - }; - unsafe { ifreq.ifr_ifrn.ifrn_name[..if_name_bytes.len()].copy_from_slice(if_name_bytes) }; - - unsafe { ioctl(fd, SIOCGIFINDEX, addr_of_mut!(ifreq).cast()) }?; - let index = unsafe { ifreq.ifr_ifru.ifru_ivalue }; - Ok(index as u32) -} - -#[cfg(feature = "alloc")] -pub(crate) fn index_to_name(fd: BorrowedFd<'_>, index: u32) -> io::Result<String> { - let mut ifreq = ifreq { - ifr_ifrn: ifreq__bindgen_ty_1 { ifrn_name: [0; 16] }, - ifr_ifru: ifreq__bindgen_ty_2 { - ifru_ivalue: index as _, - }, - }; - - unsafe { ioctl(fd, SIOCGIFNAME, addr_of_mut!(ifreq).cast()) }?; - - if let Some(nul_byte) = unsafe { ifreq.ifr_ifrn.ifrn_name } - .iter() - .position(|ch| *ch == 0) - { - let ifrn_name = unsafe { &ifreq.ifr_ifrn.ifrn_name[..nul_byte] }; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let ifrn_name = - unsafe { slice::from_raw_parts(ifrn_name.as_ptr().cast::<u8>(), ifrn_name.len()) }; - - str::from_utf8(ifrn_name) - .map_err(|_| io::Errno::ILSEQ) - .map(ToOwned::to_owned) - } else { - Err(io::Errno::INVAL) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs deleted file mode 100644 index f18cd483..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! The BSD sockets API requires us to read the `sa_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::io::Errno; -use crate::net::addr::SocketAddrLen; -use crate::net::netlink::SocketAddrNetlink; -#[cfg(target_os = "linux")] -use crate::net::xdp::{SocketAddrXdp, SocketAddrXdpFlags}; -use crate::net::{ - AddressFamily, Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6, -}; -use core::mem::size_of; -use core::slice; - -// This must match the header of `sockaddr`. -#[repr(C)] -pub(crate) struct sockaddr_header { - sa_family: u16, -} - -/// Read the `sa_family` field from a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a least an initialized `sockaddr_header`. -#[inline] -pub(crate) const unsafe fn read_sa_family(storage: *const c::sockaddr) -> u16 { - // Assert that we know the layout of `sockaddr`. - let _ = c::sockaddr { - __storage: c::sockaddr_storage { - __bindgen_anon_1: linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1 { - __bindgen_anon_1: - linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { - ss_family: 0_u16, - __data: [0; 126_usize], - }, - }, - }, - }; - - (*storage.cast::<sockaddr_header>()).sa_family -} - -/// Set the `sa_family` field of a socket address to `AF_UNSPEC`, so that we -/// can test for `AF_UNSPEC` to test whether it was stored to. -/// -/// # Safety -/// -/// `storage` must point to a least an initialized `sockaddr_header`. -#[inline] -pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) { - (*storage.cast::<sockaddr_header>()).sa_family = c::AF_UNSPEC as _; -} - -/// Check if a socket address returned from the OS is considered non-empty. -#[inline] -pub(crate) unsafe fn sockaddr_nonempty(_storage: *const c::sockaddr, len: SocketAddrLen) -> bool { - len != 0 -} - -#[inline] -pub(crate) fn read_sockaddr_v4(addr: &SocketAddrAny) -> Result<SocketAddrV4, Errno> { - if addr.address_family() != AddressFamily::INET { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_in>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in>() }; - Ok(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), - u16::from_be(decode.sin_port), - )) -} - -#[inline] -pub(crate) fn read_sockaddr_v6(addr: &SocketAddrAny) -> Result<SocketAddrV6, Errno> { - if addr.address_family() != AddressFamily::INET6 { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_in6>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in6>() }; - Ok(SocketAddrV6::new( - Ipv6Addr::from(unsafe { decode.sin6_addr.in6_u.u6_addr8 }), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - decode.sin6_scope_id, - )) -} - -#[inline] -pub(crate) fn read_sockaddr_unix(addr: &SocketAddrAny) -> Result<SocketAddrUnix, Errno> { - if addr.address_family() != AddressFamily::UNIX { - return Err(Errno::AFNOSUPPORT); - } - let offsetof_sun_path = super::addr::offsetof_sun_path(); - let len = addr.addr_len() as usize; - - assert!(len >= offsetof_sun_path); - - if len == offsetof_sun_path { - SocketAddrUnix::new(&[][..]) - } else { - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_un>() }; - - // On Linux check for Linux's [abstract namespace]. - // - // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html - if decode.sun_path[0] == 0 { - let bytes = &decode.sun_path[1..len - offsetof_sun_path]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()) }; - - return SocketAddrUnix::new_abstract_name(bytes); - } - - // Otherwise we expect a NUL-terminated filesystem path. - let bytes = &decode.sun_path[..len - 1 - offsetof_sun_path]; - - // SAFETY: Convert `&[c_char]` to `&[u8]`. - let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()) }; - - assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); - SocketAddrUnix::new(bytes) - } -} - -#[inline] -pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result<SocketAddrXdp, Errno> { - if addr.address_family() != AddressFamily::XDP { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_xdp>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_xdp>() }; - - // This ignores the `sxdp_shared_umem_fd` field, which is only expected to - // be significant in `bind` calls, and not returned from `acceptfrom` or - // `recvmsg` or similar. - Ok(SocketAddrXdp::new( - SocketAddrXdpFlags::from_bits_retain(decode.sxdp_flags), - u32::from_be(decode.sxdp_ifindex), - u32::from_be(decode.sxdp_queue_id), - )) -} - -#[inline] -pub(crate) fn read_sockaddr_netlink(addr: &SocketAddrAny) -> Result<SocketAddrNetlink, Errno> { - if addr.address_family() != AddressFamily::NETLINK { - return Err(Errno::AFNOSUPPORT); - } - assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_nl>()); - let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_nl>() }; - Ok(SocketAddrNetlink::new(decode.nl_pid, decode.nl_groups)) -} diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs deleted file mode 100644 index 3262d01f..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs +++ /dev/null @@ -1,87 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -bitflags! { - /// `MSG_*` flags for use with [`send`], [`sendto`], and related - /// functions. - /// - /// [`send`]: crate::net::send - /// [`sendto`]: crate::net::sendto - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SendFlags: u32 { - /// `MSG_CONFIRM` - const CONFIRM = c::MSG_CONFIRM; - /// `MSG_DONTROUTE` - const DONTROUTE = c::MSG_DONTROUTE; - /// `MSG_DONTWAIT` - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_EOR` - const EOR = c::MSG_EOR; - /// `MSG_MORE` - const MORE = c::MSG_MORE; - /// `MSG_NOSIGNAL` - const NOSIGNAL = c::MSG_NOSIGNAL; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MSG_*` flags for use with [`recv`], [`recvfrom`], and related - /// functions. - /// - /// [`recv`]: crate::net::recv - /// [`recvfrom`]: crate::net::recvfrom - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RecvFlags: u32 { - /// `MSG_CMSG_CLOEXEC` - const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; - /// `MSG_DONTWAIT` - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_ERRQUEUE` - const ERRQUEUE = c::MSG_ERRQUEUE; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - /// `MSG_PEEK` - const PEEK = c::MSG_PEEK; - /// `MSG_TRUNC` - const TRUNC = c::MSG_TRUNC; - /// `MSG_WAITALL` - const WAITALL = c::MSG_WAITALL; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `MSG_*` flags returned from [`recvmsg`], in the `flags` field of - /// [`RecvMsg`] - /// - /// [`recvmsg`]: crate::net::recvmsg - /// [`RecvMsg`]: crate::net::RecvMsg - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReturnFlags: u32 { - /// `MSG_OOB` - const OOB = c::MSG_OOB; - /// `MSG_EOR` - const EOR = c::MSG_EOR; - /// `MSG_TRUNC` - const TRUNC = c::MSG_TRUNC; - /// `MSG_CTRUNC` - const CTRUNC = c::MSG_CTRUNC; - /// `MSG_ERRQUEUE` - const ERRQUEUE = c::MSG_ERRQUEUE; - /// `MSG_CMSG_CLOEXEC` - const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/sockopt.rs b/vendor/rustix/src/backend/linux_raw/net/sockopt.rs deleted file mode 100644 index 3e5ea1fd..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/sockopt.rs +++ /dev/null @@ -1,1099 +0,0 @@ -//! linux_raw syscalls supporting `rustix::net::sockopt`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -use crate::backend::conv::{by_mut, c_uint, ret, socklen_t}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -use crate::ffi::CStr; -use crate::io; -use crate::net::sockopt::Timeout; -#[cfg(target_os = "linux")] -use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpRingOffset, XdpStatistics, XdpUmemReg}; -use crate::net::{ - AddressFamily, Ipv4Addr, Ipv6Addr, Protocol, RawProtocol, SocketAddrBuf, SocketAddrV4, - SocketAddrV6, SocketType, UCred, -}; -#[cfg(feature = "alloc")] -use alloc::borrow::ToOwned as _; -#[cfg(feature = "alloc")] -use alloc::string::String; -use core::mem::{size_of, MaybeUninit}; -use core::time::Duration; -use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; -use linux_raw_sys::net::{IPV6_MTU, IPV6_MULTICAST_IF, IP_MTU, IP_MULTICAST_IF}; -#[cfg(target_os = "linux")] -use linux_raw_sys::xdp::{xdp_mmap_offsets, xdp_statistics, xdp_statistics_v1}; -#[cfg(target_arch = "x86")] -use { - crate::backend::conv::{slice_just_addr, x86_sys}, - crate::backend::reg::{ArgReg, SocketArg}, - linux_raw_sys::net::{SYS_GETSOCKOPT, SYS_SETSOCKOPT}, -}; - -#[inline] -fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result<T> { - let mut optlen: c::socklen_t = size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - - let mut value = MaybeUninit::<T>::uninit(); - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - - assert_eq!( - optlen as usize, - size_of::<T>(), - "unexpected getsockopt size" - ); - - unsafe { Ok(value.assume_init()) } -} - -#[inline] -fn getsockopt_raw<T>( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - value: &mut MaybeUninit<T>, - optlen: &mut c::socklen_t, -) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall!( - __NR_getsockopt, - fd, - c_uint(level), - c_uint(optname), - value, - by_mut(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKOPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - value.into(), - by_mut(optlen), - ]) - )) - } -} - -#[inline] -fn setsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32, value: T) -> io::Result<()> { - let optlen = size_of::<T>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - setsockopt_raw(fd, level, optname, &value, optlen) -} - -#[inline] -fn setsockopt_raw<T>( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - ptr: *const T, - optlen: c::socklen_t, -) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_setsockopt, - fd, - c_uint(level), - c_uint(optname), - ptr, - socklen_t(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SETSOCKOPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - ptr.into(), - socklen_t(optlen), - ]) - )) - } -} - -#[inline] -pub(crate) fn socket_type(fd: BorrowedFd<'_>) -> io::Result<SocketType> { - getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) -} - -#[inline] -pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) -} - -#[inline] -pub(crate) fn socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) -} - -#[inline] -pub(crate) fn socket_broadcast(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option<Duration>) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: c::c_int::from(linger.is_some()), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) -} - -#[inline] -pub(crate) fn socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) -} - -#[inline] -pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) -} - -#[inline] -pub(crate) fn socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, -) -> io::Result<()> { - let time = duration_to_linux_sock_timeval(timeout)?; - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_NEW, - Timeout::Send => c::SO_SNDTIMEO_NEW, - }; - match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { - set_socket_timeout_old(fd, id, timeout) - } - otherwise => otherwise, - } -} - -/// Same as `set_socket_timeout` but uses `__kernel_old_timeval` instead of -/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. -fn set_socket_timeout_old( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option<Duration>, -) -> io::Result<()> { - let time = duration_to_linux_old_timeval(timeout)?; - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_OLD, - Timeout::Send => c::SO_SNDTIMEO_OLD, - }; - setsockopt(fd, c::SOL_SOCKET, optname, time) -} - -#[inline] -pub(crate) fn socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_NEW, - Timeout::Send => c::SO_SNDTIMEO_NEW, - }; - let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { - return socket_timeout_old(fd, id) - } - otherwise => otherwise?, - }; - Ok(duration_from_linux_sock_timeval(time)) -} - -/// Same as `get_socket_timeout` but uses `__kernel_old_timeval` instead of -/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. -fn socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result<Option<Duration>> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO_OLD, - Timeout::Send => c::SO_SNDTIMEO_OLD, - }; - let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - Ok(duration_from_linux_old_timeval(time)) -} - -/// Convert a `__linux_sock_timeval` to a Rust `Option<Duration>`. -#[inline] -fn duration_from_linux_sock_timeval(time: __kernel_sock_timeval) -> Option<Duration> { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) - } -} - -/// Like `duration_from_linux_sock_timeval` but uses Linux's old 32-bit -/// `__kernel_old_timeval`. -fn duration_from_linux_old_timeval(time: __kernel_old_timeval) -> Option<Duration> { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) - } -} - -/// Convert a Rust `Option<Duration>` to a `__kernel_sock_timeval`. -#[inline] -fn duration_to_linux_sock_timeval(timeout: Option<Duration>) -> io::Result<__kernel_sock_timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = __kernel_sock_timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => __kernel_sock_timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) -} - -/// Like `duration_to_linux_sock_timeval` but uses Linux's old 32-bit -/// `__kernel_old_timeval`. -fn duration_to_linux_old_timeval(timeout: Option<Duration>) -> io::Result<__kernel_old_timeval> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = __kernel_old_timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => __kernel_old_timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) -} - -#[inline] -pub(crate) fn socket_error(fd: BorrowedFd<'_>) -> io::Result<Result<(), io::Errno>> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) -} - -#[inline] -pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) -} - -#[inline] -pub(crate) fn socket_keepalive(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) -} - -#[inline] -pub(crate) fn set_socket_recv_buffer_size_force(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUFFORCE, size) -} - -#[inline] -pub(crate) fn socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) -} - -#[inline] -pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) -} - -#[inline] -pub(crate) fn set_socket_send_buffer_size_force(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; - setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUFFORCE, size) -} - -#[inline] -pub(crate) fn socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) -} - -#[inline] -pub(crate) fn socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, - )) -} - -#[inline] -pub(crate) fn socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) -} - -#[inline] -pub(crate) fn socket_oobinline(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) -} - -#[inline] -pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) -} - -#[inline] -pub(crate) fn socket_reuseport(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) -} - -#[inline] -pub(crate) fn socket_protocol(fd: BorrowedFd<'_>) -> io::Result<Option<Protocol>> { - getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) - .map(|raw: u32| RawProtocol::new(raw).map(Protocol::from_raw)) -} - -#[inline] -pub(crate) fn socket_cookie(fd: BorrowedFd<'_>) -> io::Result<u64> { - getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) -} - -#[inline] -pub(crate) fn socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) -} - -#[inline] -pub(crate) fn set_socket_incoming_cpu(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU, value) -} - -#[inline] -pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) -} - -#[inline] -pub(crate) fn ip_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) -} - -#[inline] -pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) -} - -#[inline] -pub(crate) fn ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) -} - -#[inline] -pub(crate) fn ip_mtu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, IP_MTU) -} - -#[inline] -pub(crate) fn ipv6_mtu(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IPV6, IPV6_MTU) -} - -#[inline] -pub(crate) fn set_ip_multicast_if_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, IP_MULTICAST_IF, mreqn) -} - -#[inline] -pub(crate) fn set_ip_multicast_if(fd: BorrowedFd<'_>, value: &Ipv4Addr) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, IP_MULTICAST_IF, to_imr_addr(value)) -} - -#[inline] -pub(crate) fn ip_multicast_if(fd: BorrowedFd<'_>) -> io::Result<Ipv4Addr> { - getsockopt(fd, c::IPPROTO_IP, IP_MULTICAST_IF).map(from_in_addr) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_if(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, IPV6_MULTICAST_IF, value as c::c_int) -} - -#[inline] -pub(crate) fn ipv6_multicast_if(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IPV6, IPV6_MULTICAST_IF) -} - -#[inline] -pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) -} - -#[inline] -pub(crate) fn ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) -} - -#[inline] -pub(crate) fn ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) -} - -#[inline] -pub(crate) fn ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) -} - -#[inline] -pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - let mreq = to_ip_mreq(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn set_ip_add_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) -} - -#[inline] -pub(crate) fn set_ip_add_source_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) -} - -#[inline] -pub(crate) fn set_ip_drop_source_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) -} - -#[inline] -pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_ADD_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - let mreq = to_ip_mreq(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn set_ip_drop_membership_with_ifindex( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - let mreqn = to_ip_mreqn(multiaddr, address, ifindex as i32); - setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) -} - -#[inline] -pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_DROP_MEMBERSHIP, mreq) -} - -#[inline] -pub(crate) fn ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result<u8> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) -} - -#[inline] -pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops.into(), - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) -} - -#[inline] -pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) -} - -#[inline] -pub(crate) fn ip_tos(fd: BorrowedFd<'_>) -> io::Result<u8> { - let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; - Ok(value as u8) -} - -#[inline] -pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) -} - -#[inline] -pub(crate) fn ip_recvtos(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) -} - -#[inline] -pub(crate) fn ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) -} - -#[inline] -pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) -} - -#[inline] -pub(crate) fn ip_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) -} - -#[inline] -pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) -} - -#[inline] -pub(crate) fn ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) -} - -#[inline] -pub(crate) fn ip_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV4> { - let level = c::IPPROTO_IP; - let optname = c::SO_ORIGINAL_DST; - let mut addr = SocketAddrBuf::new(); - - getsockopt_raw(fd, level, optname, &mut addr.storage, &mut addr.len)?; - - Ok(unsafe { addr.into_any() }.try_into().unwrap()) -} - -#[inline] -pub(crate) fn ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result<SocketAddrV6> { - let level = c::IPPROTO_IPV6; - let optname = c::IP6T_SO_ORIGINAL_DST; - let mut addr = SocketAddrBuf::new(); - - getsockopt_raw(fd, level, optname, &mut addr.storage, &mut addr.len)?; - - Ok(unsafe { addr.into_any() }.try_into().unwrap()) -} - -#[inline] -pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) -} - -#[inline] -pub(crate) fn ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS) -} - -#[inline] -pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) -} - -#[inline] -pub(crate) fn tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) -} - -#[inline] -pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) -} - -#[inline] -pub(crate) fn tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) -} - -#[inline] -pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE, secs) -} - -#[inline] -pub(crate) fn tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs.into())) -} - -#[inline] -pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) -} - -#[inline] -pub(crate) fn tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result<Duration> { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs.into())) -} - -#[inline] -pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) -} - -#[inline] -pub(crate) fn tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) -} - -#[inline] -pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) -} - -#[inline] -pub(crate) fn tcp_quickack(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) -} - -#[inline] -pub(crate) fn set_tcp_congestion(fd: BorrowedFd<'_>, value: &str) -> io::Result<()> { - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - let optlen = value.len().try_into().unwrap(); - setsockopt_raw(fd, level, optname, value.as_ptr(), optlen) -} - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn tcp_congestion(fd: BorrowedFd<'_>) -> io::Result<String> { - const OPTLEN: c::socklen_t = 16; - - let level = c::IPPROTO_TCP; - let optname = c::TCP_CONGESTION; - let mut value = MaybeUninit::<[MaybeUninit<u8>; OPTLEN as usize]>::uninit(); - let mut optlen = OPTLEN; - getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; - unsafe { - let value = value.assume_init(); - let slice: &[u8] = core::mem::transmute(&value[..optlen as usize]); - assert!(slice.contains(&b'\0')); - Ok( - core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) - .unwrap() - .to_owned(), - ) - } -} - -#[inline] -pub(crate) fn set_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_TCP, - c::TCP_THIN_LINEAR_TIMEOUTS, - from_bool(value), - ) -} - -#[inline] -pub(crate) fn tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) -} - -#[inline] -pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) -} - -#[inline] -pub(crate) fn tcp_cork(fd: BorrowedFd<'_>) -> io::Result<bool> { - getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) -} - -#[inline] -pub(crate) fn socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> { - getsockopt(fd, c::SOL_SOCKET, linux_raw_sys::net::SO_PEERCRED) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_reg(fd: BorrowedFd<'_>, value: XdpUmemReg) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_REG, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_fill_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_FILL_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_umem_completion_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_UMEM_COMPLETION_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_tx_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_TX_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn set_xdp_rx_ring_size(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { - setsockopt(fd, c::SOL_XDP, c::XDP_RX_RING, value) -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_mmap_offsets(fd: BorrowedFd<'_>) -> io::Result<XdpMmapOffsets> { - // The kernel will write `xdp_mmap_offsets` or `xdp_mmap_offsets_v1` to the - // supplied pointer, depending on the kernel version. Both structs only - // contain u64 values. By using the larger of both as the parameter, we can - // shuffle the values to the non-v1 version returned by - // `get_xdp_mmap_offsets` while keeping the return type unaffected by the - // kernel version. This works because C will layout all struct members one - // after the other. - - let mut optlen = size_of::<xdp_mmap_offsets>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - let mut value = MaybeUninit::<xdp_mmap_offsets>::zeroed(); - getsockopt_raw(fd, c::SOL_XDP, c::XDP_MMAP_OFFSETS, &mut value, &mut optlen)?; - - if optlen as usize == size_of::<c::xdp_mmap_offsets_v1>() { - // SAFETY: All members of xdp_mmap_offsets are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xpd_mmap_offsets = unsafe { value.assume_init() }; - Ok(XdpMmapOffsets { - rx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.producer, - consumer: xpd_mmap_offsets.rx.consumer, - desc: xpd_mmap_offsets.rx.desc, - flags: None, - }, - tx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.flags, - consumer: xpd_mmap_offsets.tx.producer, - desc: xpd_mmap_offsets.tx.consumer, - flags: None, - }, - fr: XdpRingOffset { - producer: xpd_mmap_offsets.tx.desc, - consumer: xpd_mmap_offsets.tx.flags, - desc: xpd_mmap_offsets.fr.producer, - flags: None, - }, - cr: XdpRingOffset { - producer: xpd_mmap_offsets.fr.consumer, - consumer: xpd_mmap_offsets.fr.desc, - desc: xpd_mmap_offsets.fr.flags, - flags: None, - }, - }) - } else { - assert_eq!( - optlen as usize, - size_of::<xdp_mmap_offsets>(), - "unexpected getsockopt size" - ); - // SAFETY: All members of xdp_mmap_offsets are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xpd_mmap_offsets = unsafe { value.assume_init() }; - Ok(XdpMmapOffsets { - rx: XdpRingOffset { - producer: xpd_mmap_offsets.rx.producer, - consumer: xpd_mmap_offsets.rx.consumer, - desc: xpd_mmap_offsets.rx.desc, - flags: Some(xpd_mmap_offsets.rx.flags), - }, - tx: XdpRingOffset { - producer: xpd_mmap_offsets.tx.producer, - consumer: xpd_mmap_offsets.tx.consumer, - desc: xpd_mmap_offsets.tx.desc, - flags: Some(xpd_mmap_offsets.tx.flags), - }, - fr: XdpRingOffset { - producer: xpd_mmap_offsets.fr.producer, - consumer: xpd_mmap_offsets.fr.consumer, - desc: xpd_mmap_offsets.fr.desc, - flags: Some(xpd_mmap_offsets.fr.flags), - }, - cr: XdpRingOffset { - producer: xpd_mmap_offsets.cr.producer, - consumer: xpd_mmap_offsets.cr.consumer, - desc: xpd_mmap_offsets.cr.desc, - flags: Some(xpd_mmap_offsets.cr.flags), - }, - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_statistics(fd: BorrowedFd<'_>) -> io::Result<XdpStatistics> { - let mut optlen = size_of::<xdp_statistics>().try_into().unwrap(); - debug_assert!( - optlen as usize >= size_of::<c::c_int>(), - "Socket APIs don't ever use `bool` directly" - ); - let mut value = MaybeUninit::<xdp_statistics>::zeroed(); - getsockopt_raw(fd, c::SOL_XDP, c::XDP_STATISTICS, &mut value, &mut optlen)?; - - if optlen as usize == size_of::<xdp_statistics_v1>() { - // SAFETY: All members of xdp_statistics are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xdp_statistics = unsafe { value.assume_init() }; - Ok(XdpStatistics { - rx_dropped: xdp_statistics.rx_dropped, - rx_invalid_descs: xdp_statistics.rx_dropped, - tx_invalid_descs: xdp_statistics.rx_dropped, - rx_ring_full: None, - rx_fill_ring_empty_descs: None, - tx_ring_empty_descs: None, - }) - } else { - assert_eq!( - optlen as usize, - size_of::<xdp_statistics>(), - "unexpected getsockopt size" - ); - // SAFETY: All members of xdp_statistics are `u64` and thus are - // correctly initialized by `MaybeUninit::<xdp_statistics>::zeroed()`. - let xdp_statistics = unsafe { value.assume_init() }; - Ok(XdpStatistics { - rx_dropped: xdp_statistics.rx_dropped, - rx_invalid_descs: xdp_statistics.rx_invalid_descs, - tx_invalid_descs: xdp_statistics.tx_invalid_descs, - rx_ring_full: Some(xdp_statistics.rx_ring_full), - rx_fill_ring_empty_descs: Some(xdp_statistics.rx_fill_ring_empty_descs), - tx_ring_empty_descs: Some(xdp_statistics.tx_ring_empty_descs), - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn xdp_options(fd: BorrowedFd<'_>) -> io::Result<XdpOptionsFlags> { - getsockopt(fd, c::SOL_XDP, c::XDP_OPTIONS) -} - -#[inline] -fn from_in_addr(in_addr: c::in_addr) -> Ipv4Addr { - Ipv4Addr::from(in_addr.s_addr.to_ne_bytes()) -} - -#[inline] -fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } -} - -#[inline] -fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { - c::ip_mreqn { - imr_multiaddr: to_imr_addr(multiaddr), - imr_address: to_imr_addr(address), - imr_ifindex: ifindex, - } -} - -#[inline] -fn to_imr_source( - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> c::ip_mreq_source { - c::ip_mreq_source { - imr_multiaddr: to_imr_addr(multiaddr).s_addr, - imr_interface: to_imr_addr(interface).s_addr, - imr_sourceaddr: to_imr_addr(sourceaddr).s_addr, - } -} - -#[inline] -fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - c::in_addr { - s_addr: u32::from_ne_bytes(addr.octets()), - } -} - -#[inline] -fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_ifindex: to_ipv6mr_interface(interface), - } -} - -#[inline] -fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: multiaddr.octets(), - }, - } -} - -#[inline] -fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int -} - -#[inline] -fn from_bool(value: bool) -> c::c_uint { - c::c_uint::from(value) -} - -#[inline] -fn to_bool(value: c::c_uint) -> bool { - value != 0 -} - -/// Convert to seconds, rounding up if necessary. -#[inline] -fn duration_to_secs<T: TryFrom<u64>>(duration: Duration) -> io::Result<T> { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) -} diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs deleted file mode 100644 index 488e08f0..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs +++ /dev/null @@ -1,731 +0,0 @@ -//! linux_raw syscalls supporting `rustix::net`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use super::msghdr::{noaddr_msghdr, with_msghdr, with_recv_msghdr}; -use super::read_sockaddr::initialize_family_to_unspec; -use super::send_recv::{RecvFlags, ReturnFlags, SendFlags}; -use crate::backend::c; -#[cfg(target_os = "linux")] -use crate::backend::conv::slice_mut; -use crate::backend::conv::{ - by_mut, by_ref, c_int, c_uint, pass_usize, ret, ret_owned_fd, ret_usize, size_of, slice, - socklen_t, zero, -}; -use crate::backend::reg::raw_arg; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::addr::SocketAddrArg; -#[cfg(target_os = "linux")] -use crate::net::MMsgHdr; -use crate::net::{ - AddressFamily, Protocol, RecvAncillaryBuffer, RecvMsg, SendAncillaryBuffer, Shutdown, - SocketAddrAny, SocketAddrBuf, SocketFlags, SocketType, -}; -use core::mem::MaybeUninit; -#[cfg(target_arch = "x86")] -use { - crate::backend::conv::{slice_just_addr, x86_sys}, - crate::backend::reg::{ArgReg, SocketArg}, - linux_raw_sys::net::{ - SYS_ACCEPT, SYS_ACCEPT4, SYS_BIND, SYS_CONNECT, SYS_GETPEERNAME, SYS_GETSOCKNAME, - SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMMSG, SYS_SENDMSG, - SYS_SENDTO, SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, - }, -}; - -#[inline] -pub(crate) fn socket( - family: AddressFamily, - type_: SocketType, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_socket, family, type_, protocol)) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SOCKET), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - family.into(), - type_.into(), - protocol.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn socket_with( - family: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socket, - family, - (type_, flags), - protocol - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SOCKET), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - family.into(), - (type_, flags).into(), - protocol.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn socketpair( - family: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<(OwnedFd, OwnedFd)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!( - __NR_socketpair, - family, - (type_, flags), - protocol, - &mut result - ))?; - let [fd0, fd1] = result.assume_init(); - Ok((fd0, fd1)) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_SOCKETPAIR), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - family.into(), - (type_, flags).into(), - protocol.into(), - (&mut result).into(), - ]) - ))?; - let [fd0, fd1] = result.assume_init(); - Ok((fd0, fd1)) - } -} - -#[inline] -pub(crate) fn accept(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> { - #[cfg(not(any(target_arch = "x86", target_arch = "s390x")))] - unsafe { - let fd = ret_owned_fd(syscall_readonly!(__NR_accept, fd, zero(), zero()))?; - Ok(fd) - } - #[cfg(target_arch = "x86")] - unsafe { - let fd = ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_ACCEPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), zero(), zero()]) - ))?; - Ok(fd) - } - #[cfg(target_arch = "s390x")] - { - // accept is not available on s390x - accept_with(fd, SocketFlags::empty()) - } -} - -#[inline] -pub(crate) fn accept_with(fd: BorrowedFd<'_>, flags: SocketFlags) -> io::Result<OwnedFd> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let fd = ret_owned_fd(syscall_readonly!(__NR_accept4, fd, zero(), zero(), flags))?; - Ok(fd) - } - #[cfg(target_arch = "x86")] - unsafe { - let fd = ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_ACCEPT4), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), zero(), zero(), flags.into()]) - ))?; - Ok(fd) - } -} - -#[inline] -pub(crate) fn acceptfrom(fd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - #[cfg(not(any(target_arch = "x86", target_arch = "s390x")))] - unsafe { - let mut addr = SocketAddrBuf::new(); - let fd = ret_owned_fd(syscall!( - __NR_accept, - fd, - &mut addr.storage, - by_mut(&mut addr.len) - ))?; - Ok((fd, addr.into_any_option())) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addr = SocketAddrBuf::new(); - let fd = ret_owned_fd(syscall!( - __NR_socketcall, - x86_sys(SYS_ACCEPT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut addr.storage).into(), - by_mut(&mut addr.len), - ]) - ))?; - Ok((fd, addr.into_any_option())) - } - #[cfg(target_arch = "s390x")] - { - // accept is not available on s390x - acceptfrom_with(fd, SocketFlags::empty()) - } -} - -#[inline] -pub(crate) fn acceptfrom_with( - fd: BorrowedFd<'_>, - flags: SocketFlags, -) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addr = SocketAddrBuf::new(); - let fd = ret_owned_fd(syscall!( - __NR_accept4, - fd, - &mut addr.storage, - by_mut(&mut addr.len), - flags - ))?; - Ok((fd, addr.into_any_option())) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addr = SocketAddrBuf::new(); - let fd = ret_owned_fd(syscall!( - __NR_socketcall, - x86_sys(SYS_ACCEPT4), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut addr.storage).into(), - by_mut(&mut addr.len), - flags.into(), - ]) - ))?; - Ok((fd, addr.into_any_option())) - } -} - -#[inline] -pub(crate) fn recvmsg( - sockfd: BorrowedFd<'_>, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - msg_flags: RecvFlags, -) -> io::Result<RecvMsg> { - let mut addr = SocketAddrBuf::new(); - - // SAFETY: This passes the `msghdr` reference to the OS which reads the - // buffers only within the designated bounds. - let (bytes, flags) = unsafe { - with_recv_msghdr(&mut addr, iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = ret_usize(syscall!(__NR_recvmsg, sockfd, by_mut(msghdr), msg_flags)); - - #[cfg(target_arch = "x86")] - let result = ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECVMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_mut(msghdr), - msg_flags.into(), - ]) - )); - - result.map(|bytes| (bytes, msghdr.msg_flags)) - })? - }; - - // Get the address of the sender, if any. - Ok(RecvMsg { - bytes, - address: unsafe { addr.into_any_option() }, - flags: ReturnFlags::from_bits_retain(flags), - }) -} - -#[inline] -pub(crate) fn sendmsg( - sockfd: BorrowedFd<'_>, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - let msghdr = noaddr_msghdr(iov, control); - - #[cfg(not(target_arch = "x86"))] - let result = unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_ref(&msghdr), - msg_flags.into() - ]) - )) - }; - - result -} - -#[inline] -pub(crate) fn sendmsg_addr( - sockfd: BorrowedFd<'_>, - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - msg_flags: SendFlags, -) -> io::Result<usize> { - // SAFETY: This passes the `msghdr` reference to the OS which reads the - // buffers only within the designated bounds. - unsafe { - with_msghdr(addr, iov, control, |msghdr| { - #[cfg(not(target_arch = "x86"))] - let result = ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(msghdr), msg_flags)); - - #[cfg(target_arch = "x86")] - let result = ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - sockfd.into(), - by_ref(msghdr), - msg_flags.into(), - ]) - )); - - result - }) - } -} - -#[cfg(target_os = "linux")] -#[inline] -pub(crate) fn sendmmsg( - sockfd: BorrowedFd<'_>, - msgs: &mut [MMsgHdr<'_>], - flags: SendFlags, -) -> io::Result<usize> { - let (msgs, len) = slice_mut(msgs); - - #[cfg(not(target_arch = "x86"))] - let result = unsafe { ret_usize(syscall!(__NR_sendmmsg, sockfd, msgs, len, flags)) }; - - #[cfg(target_arch = "x86")] - let result = unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_SENDMMSG), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[sockfd.into(), msgs, len, flags.into()]) - )) - }; - - result -} - -#[inline] -pub(crate) fn shutdown(fd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_shutdown, - fd, - c_uint(how as c::c_uint) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SHUTDOWN), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), c_uint(how as c::c_uint)]) - )) - } -} - -#[inline] -pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result<usize> { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86", - target_arch = "x86_64", - )))] - unsafe { - ret_usize(syscall_readonly!(__NR_send, fd, buf_addr, buf_len, flags)) - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86_64", - ))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - zero(), - zero() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SEND), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into() - ]) - )) - } -} - -#[inline] -pub(crate) fn sendto( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &impl SocketAddrArg, -) -> io::Result<usize> { - let (buf_addr, buf_len) = slice(buf); - - // SAFETY: This passes the `addr_ptr` reference to the OS which reads the - // buffers only within the `addr_len` bound. - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - #[cfg(not(target_arch = "x86"))] - { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - raw_arg(addr_ptr as *mut _), - socklen_t(addr_len) - )) - } - #[cfg(target_arch = "x86")] - { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - raw_arg(addr_ptr as *mut _), - socklen_t(addr_len) - ]) - )) - } - }) - } -} - -#[inline] -pub(crate) unsafe fn recv( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - flags: RecvFlags, -) -> io::Result<usize> { - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86", - target_arch = "x86_64", - )))] - { - ret_usize(syscall!(__NR_recv, fd, buf.0, pass_usize(buf.1), flags)) - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86_64", - ))] - { - ret_usize(syscall!( - __NR_recvfrom, - fd, - buf.0, - pass_usize(buf.1), - flags, - zero(), - zero() - )) - } - #[cfg(target_arch = "x86")] - { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECV), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf.0.into(), - pass_usize(buf.1), - flags.into(), - ]) - )) - } -} - -#[inline] -pub(crate) unsafe fn recvfrom( - fd: BorrowedFd<'_>, - buf: (*mut u8, usize), - flags: RecvFlags, -) -> io::Result<(usize, Option<SocketAddrAny>)> { - let mut addr = SocketAddrBuf::new(); - - // `recvfrom` does not write to the storage if the socket is - // connection-oriented sockets, so we initialize the family field to - // `AF_UNSPEC` so that we can detect this case. - initialize_family_to_unspec(addr.storage.as_mut_ptr().cast::<c::sockaddr>()); - - #[cfg(not(target_arch = "x86"))] - let nread = ret_usize(syscall!( - __NR_recvfrom, - fd, - buf.0, - pass_usize(buf.1), - flags, - &mut addr.storage, - by_mut(&mut addr.len) - ))?; - #[cfg(target_arch = "x86")] - let nread = ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECVFROM), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - buf.0.into(), - pass_usize(buf.1), - flags.into(), - (&mut addr.storage).into(), - by_mut(&mut addr.len), - ]) - ))?; - - Ok((nread, addr.into_any_option())) -} - -#[inline] -pub(crate) fn getpeername(fd: BorrowedFd<'_>) -> io::Result<Option<SocketAddrAny>> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(syscall!( - __NR_getpeername, - fd, - &mut addr.storage, - by_mut(&mut addr.len) - ))?; - Ok(addr.into_any_option()) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETPEERNAME), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut addr.storage).into(), - by_mut(&mut addr.len), - ]) - ))?; - Ok(addr.into_any_option()) - } -} - -#[inline] -pub(crate) fn getsockname(fd: BorrowedFd<'_>) -> io::Result<SocketAddrAny> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(syscall!( - __NR_getsockname, - fd, - &mut addr.storage, - by_mut(&mut addr.len) - ))?; - Ok(addr.into_any()) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addr = SocketAddrBuf::new(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKNAME), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - (&mut addr.storage).into(), - by_mut(&mut addr.len), - ]) - ))?; - Ok(addr.into_any()) - } -} - -#[inline] -pub(crate) fn bind(fd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> { - // SAFETY: This passes the `addr_ptr` reference to the OS which reads the - // buffers only within the `addr_len` bound. - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - #[cfg(not(target_arch = "x86"))] - { - ret(syscall_readonly!( - __NR_bind, - fd, - raw_arg(addr_ptr as *mut _), - socklen_t(addr_len) - )) - } - #[cfg(target_arch = "x86")] - { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - raw_arg(addr_ptr as *mut _), - socklen_t(addr_len) - ]) - )) - } - }) - } -} - -#[inline] -pub(crate) fn connect(fd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> { - // SAFETY: This passes the `addr_ptr` reference to the OS which reads the - // buffers only within the `addr_len` bound. - unsafe { - addr.with_sockaddr(|addr_ptr, addr_len| { - #[cfg(not(target_arch = "x86"))] - { - ret(syscall_readonly!( - __NR_connect, - fd, - raw_arg(addr_ptr as *mut _), - socklen_t(addr_len) - )) - } - #[cfg(target_arch = "x86")] - { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - raw_arg(addr_ptr as *mut _), - socklen_t(addr_len) - ]) - )) - } - }) - } -} - -#[inline] -pub(crate) fn connect_unspec(fd: BorrowedFd<'_>) -> io::Result<()> { - debug_assert_eq!(c::AF_UNSPEC, 0); - let addr = MaybeUninit::<c::sockaddr_storage>::zeroed(); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&addr), - size_of::<c::sockaddr_storage, _>() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[ - fd.into(), - by_ref(&addr), - size_of::<c::sockaddr_storage, _>(), - ]) - )) - } -} - -#[inline] -pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_LISTEN), - slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[fd.into(), c_int(backlog)]) - )) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs deleted file mode 100644 index 3b348221..00000000 --- a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! The BSD sockets API requires us to read the `sa_family` field before we can -//! interpret the rest of a `sockaddr` produced by the kernel. -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::net::{SocketAddrV4, SocketAddrV6}; - -pub(crate) fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { - c::sockaddr_in { - sin_family: c::AF_INET as _, - sin_port: u16::to_be(v4.port()), - sin_addr: c::in_addr { - s_addr: u32::from_ne_bytes(v4.ip().octets()), - }, - __pad: [0_u8; 8], - } -} - -pub(crate) fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { - c::sockaddr_in6 { - sin6_family: c::AF_INET6 as _, - sin6_port: u16::to_be(v6.port()), - sin6_flowinfo: u32::to_be(v6.flowinfo()), - sin6_addr: c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: v6.ip().octets(), - }, - }, - sin6_scope_id: v6.scope_id(), - } -} diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs deleted file mode 100644 index d748219a..00000000 --- a/vendor/rustix/src/backend/linux_raw/param/auxv.rs +++ /dev/null @@ -1,583 +0,0 @@ -//! Linux auxv support. -//! -//! # Safety -//! -//! This uses raw pointers to locate and read the kernel-provided auxv array. -#![allow(unsafe_code)] - -use super::super::conv::{c_int, pass_usize, ret_usize}; -use crate::backend::c; -use crate::fd::OwnedFd; -#[cfg(feature = "param")] -use crate::ffi::CStr; -use crate::fs::{Mode, OFlags}; -use crate::utils::{as_ptr, check_raw_pointer}; -#[cfg(feature = "alloc")] -use alloc::vec::Vec; -use core::mem::size_of; -use core::ptr::{null_mut, read_unaligned, NonNull}; -#[cfg(feature = "runtime")] -use core::sync::atomic::AtomicU8; -use core::sync::atomic::Ordering::Relaxed; -use core::sync::atomic::{AtomicPtr, AtomicUsize}; -use linux_raw_sys::elf::*; -use linux_raw_sys::general::{ - AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_MINSIGSTKSZ, AT_NULL, AT_PAGESZ, - AT_SYSINFO_EHDR, -}; -#[cfg(feature = "runtime")] -use linux_raw_sys::general::{ - AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE, AT_UID, -}; -#[cfg(feature = "alloc")] -use {alloc::borrow::Cow, alloc::vec}; - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn page_size() -> usize { - let mut page_size = PAGE_SIZE.load(Relaxed); - - if page_size == 0 { - init_auxv(); - page_size = PAGE_SIZE.load(Relaxed); - } - - page_size -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn clock_ticks_per_second() -> u64 { - let mut ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed); - - if ticks == 0 { - init_auxv(); - ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed); - } - - ticks as u64 -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_hwcap() -> (usize, usize) { - let mut hwcap = HWCAP.load(Relaxed); - let mut hwcap2 = HWCAP2.load(Relaxed); - - if hwcap == 0 || hwcap2 == 0 { - init_auxv(); - hwcap = HWCAP.load(Relaxed); - hwcap2 = HWCAP2.load(Relaxed); - } - - (hwcap, hwcap2) -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_minsigstksz() -> usize { - let mut minsigstksz = MINSIGSTKSZ.load(Relaxed); - - if minsigstksz == 0 { - init_auxv(); - minsigstksz = MINSIGSTKSZ.load(Relaxed); - } - - minsigstksz -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_execfn() -> &'static CStr { - let mut execfn = EXECFN.load(Relaxed); - - if execfn.is_null() { - init_auxv(); - execfn = EXECFN.load(Relaxed); - } - - // SAFETY: We assume the `AT_EXECFN` value provided by the kernel is a - // valid pointer to a valid NUL-terminated array of bytes. - unsafe { CStr::from_ptr(execfn.cast()) } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn linux_secure() -> bool { - let mut secure = SECURE.load(Relaxed); - - // 0 means not initialized yet. - if secure == 0 { - init_auxv(); - secure = SECURE.load(Relaxed); - } - - // 0 means not present. Libc `getauxval(AT_SECURE)` would return 0. - // 1 means not in secure mode. - // 2 means in secure mode. - secure > 1 -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { - let mut phdr = PHDR.load(Relaxed); - let mut phent = PHENT.load(Relaxed); - let mut phnum = PHNUM.load(Relaxed); - - if phdr.is_null() || phnum == 0 { - init_auxv(); - phdr = PHDR.load(Relaxed); - phent = PHENT.load(Relaxed); - phnum = PHNUM.load(Relaxed); - } - - (phdr.cast(), phent, phnum) -} - -/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, so -/// if we don't see it, this function returns a null pointer. -/// -/// And, this function returns a null pointer, rather than panicking, if the -/// auxv records can't be read. -#[inline] -pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { - let mut ehdr = SYSINFO_EHDR.load(Relaxed); - - if ehdr.is_null() { - // Use `maybe_init_auxv` to read the aux vectors if it can, but do - // nothing if it can't. If it can't, then we'll get a null pointer - // here, which our callers are prepared to deal with. - maybe_init_auxv(); - - ehdr = SYSINFO_EHDR.load(Relaxed); - } - - ehdr -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn entry() -> usize { - let mut entry = ENTRY.load(Relaxed); - - if entry == 0 { - init_auxv(); - entry = ENTRY.load(Relaxed); - } - - entry -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn random() -> *const [u8; 16] { - let mut random = RANDOM.load(Relaxed); - - if random.is_null() { - init_auxv(); - random = RANDOM.load(Relaxed); - } - - random -} - -static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0); -static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0); -static HWCAP: AtomicUsize = AtomicUsize::new(0); -static HWCAP2: AtomicUsize = AtomicUsize::new(0); -static MINSIGSTKSZ: AtomicUsize = AtomicUsize::new(0); -static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(null_mut()); -static SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut()); -#[cfg(feature = "runtime")] -static SECURE: AtomicU8 = AtomicU8::new(0); -#[cfg(feature = "runtime")] -static PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(null_mut()); -#[cfg(feature = "runtime")] -static PHENT: AtomicUsize = AtomicUsize::new(0); -#[cfg(feature = "runtime")] -static PHNUM: AtomicUsize = AtomicUsize::new(0); -#[cfg(feature = "runtime")] -static ENTRY: AtomicUsize = AtomicUsize::new(0); -#[cfg(feature = "runtime")] -static RANDOM: AtomicPtr<[u8; 16]> = AtomicPtr::new(null_mut()); - -const PR_GET_AUXV: c::c_int = 0x4155_5856; - -/// Use Linux ≥ 6.4's [`PR_GET_AUXV`] to read the aux records, into a provided -/// statically-sized buffer. Return: -/// - `Ok(…)` if the buffer is big enough. -/// - `Err(Ok(len))` if we need a buffer of length `len`. -/// - `Err(Err(err))` if we failed with `err`. -/// -/// [`PR_GET_AUXV`]: https://www.man7.org/linux/man-pages/man2/PR_GET_AUXV.2const.html -#[cold] -fn pr_get_auxv_static(buffer: &mut [u8; 512]) -> Result<&mut [u8], crate::io::Result<usize>> { - let len = unsafe { - ret_usize(syscall_always_asm!( - __NR_prctl, - c_int(PR_GET_AUXV), - buffer.as_mut_ptr(), - pass_usize(buffer.len()), - pass_usize(0), - pass_usize(0) - )) - .map_err(Err)? - }; - if len <= buffer.len() { - return Ok(&mut buffer[..len]); - } - Err(Ok(len)) -} - -/// Use Linux ≥ 6.4's [`PR_GET_AUXV`] to read the aux records, using a -/// provided statically-sized buffer if possible, or a dynamically allocated -/// buffer otherwise. Return: -/// - Ok(…) on success. -/// - Err(err) on failure. -/// -/// [`PR_GET_AUXV`]: https://www.man7.org/linux/man-pages/man2/PR_GET_AUXV.2const.html -#[cfg(feature = "alloc")] -#[cold] -fn pr_get_auxv_dynamic(buffer: &mut [u8; 512]) -> crate::io::Result<Cow<'_, [u8]>> { - // First try use the static buffer. - let len = match pr_get_auxv_static(buffer) { - Ok(buffer) => return Ok(Cow::Borrowed(buffer)), - Err(Ok(len)) => len, - Err(Err(err)) => return Err(err), - }; - - // If that indicates it needs a bigger buffer, allocate one. - let mut buffer = vec![0_u8; len]; - let len = unsafe { - ret_usize(syscall_always_asm!( - __NR_prctl, - c_int(PR_GET_AUXV), - buffer.as_mut_ptr(), - pass_usize(buffer.len()), - pass_usize(0), - pass_usize(0) - ))? - }; - assert_eq!(len, buffer.len()); - Ok(Cow::Owned(buffer)) -} - -/// Read the auxv records and initialize the various static variables. Panic -/// if an error is encountered. -#[cold] -fn init_auxv() { - init_auxv_impl().unwrap(); -} - -/// Like `init_auxv`, but don't panic if an error is encountered. The caller -/// must be prepared for initialization to be skipped. -#[cold] -fn maybe_init_auxv() { - let _ = init_auxv_impl(); -} - -/// If we don't have "use-explicitly-provided-auxv" or "use-libc-auxv", we -/// read the aux vector via the `prctl` `PR_GET_AUXV`, with a fallback to -/// /proc/self/auxv for kernels that don't support `PR_GET_AUXV`. -#[cold] -fn init_auxv_impl() -> Result<(), ()> { - // 512 bytes of AUX elements ought to be enough for anybody… - let mut buffer = [0_u8; 512]; - - // If we don't have "alloc", just try to read into our statically-sized - // buffer. This might fail due to the buffer being insufficient; we're - // prepared to cope, though we may do suboptimal things. - #[cfg(not(feature = "alloc"))] - let result = pr_get_auxv_static(&mut buffer); - - // If we do have "alloc" then read into our statically-sized buffer if - // it fits, or fall back to a dynamically-allocated buffer. - #[cfg(feature = "alloc")] - let result = pr_get_auxv_dynamic(&mut buffer); - - if let Ok(buffer) = result { - // SAFETY: We assume the kernel returns a valid auxv. - unsafe { - init_from_aux_iter(AuxPointer(buffer.as_ptr().cast())).unwrap(); - } - return Ok(()); - } - - // If `PR_GET_AUXV` is unavailable, or if we don't have "alloc" and - // the aux records don't fit in our static buffer, then fall back to trying - // to open "/proc/self/auxv". We don't use `proc_self_fd` because its extra - // checking breaks on QEMU. - if let Ok(file) = crate::fs::open("/proc/self/auxv", OFlags::RDONLY, Mode::empty()) { - #[cfg(feature = "alloc")] - init_from_auxv_file(file).unwrap(); - - #[cfg(not(feature = "alloc"))] - unsafe { - init_from_aux_iter(AuxFile(file)).unwrap(); - } - - return Ok(()); - } - - Err(()) -} - -/// Process auxv entries from the open file `auxv`. -#[cfg(feature = "alloc")] -#[cold] -#[must_use] -fn init_from_auxv_file(auxv: OwnedFd) -> Option<()> { - let mut buffer = Vec::<u8>::with_capacity(512); - loop { - let cur = buffer.len(); - - // Request one extra byte; `Vec` will often allocate more. - buffer.reserve(1); - - // Use all the space it allocated. - buffer.resize(buffer.capacity(), 0); - - // Read up to that many bytes. - let n = match crate::io::read(&auxv, &mut buffer[cur..]) { - Err(crate::io::Errno::INTR) => 0, - Err(_err) => panic!(), - Ok(0) => break, - Ok(n) => n, - }; - - // Account for the number of bytes actually read. - buffer.resize(cur + n, 0_u8); - } - - // SAFETY: We loaded from an auxv file into the buffer. - unsafe { init_from_aux_iter(AuxPointer(buffer.as_ptr().cast())) } -} - -/// Process auxv entries from the auxv array pointed to by `auxp`. -/// -/// # Safety -/// -/// This must be passed a pointer to an auxv array. -/// -/// The buffer contains `Elf_aux_t` elements, though it need not be aligned; -/// function uses `read_unaligned` to read from it. -#[cold] -#[must_use] -unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Option<()> { - let mut pagesz = 0; - let mut clktck = 0; - let mut hwcap = 0; - let mut hwcap2 = 0; - let mut minsigstksz = 0; - let mut execfn = null_mut(); - let mut sysinfo_ehdr = null_mut(); - #[cfg(feature = "runtime")] - let mut secure = 0; - #[cfg(feature = "runtime")] - let mut phdr = null_mut(); - #[cfg(feature = "runtime")] - let mut phnum = 0; - #[cfg(feature = "runtime")] - let mut phent = 0; - #[cfg(feature = "runtime")] - let mut entry = 0; - #[cfg(feature = "runtime")] - let mut uid = None; - #[cfg(feature = "runtime")] - let mut euid = None; - #[cfg(feature = "runtime")] - let mut gid = None; - #[cfg(feature = "runtime")] - let mut egid = None; - #[cfg(feature = "runtime")] - let mut random = null_mut(); - - for Elf_auxv_t { a_type, a_val } in aux_iter { - match a_type as _ { - AT_PAGESZ => pagesz = a_val as usize, - AT_CLKTCK => clktck = a_val as usize, - AT_HWCAP => hwcap = a_val as usize, - AT_HWCAP2 => hwcap2 = a_val as usize, - AT_MINSIGSTKSZ => minsigstksz = a_val as usize, - AT_EXECFN => execfn = check_raw_pointer::<c::c_char>(a_val as *mut _)?.as_ptr(), - AT_SYSINFO_EHDR => sysinfo_ehdr = check_elf_base(a_val as *mut _)?.as_ptr(), - - AT_BASE => { - // The `AT_BASE` value can be null in a static executable that - // doesn't use a dynamic linker. If so, ignore it. - if !a_val.is_null() { - let _ = check_elf_base(a_val.cast())?; - } - } - - #[cfg(feature = "runtime")] - AT_SECURE => secure = (a_val as usize != 0) as u8 + 1, - #[cfg(feature = "runtime")] - AT_UID => uid = Some(a_val), - #[cfg(feature = "runtime")] - AT_EUID => euid = Some(a_val), - #[cfg(feature = "runtime")] - AT_GID => gid = Some(a_val), - #[cfg(feature = "runtime")] - AT_EGID => egid = Some(a_val), - #[cfg(feature = "runtime")] - AT_PHDR => phdr = check_raw_pointer::<Elf_Phdr>(a_val as *mut _)?.as_ptr(), - #[cfg(feature = "runtime")] - AT_PHNUM => phnum = a_val as usize, - #[cfg(feature = "runtime")] - AT_PHENT => phent = a_val as usize, - #[cfg(feature = "runtime")] - AT_ENTRY => entry = a_val as usize, - #[cfg(feature = "runtime")] - AT_RANDOM => random = check_raw_pointer::<[u8; 16]>(a_val as *mut _)?.as_ptr(), - - AT_NULL => break, - _ => (), - } - } - - #[cfg(feature = "runtime")] - assert_eq!(phent, size_of::<Elf_Phdr>()); - - // If we're running set-uid or set-gid, enable “secure execution” mode, - // which doesn't do much, but users may be depending on the things that - // it does do. - #[cfg(feature = "runtime")] - if uid != euid || gid != egid { - secure = 2; - } - - // The base and sysinfo_ehdr (if present) matches our platform. Accept the - // aux values. - PAGE_SIZE.store(pagesz, Relaxed); - CLOCK_TICKS_PER_SECOND.store(clktck, Relaxed); - HWCAP.store(hwcap, Relaxed); - HWCAP2.store(hwcap2, Relaxed); - MINSIGSTKSZ.store(minsigstksz, Relaxed); - EXECFN.store(execfn, Relaxed); - SYSINFO_EHDR.store(sysinfo_ehdr, Relaxed); - #[cfg(feature = "runtime")] - SECURE.store(secure, Relaxed); - #[cfg(feature = "runtime")] - PHDR.store(phdr, Relaxed); - #[cfg(feature = "runtime")] - PHNUM.store(phnum, Relaxed); - #[cfg(feature = "runtime")] - ENTRY.store(entry, Relaxed); - #[cfg(feature = "runtime")] - RANDOM.store(random, Relaxed); - - Some(()) -} - -/// Check that `base` is a valid pointer to the kernel-provided vDSO. -/// -/// `base` is some value we got from a `AT_SYSINFO_EHDR` aux record somewhere, -/// which hopefully holds the value of the kernel-provided vDSO in memory. Do a -/// series of checks to be as sure as we can that it's safe to use. -#[cold] -#[must_use] -unsafe fn check_elf_base(base: *const Elf_Ehdr) -> Option<NonNull<Elf_Ehdr>> { - // If we're reading a 64-bit auxv on a 32-bit platform, we'll see a zero - // `a_val` because `AT_*` values are never greater than `u32::MAX`. Zero is - // used by libc's `getauxval` to indicate errors, so it should never be a - // valid value. - if base.is_null() { - return None; - } - - let hdr = check_raw_pointer::<Elf_Ehdr>(base as *mut _)?; - - let hdr = hdr.as_ref(); - if hdr.e_ident[..SELFMAG] != ELFMAG { - return None; // Wrong ELF magic - } - if !matches!(hdr.e_ident[EI_OSABI], ELFOSABI_SYSV | ELFOSABI_LINUX) { - return None; // Unrecognized ELF OS ABI - } - if hdr.e_ident[EI_ABIVERSION] != ELFABIVERSION { - return None; // Unrecognized ELF ABI version - } - if hdr.e_type != ET_DYN { - return None; // Wrong ELF type - } - - // If ELF is extended, we'll need to adjust. - if hdr.e_ident[EI_VERSION] != EV_CURRENT - || hdr.e_ehsize as usize != size_of::<Elf_Ehdr>() - || hdr.e_phentsize as usize != size_of::<Elf_Phdr>() - { - return None; - } - // We don't currently support extra-large numbers of segments. - if hdr.e_phnum == PN_XNUM { - return None; - } - - // If `e_phoff` is zero, it's more likely that we're looking at memory that - // has been zeroed than that the kernel has somehow aliased the `Ehdr` and - // the `Phdr`. - if hdr.e_phoff < size_of::<Elf_Ehdr>() { - return None; - } - - // Verify that the `EI_CLASS`/`EI_DATA`/`e_machine` fields match the - // architecture we're running as. This helps catch cases where we're - // running under QEMU. - if hdr.e_ident[EI_CLASS] != ELFCLASS { - return None; // Wrong ELF class - } - if hdr.e_ident[EI_DATA] != ELFDATA { - return None; // Wrong ELF data - } - if hdr.e_machine != EM_CURRENT { - return None; // Wrong machine type - } - - Some(NonNull::new_unchecked(as_ptr(hdr) as *mut _)) -} - -// Aux reading utilities - -// Read auxv records from an array in memory. -struct AuxPointer(*const Elf_auxv_t); - -impl Iterator for AuxPointer { - type Item = Elf_auxv_t; - - #[cold] - fn next(&mut self) -> Option<Self::Item> { - unsafe { - let value = read_unaligned(self.0); - self.0 = self.0.add(1); - Some(value) - } - } -} - -// Read auxv records from a file. -#[cfg(not(feature = "alloc"))] -struct AuxFile(OwnedFd); - -#[cfg(not(feature = "alloc"))] -impl Iterator for AuxFile { - type Item = Elf_auxv_t; - - // This implementation does lots of `read`s and it isn't amazing, but - // hopefully we won't use it often. - #[cold] - fn next(&mut self) -> Option<Self::Item> { - let mut buf = [0_u8; size_of::<Self::Item>()]; - let mut slice = &mut buf[..]; - while !slice.is_empty() { - match crate::io::read(&self.0, &mut *slice) { - Ok(0) => panic!("unexpected end of auxv file"), - Ok(n) => slice = &mut slice[n..], - Err(crate::io::Errno::INTR) => continue, - Err(err) => panic!("{:?}", err), - } - } - Some(unsafe { read_unaligned(buf.as_ptr().cast()) }) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/param/init.rs b/vendor/rustix/src/backend/linux_raw/param/init.rs deleted file mode 100644 index de1e5949..00000000 --- a/vendor/rustix/src/backend/linux_raw/param/init.rs +++ /dev/null @@ -1,175 +0,0 @@ -//! Linux auxv `init` function, for "use-explicitly-provided-auxv" mode. -//! -//! # Safety -//! -//! This uses raw pointers to locate and read the kernel-provided auxv array. -#![allow(unsafe_code)] - -use crate::backend::c; -#[cfg(feature = "param")] -use crate::ffi::CStr; -use core::ffi::c_void; -use core::ptr::{null_mut, read, NonNull}; -#[cfg(feature = "runtime")] -use core::sync::atomic::AtomicBool; -use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; -use linux_raw_sys::elf::*; -use linux_raw_sys::general::{ - AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_MINSIGSTKSZ, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, -}; -#[cfg(feature = "runtime")] -use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE}; - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn page_size() -> usize { - PAGE_SIZE.load(Ordering::Relaxed) -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn clock_ticks_per_second() -> u64 { - CLOCK_TICKS_PER_SECOND.load(Ordering::Relaxed) as u64 -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_hwcap() -> (usize, usize) { - ( - HWCAP.load(Ordering::Relaxed), - HWCAP2.load(Ordering::Relaxed), - ) -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_minsigstksz() -> usize { - MINSIGSTKSZ.load(Ordering::Relaxed) -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_execfn() -> &'static CStr { - let execfn = EXECFN.load(Ordering::Relaxed); - - // SAFETY: We initialize `EXECFN` to a valid `CStr` pointer, and we assume - // the `AT_EXECFN` value provided by the kernel points to a valid C string. - unsafe { CStr::from_ptr(execfn.cast()) } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn linux_secure() -> bool { - SECURE.load(Ordering::Relaxed) -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn exe_phdrs() -> (*const c_void, usize, usize) { - ( - PHDR.load(Ordering::Relaxed).cast(), - PHENT.load(Ordering::Relaxed), - PHNUM.load(Ordering::Relaxed), - ) -} - -/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, so -/// if we don't see it, this function returns a null pointer. -#[inline] -pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { - SYSINFO_EHDR.load(Ordering::Relaxed) -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn entry() -> usize { - ENTRY.load(Ordering::Relaxed) -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn random() -> *const [u8; 16] { - RANDOM.load(Ordering::Relaxed) -} - -static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0); -static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0); -static HWCAP: AtomicUsize = AtomicUsize::new(0); -static HWCAP2: AtomicUsize = AtomicUsize::new(0); -static MINSIGSTKSZ: AtomicUsize = AtomicUsize::new(0); -static SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut()); -// Initialize `EXECFN` to a valid `CStr` pointer so that we don't need to check -// for null on every `execfn` call. -static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(b"\0".as_ptr() as _); -#[cfg(feature = "runtime")] -static SECURE: AtomicBool = AtomicBool::new(false); -// Use `dangling` so that we can always treat it like an empty slice. -#[cfg(feature = "runtime")] -static PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(NonNull::dangling().as_ptr()); -#[cfg(feature = "runtime")] -static PHENT: AtomicUsize = AtomicUsize::new(0); -#[cfg(feature = "runtime")] -static PHNUM: AtomicUsize = AtomicUsize::new(0); -#[cfg(feature = "runtime")] -static ENTRY: AtomicUsize = AtomicUsize::new(0); -#[cfg(feature = "runtime")] -static RANDOM: AtomicPtr<[u8; 16]> = AtomicPtr::new(NonNull::dangling().as_ptr()); - -/// When "use-explicitly-provided-auxv" is enabled, we export a function to be -/// called during initialization, and passed a pointer to the original -/// environment variable block set up by the OS. -pub(crate) unsafe fn init(envp: *mut *mut u8) { - init_from_envp(envp); -} - -/// # Safety -/// -/// This must be passed a pointer to the environment variable buffer -/// provided by the kernel, which is followed in memory by the auxv array. -unsafe fn init_from_envp(mut envp: *mut *mut u8) { - while !(*envp).is_null() { - envp = envp.add(1); - } - init_from_auxp(envp.add(1).cast()) -} - -/// Process auxv entries from the auxv array pointed to by `auxp`. -/// -/// # Safety -/// -/// This must be passed a pointer to an auxv array. -/// -/// The buffer contains `Elf_aux_t` elements, though it need not be aligned; -/// function uses `read_unaligned` to read from it. -unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { - loop { - let Elf_auxv_t { a_type, a_val } = read(auxp); - - match a_type as _ { - AT_PAGESZ => PAGE_SIZE.store(a_val as usize, Ordering::Relaxed), - AT_CLKTCK => CLOCK_TICKS_PER_SECOND.store(a_val as usize, Ordering::Relaxed), - AT_HWCAP => HWCAP.store(a_val as usize, Ordering::Relaxed), - AT_HWCAP2 => HWCAP2.store(a_val as usize, Ordering::Relaxed), - AT_MINSIGSTKSZ => MINSIGSTKSZ.store(a_val as usize, Ordering::Relaxed), - AT_EXECFN => EXECFN.store(a_val.cast::<c::c_char>(), Ordering::Relaxed), - AT_SYSINFO_EHDR => SYSINFO_EHDR.store(a_val.cast::<Elf_Ehdr>(), Ordering::Relaxed), - - #[cfg(feature = "runtime")] - AT_SECURE => SECURE.store(a_val as usize != 0, Ordering::Relaxed), - #[cfg(feature = "runtime")] - AT_PHDR => PHDR.store(a_val.cast::<Elf_Phdr>(), Ordering::Relaxed), - #[cfg(feature = "runtime")] - AT_PHNUM => PHNUM.store(a_val as usize, Ordering::Relaxed), - #[cfg(feature = "runtime")] - AT_PHENT => PHENT.store(a_val as usize, Ordering::Relaxed), - #[cfg(feature = "runtime")] - AT_ENTRY => ENTRY.store(a_val as usize, Ordering::Relaxed), - #[cfg(feature = "runtime")] - AT_RANDOM => RANDOM.store(a_val.cast::<[u8; 16]>(), Ordering::Relaxed), - - AT_NULL => break, - _ => (), - } - auxp = auxp.add(1); - } -} diff --git a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs deleted file mode 100644 index d77d3a84..00000000 --- a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs +++ /dev/null @@ -1,198 +0,0 @@ -//! Linux auxv support, using libc. -//! -//! # Safety -//! -//! This uses raw pointers to locate and read the kernel-provided auxv array. -#![allow(unsafe_code)] - -use crate::backend::c; -#[cfg(feature = "param")] -use crate::ffi::CStr; -#[cfg(not(feature = "runtime"))] -use core::ptr::null; -use linux_raw_sys::elf::*; - -// `getauxval` wasn't supported in glibc until 2.16. Also this lets us use -// `*mut` as the return type to preserve strict provenance. -#[cfg(not(feature = "runtime"))] -weak!(fn getauxval(c::c_ulong) -> *mut c::c_void); - -// With the "runtime" feature, go ahead and depend on `getauxval` existing so -// that we never fail. -#[cfg(feature = "runtime")] -extern "C" { - fn getauxval(type_: c::c_ulong) -> *mut c::c_void; -} - -#[cfg(feature = "runtime")] -const AT_PHDR: c::c_ulong = 3; -#[cfg(feature = "runtime")] -const AT_PHENT: c::c_ulong = 4; -#[cfg(feature = "runtime")] -const AT_PHNUM: c::c_ulong = 5; -#[cfg(feature = "runtime")] -const AT_ENTRY: c::c_ulong = 9; -const AT_HWCAP: c::c_ulong = 16; -#[cfg(feature = "runtime")] -const AT_RANDOM: c::c_ulong = 25; -const AT_HWCAP2: c::c_ulong = 26; -const AT_SECURE: c::c_ulong = 23; -const AT_EXECFN: c::c_ulong = 31; -const AT_SYSINFO_EHDR: c::c_ulong = 33; -const AT_MINSIGSTKSZ: c::c_ulong = 51; - -// Declare `sysconf` ourselves so that we don't depend on all of libc just for -// this. -extern "C" { - fn sysconf(name: c::c_int) -> c::c_long; -} - -#[cfg(target_os = "android")] -const _SC_PAGESIZE: c::c_int = 39; -#[cfg(target_os = "linux")] -const _SC_PAGESIZE: c::c_int = 30; -#[cfg(target_os = "android")] -const _SC_CLK_TCK: c::c_int = 6; -#[cfg(target_os = "linux")] -const _SC_CLK_TCK: c::c_int = 2; - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn page_size() -> usize { - unsafe { sysconf(_SC_PAGESIZE) as usize } -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn clock_ticks_per_second() -> u64 { - unsafe { sysconf(_SC_CLK_TCK) as u64 } -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_hwcap() -> (usize, usize) { - #[cfg(not(feature = "runtime"))] - unsafe { - if let Some(libc_getauxval) = getauxval.get() { - let hwcap = libc_getauxval(AT_HWCAP) as usize; - let hwcap2 = libc_getauxval(AT_HWCAP2) as usize; - (hwcap, hwcap2) - } else { - (0, 0) - } - } - - #[cfg(feature = "runtime")] - unsafe { - let hwcap = getauxval(AT_HWCAP) as usize; - let hwcap2 = getauxval(AT_HWCAP2) as usize; - (hwcap, hwcap2) - } -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_minsigstksz() -> usize { - #[cfg(not(feature = "runtime"))] - if let Some(libc_getauxval) = getauxval.get() { - unsafe { libc_getauxval(AT_MINSIGSTKSZ) as usize } - } else { - 0 - } - - #[cfg(feature = "runtime")] - unsafe { - getauxval(AT_MINSIGSTKSZ) as usize - } -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_execfn() -> &'static CStr { - #[cfg(not(feature = "runtime"))] - unsafe { - if let Some(libc_getauxval) = getauxval.get() { - CStr::from_ptr(libc_getauxval(AT_EXECFN).cast()) - } else { - cstr!("") - } - } - - #[cfg(feature = "runtime")] - unsafe { - CStr::from_ptr(getauxval(AT_EXECFN).cast()) - } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn linux_secure() -> bool { - unsafe { getauxval(AT_SECURE) as usize != 0 } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { - unsafe { - let phdr: *const c::c_void = getauxval(AT_PHDR); - let phent = getauxval(AT_PHENT) as usize; - let phnum = getauxval(AT_PHNUM) as usize; - (phdr, phent, phnum) - } -} - -/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, so -/// if we don't see it, this function returns a null pointer. -#[inline] -pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { - #[cfg(not(feature = "runtime"))] - unsafe { - if let Some(libc_getauxval) = getauxval.get() { - libc_getauxval(AT_SYSINFO_EHDR) as *const Elf_Ehdr - } else { - null() - } - } - - #[cfg(feature = "runtime")] - unsafe { - getauxval(AT_SYSINFO_EHDR) as *const Elf_Ehdr - } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn entry() -> usize { - unsafe { getauxval(AT_ENTRY) as usize } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn random() -> *const [u8; 16] { - unsafe { getauxval(AT_RANDOM) as *const [u8; 16] } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_abi() { - const_assert_eq!(self::_SC_PAGESIZE, ::libc::_SC_PAGESIZE); - const_assert_eq!(self::_SC_CLK_TCK, ::libc::_SC_CLK_TCK); - const_assert_eq!(self::AT_HWCAP, ::libc::AT_HWCAP); - const_assert_eq!(self::AT_HWCAP2, ::libc::AT_HWCAP2); - const_assert_eq!(self::AT_EXECFN, ::libc::AT_EXECFN); - const_assert_eq!(self::AT_SECURE, ::libc::AT_SECURE); - const_assert_eq!(self::AT_SYSINFO_EHDR, ::libc::AT_SYSINFO_EHDR); - const_assert_eq!(self::AT_MINSIGSTKSZ, ::libc::AT_MINSIGSTKSZ); - #[cfg(feature = "runtime")] - const_assert_eq!(self::AT_PHDR, ::libc::AT_PHDR); - #[cfg(feature = "runtime")] - const_assert_eq!(self::AT_PHNUM, ::libc::AT_PHNUM); - #[cfg(feature = "runtime")] - const_assert_eq!(self::AT_ENTRY, ::libc::AT_ENTRY); - #[cfg(feature = "runtime")] - const_assert_eq!(self::AT_RANDOM, ::libc::AT_RANDOM); - } -} diff --git a/vendor/rustix/src/backend/linux_raw/param/mod.rs b/vendor/rustix/src/backend/linux_raw/param/mod.rs deleted file mode 100644 index 365f0160..00000000 --- a/vendor/rustix/src/backend/linux_raw/param/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// With "use-explicitly-provided-auxv" enabled, we expect to be initialized -// with an explicit `rustix::param::init` call. -// -// With "use-libc-auxv" enabled, use libc's `getauxval`. -// -// Otherwise, we read aux values from /proc/self/auxv. -#[cfg_attr(feature = "use-explicitly-provided-auxv", path = "init.rs")] -#[cfg_attr( - all( - not(feature = "use-explicitly-provided-auxv"), - feature = "use-libc-auxv" - ), - path = "libc_auxv.rs" -)] -pub(crate) mod auxv; diff --git a/vendor/rustix/src/backend/linux_raw/pid/mod.rs b/vendor/rustix/src/backend/linux_raw/pid/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/linux_raw/pid/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/pid/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pid/syscalls.rs deleted file mode 100644 index 49aaf43e..00000000 --- a/vendor/rustix/src/backend/linux_raw/pid/syscalls.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! linux_raw syscalls for PIDs -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::ret_usize_infallible; -use crate::pid::{Pid, RawPid}; - -#[inline] -#[must_use] -pub(crate) fn getpid() -> Pid { - unsafe { - let pid = ret_usize_infallible(syscall_readonly!(__NR_getpid)) as RawPid; - Pid::from_raw_unchecked(pid) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/pipe/mod.rs b/vendor/rustix/src/backend/linux_raw/pipe/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/pipe/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs deleted file mode 100644 index 86fe0855..00000000 --- a/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! linux_raw syscalls supporting `rustix::pipe`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{c_int, c_uint, opt_mut, pass_usize, ret, ret_usize, slice}; -use crate::backend::{c, MAX_IOV}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::pipe::{IoSliceRaw, PipeFlags, SpliceFlags}; -use core::cmp; -use core::mem::MaybeUninit; -use linux_raw_sys::general::{F_GETPIPE_SZ, F_SETPIPE_SZ}; - -#[inline] -pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { - // aarch64 and risc64 omit `__NR_pipe`. On mips, `__NR_pipe` uses a special - // calling convention, but using it is not worth complicating our syscall - // wrapping infrastructure at this time. - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - ))] - { - pipe_with(PipeFlags::empty()) - } - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv64", - )))] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!(__NR_pipe, &mut result))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[inline] -pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!(__NR_pipe2, &mut result, flags))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[inline] -pub(crate) fn splice( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - unsafe { - ret_usize(syscall!( - __NR_splice, - fd_in, - opt_mut(off_in), - fd_out, - opt_mut(off_out), - pass_usize(len), - flags - )) - } -} - -#[inline] -pub(crate) unsafe fn vmsplice( - fd: BorrowedFd<'_>, - bufs: &[IoSliceRaw<'_>], - flags: SpliceFlags, -) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - ret_usize(syscall!(__NR_vmsplice, fd, bufs_addr, bufs_len, flags)) -} - -#[inline] -pub(crate) fn tee( - fd_in: BorrowedFd<'_>, - fd_out: BorrowedFd<'_>, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - unsafe { ret_usize(syscall!(__NR_tee, fd_in, fd_out, pass_usize(len), flags)) } -} - -#[inline] -pub(crate) fn fcntl_getpipe_size(fd: BorrowedFd<'_>) -> io::Result<usize> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETPIPE_SZ))) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETPIPE_SZ))) - } -} - -#[inline] -pub(crate) fn fcntl_setpipe_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<usize> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?; - - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(F_SETPIPE_SZ), - c_int(size) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(F_SETPIPE_SZ), - c_int(size) - )) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/pipe/types.rs b/vendor/rustix/src/backend/linux_raw/pipe/types.rs deleted file mode 100644 index ae185562..00000000 --- a/vendor/rustix/src/backend/linux_raw/pipe/types.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::backend::c; -use crate::ffi; -use bitflags::bitflags; -use core::marker::PhantomData; - -bitflags! { - /// `O_*` constants for use with [`pipe_with`]. - /// - /// [`pipe_with`]: crate::pipe::pipe_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PipeFlags: ffi::c_uint { - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - /// `O_DIRECT` - const DIRECT = linux_raw_sys::general::O_DIRECT; - /// `O_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `SPLICE_F_*` constants for use with [`splice`], [`vmsplice`], and - /// [`tee`]. - /// - /// [`splice`]: crate::pipe::splice - /// [`vmsplice`]: crate::pipe::splice - /// [`tee`]: crate::pipe::tee - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpliceFlags: ffi::c_uint { - /// `SPLICE_F_MOVE` - const MOVE = linux_raw_sys::general::SPLICE_F_MOVE; - /// `SPLICE_F_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::SPLICE_F_NONBLOCK; - /// `SPLICE_F_MORE` - const MORE = linux_raw_sys::general::SPLICE_F_MORE; - /// `SPLICE_F_GIFT` - const GIFT = linux_raw_sys::general::SPLICE_F_GIFT; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// A buffer type for use with [`vmsplice`]. -/// -/// It is guaranteed to be ABI compatible with the iovec type on Unix platforms -/// and `WSABUF` on Windows. Unlike `IoSlice` and `IoSliceMut` it is -/// semantically like a raw pointer, and therefore can be shared or mutated as -/// needed. -/// -/// [`vmsplice`]: crate::pipe::vmsplice -#[repr(transparent)] -pub struct IoSliceRaw<'a> { - _buf: c::iovec, - _lifetime: PhantomData<&'a ()>, -} - -impl<'a> IoSliceRaw<'a> { - /// Creates a new `IoSlice` wrapping a byte slice. - pub fn from_slice(buf: &'a [u8]) -> Self { - IoSliceRaw { - _buf: c::iovec { - iov_base: (buf.as_ptr() as *mut u8).cast::<ffi::c_void>(), - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } - } - - /// Creates a new `IoSlice` wrapping a mutable byte slice. - pub fn from_slice_mut(buf: &'a mut [u8]) -> Self { - IoSliceRaw { - _buf: c::iovec { - iov_base: buf.as_mut_ptr().cast::<ffi::c_void>(), - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } - } -} diff --git a/vendor/rustix/src/backend/linux_raw/prctl/mod.rs b/vendor/rustix/src/backend/linux_raw/prctl/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/linux_raw/prctl/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/prctl/syscalls.rs b/vendor/rustix/src/backend/linux_raw/prctl/syscalls.rs deleted file mode 100644 index 1410d512..00000000 --- a/vendor/rustix/src/backend/linux_raw/prctl/syscalls.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! linux_raw syscalls supporting modules that use `prctl`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -use crate::backend::conv::{c_int, ret_c_int}; -use crate::io; - -#[inline] -pub(crate) unsafe fn prctl( - option: c::c_int, - arg2: *mut c::c_void, - arg3: *mut c::c_void, - arg4: *mut c::c_void, - arg5: *mut c::c_void, -) -> io::Result<c::c_int> { - ret_c_int(syscall!(__NR_prctl, c_int(option), arg2, arg3, arg4, arg5)) -} diff --git a/vendor/rustix/src/backend/linux_raw/process/mod.rs b/vendor/rustix/src/backend/linux_raw/process/mod.rs deleted file mode 100644 index 6bc9443d..00000000 --- a/vendor/rustix/src/backend/linux_raw/process/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; -pub(crate) mod wait; diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs deleted file mode 100644 index c9c1fd82..00000000 --- a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs +++ /dev/null @@ -1,560 +0,0 @@ -//! linux_raw syscalls supporting `rustix::process`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -#[cfg(all(feature = "alloc", feature = "fs"))] -use crate::backend::conv::slice_mut; -use crate::backend::conv::{ - by_mut, by_ref, c_int, c_uint, negative_pid, pass_usize, raw_fd, ret, ret_c_int, - ret_c_int_infallible, ret_infallible, ret_owned_fd, zero, -}; -use crate::fd::{AsRawFd as _, BorrowedFd, OwnedFd, RawFd}; -#[cfg(feature = "fs")] -use crate::ffi::CStr; -use crate::io; -use crate::pid::RawPid; -use crate::process::{ - Flock, Pid, PidfdFlags, PidfdGetfdFlags, Resource, Rlimit, Uid, WaitId, WaitIdOptions, - WaitIdStatus, WaitOptions, WaitStatus, -}; -use crate::signal::Signal; -use core::mem::MaybeUninit; -use core::ptr::{null, null_mut}; -use linux_raw_sys::general::{rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, RLIM64_INFINITY}; -#[cfg(feature = "fs")] -use {crate::backend::conv::ret_c_uint_infallible, crate::fs::Mode}; -#[cfg(feature = "alloc")] -use { - crate::backend::conv::{ret_usize, slice_just_addr_mut}, - crate::process::Gid, -}; - -#[cfg(feature = "fs")] -#[inline] -pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_chdir, filename)) } -} - -#[inline] -pub(crate) fn fchdir(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fchdir, fd)) } -} - -#[cfg(feature = "fs")] -#[inline] -pub(crate) fn chroot(filename: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_chroot, filename)) } -} - -#[cfg(all(feature = "alloc", feature = "fs"))] -#[inline] -pub(crate) fn getcwd(buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { ret_usize(syscall!(__NR_getcwd, buf_addr_mut, buf_len)) } -} - -#[inline] -#[must_use] -pub(crate) fn getppid() -> Option<Pid> { - unsafe { - let ppid = ret_c_int_infallible(syscall_readonly!(__NR_getppid)); - Pid::from_raw(ppid) - } -} - -#[inline] -pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { - unsafe { - let pgid = ret_c_int(syscall_readonly!(__NR_getpgid, c_int(Pid::as_raw(pid))))?; - debug_assert!(pgid > 0); - Ok(Pid::from_raw_unchecked(pgid)) - } -} - -#[inline] -pub(crate) fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpgid, - c_int(Pid::as_raw(pid)), - c_int(Pid::as_raw(pgid)) - )) - } -} - -#[inline] -#[must_use] -pub(crate) fn getpgrp() -> Pid { - // Use the `getpgrp` syscall if available. - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - let pgid = ret_c_int_infallible(syscall_readonly!(__NR_getpgrp)); - debug_assert!(pgid > 0); - Pid::from_raw_unchecked(pgid) - } - - // Otherwise use `getpgrp` and pass it zero. - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - unsafe { - let pgid = ret_c_int_infallible(syscall_readonly!(__NR_getpgid, c_uint(0))); - debug_assert!(pgid > 0); - Pid::from_raw_unchecked(pgid) - } -} - -#[cfg(feature = "fs")] -#[inline] -pub(crate) fn umask(mode: Mode) -> Mode { - unsafe { Mode::from_bits_retain(ret_c_uint_infallible(syscall_readonly!(__NR_umask, mode))) } -} - -#[inline] -pub(crate) fn nice(inc: i32) -> io::Result<i32> { - let priority = (if inc > -40 && inc < 40 { - inc + getpriority_process(None)? - } else { - inc - }) - .clamp(-20, 19); - setpriority_process(None, priority)?; - Ok(priority) -} - -#[inline] -pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_USER), - c_uint(uid.as_raw()) - ))?) - } -} - -#[inline] -pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_PGRP), - c_int(Pid::as_raw(pgid)) - ))?) - } -} - -#[inline] -pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_PROCESS), - c_int(Pid::as_raw(pid)) - ))?) - } -} - -#[inline] -pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_USER), - c_uint(uid.as_raw()), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_PGRP), - c_int(Pid::as_raw(pgid)), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_PROCESS), - c_int(Pid::as_raw(pid)), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn getrlimit(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::<rlimit64>::uninit(); - unsafe { - ret_infallible(syscall!( - __NR_prlimit64, - c_uint(0), - limit, - null::<c::c_void>(), - &mut result - )); - rlimit_from_linux(result.assume_init()) - } -} - -#[inline] -pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { - unsafe { - let lim = rlimit_to_linux(new); - match ret(syscall_readonly!( - __NR_prlimit64, - c_uint(0), - limit, - by_ref(&lim), - null_mut::<c::c_void>() - )) { - Ok(()) => Ok(()), - Err(err) => Err(err), - } - } -} - -#[inline] -pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Result<Rlimit> { - let lim = rlimit_to_linux(new); - let mut result = MaybeUninit::<rlimit64>::uninit(); - unsafe { - match ret(syscall!( - __NR_prlimit64, - c_int(Pid::as_raw(pid)), - limit, - by_ref(&lim), - &mut result - )) { - Ok(()) => Ok(rlimit_from_linux(result.assume_init())), - Err(err) => Err(err), - } - } -} - -/// Convert a C `rlimit64` to a Rust `Rlimit`. -#[inline] -fn rlimit_from_linux(lim: rlimit64) -> Rlimit { - let current = if lim.rlim_cur == RLIM64_INFINITY as u64 { - None - } else { - Some(lim.rlim_cur) - }; - let maximum = if lim.rlim_max == RLIM64_INFINITY as u64 { - None - } else { - Some(lim.rlim_max) - }; - Rlimit { current, maximum } -} - -/// Convert a Rust [`Rlimit`] to a C `rlimit64`. -#[inline] -fn rlimit_to_linux(lim: Rlimit) -> rlimit64 { - let rlim_cur = match lim.current { - Some(r) => r, - None => RLIM64_INFINITY as _, - }; - let rlim_max = match lim.maximum { - Some(r) => r, - None => RLIM64_INFINITY as _, - }; - rlimit64 { rlim_cur, rlim_max } -} - -#[inline] -pub(crate) fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(!0, waitopts) -} - -#[inline] -pub(crate) fn waitpid( - pid: Option<Pid>, - waitopts: WaitOptions, -) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(Pid::as_raw(pid), waitopts) -} - -#[inline] -pub(crate) fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(-pgid.as_raw_nonzero().get(), waitopts) -} - -#[inline] -pub(crate) fn _waitpid( - pid: RawPid, - waitopts: WaitOptions, -) -> io::Result<Option<(Pid, WaitStatus)>> { - unsafe { - let mut status = MaybeUninit::<i32>::uninit(); - let pid = ret_c_int(syscall!( - __NR_wait4, - c_int(pid as _), - &mut status, - c_int(waitopts.bits() as _), - zero() - ))?; - Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status.assume_init())))) - } -} - -#[inline] -pub(crate) fn waitid(id: WaitId<'_>, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // Get the id to wait on. - match id { - WaitId::All => _waitid_all(options), - WaitId::Pid(pid) => _waitid_pid(pid, options), - WaitId::Pgid(pid) => _waitid_pgid(pid, options), - WaitId::PidFd(fd) => _waitid_pidfd(fd, options), - } -} - -#[inline] -fn _waitid_all(options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(syscall!( - __NR_waitid, - c_uint(c::P_ALL), - c_uint(0), - &mut status, - c_int(options.bits() as _), - zero() - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -#[inline] -fn _waitid_pid(pid: Pid, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(syscall!( - __NR_waitid, - c_uint(c::P_PID), - c_int(Pid::as_raw(Some(pid))), - &mut status, - c_int(options.bits() as _), - zero() - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -#[inline] -fn _waitid_pgid(pgid: Option<Pid>, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(syscall!( - __NR_waitid, - c_uint(c::P_PGID), - c_int(Pid::as_raw(pgid)), - &mut status, - c_int(options.bits() as _), - zero() - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -#[inline] -fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitIdOptions) -> io::Result<Option<WaitIdStatus>> { - // `waitid` can return successfully without initializing the struct (no - // children found when using `WNOHANG`) - let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); - unsafe { - ret(syscall!( - __NR_waitid, - c_uint(c::P_PIDFD), - c_uint(fd.as_raw_fd() as _), - &mut status, - c_int(options.bits() as _), - zero() - ))? - }; - - Ok(unsafe { cvt_waitid_status(status) }) -} - -/// Convert a `siginfo_t` to a `WaitIdStatus`. -/// -/// # Safety -/// -/// The caller must ensure that `status` is initialized and that `waitid` -/// returned successfully. -#[inline] -unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitIdStatus> { - let status = status.assume_init(); - if status - .__bindgen_anon_1 - .__bindgen_anon_1 - ._sifields - ._sigchld - ._pid - == 0 - { - None - } else { - Some(WaitIdStatus(status)) - } -} - -#[inline] -pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> { - unsafe { - let pid = ret_c_int(syscall_readonly!(__NR_getsid, c_int(Pid::as_raw(pid))))?; - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[inline] -pub(crate) fn setsid() -> io::Result<Pid> { - unsafe { - let pid = ret_c_int(syscall_readonly!(__NR_setsid))?; - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[inline] -pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pid, sig)) } -} - -#[inline] -pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, negative_pid(pid), sig)) } -} - -#[inline] -pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pass_usize(0), sig)) } -} - -#[inline] -pub(crate) fn test_kill_process(pid: Pid) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pid, pass_usize(0))) } -} - -#[inline] -pub(crate) fn test_kill_process_group(pid: Pid) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_kill, - negative_pid(pid), - pass_usize(0) - )) - } -} - -#[inline] -pub(crate) fn test_kill_current_process_group() -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pass_usize(0), pass_usize(0))) } -} - -#[inline] -pub(crate) fn pidfd_getfd( - pidfd: BorrowedFd<'_>, - targetfd: RawFd, - flags: PidfdGetfdFlags, -) -> io::Result<OwnedFd> { - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_pidfd_getfd, - pidfd, - raw_fd(targetfd), - c_int(flags.bits() as _) - )) - } -} - -#[inline] -pub(crate) fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_pidfd_open, pid, flags)) } -} - -#[inline] -pub(crate) fn pidfd_send_signal(fd: BorrowedFd<'_>, sig: Signal) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_pidfd_send_signal, - fd, - sig, - pass_usize(0), - pass_usize(0) - )) - } -} - -#[cfg(feature = "fs")] -#[inline] -pub(crate) fn pivot_root(new_root: &CStr, put_old: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_pivot_root, new_root, put_old)) } -} - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> { - let len = buf.len().try_into().map_err(|_| io::Errno::NOMEM)?; - - unsafe { - ret_usize(syscall!( - __NR_getgroups, - c_int(len), - slice_just_addr_mut(buf) - )) - } -} - -#[inline] -pub(crate) fn fcntl_getlk(fd: BorrowedFd<'_>, lock: &Flock) -> io::Result<Option<Flock>> { - let mut curr_lock: c::flock = lock.as_raw(); - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_fcntl64, - fd, - c_uint(c::F_GETLK64), - by_mut(&mut curr_lock) - ))? - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall!( - __NR_fcntl, - fd, - c_uint(c::F_GETLK), - by_mut(&mut curr_lock) - ))? - } - - // If no blocking lock is found, `fcntl(GETLK, ..)` sets `l_type` to - // `F_UNLCK`. - if curr_lock.l_type == c::F_UNLCK as _ { - Ok(None) - } else { - Ok(Some(unsafe { Flock::from_raw_unchecked(curr_lock) })) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/process/types.rs b/vendor/rustix/src/backend/linux_raw/process/types.rs deleted file mode 100644 index 58b8cc14..00000000 --- a/vendor/rustix/src/backend/linux_raw/process/types.rs +++ /dev/null @@ -1,43 +0,0 @@ -/// A resource value for use with [`getrlimit`], [`setrlimit`], and -/// [`prlimit`]. -/// -/// [`getrlimit`]: crate::process::getrlimit -/// [`setrlimit`]: crate::process::setrlimit -/// [`prlimit`]: crate::process::prlimit -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -#[non_exhaustive] -pub enum Resource { - /// `RLIMIT_CPU` - Cpu = linux_raw_sys::general::RLIMIT_CPU, - /// `RLIMIT_FSIZE` - Fsize = linux_raw_sys::general::RLIMIT_FSIZE, - /// `RLIMIT_DATA` - Data = linux_raw_sys::general::RLIMIT_DATA, - /// `RLIMIT_STACK` - Stack = linux_raw_sys::general::RLIMIT_STACK, - /// `RLIMIT_CORE` - Core = linux_raw_sys::general::RLIMIT_CORE, - /// `RLIMIT_RSS` - Rss = linux_raw_sys::general::RLIMIT_RSS, - /// `RLIMIT_NPROC` - Nproc = linux_raw_sys::general::RLIMIT_NPROC, - /// `RLIMIT_NOFILE` - Nofile = linux_raw_sys::general::RLIMIT_NOFILE, - /// `RLIMIT_MEMLOCK` - Memlock = linux_raw_sys::general::RLIMIT_MEMLOCK, - /// `RLIMIT_AS` - As = linux_raw_sys::general::RLIMIT_AS, - /// `RLIMIT_LOCKS` - Locks = linux_raw_sys::general::RLIMIT_LOCKS, - /// `RLIMIT_SIGPENDING` - Sigpending = linux_raw_sys::general::RLIMIT_SIGPENDING, - /// `RLIMIT_MSGQUEUE` - Msgqueue = linux_raw_sys::general::RLIMIT_MSGQUEUE, - /// `RLIMIT_NICE` - Nice = linux_raw_sys::general::RLIMIT_NICE, - /// `RLIMIT_RTPRIO` - Rtprio = linux_raw_sys::general::RLIMIT_RTPRIO, - /// `RLIMIT_RTTIME` - Rttime = linux_raw_sys::general::RLIMIT_RTTIME, -} diff --git a/vendor/rustix/src/backend/linux_raw/process/wait.rs b/vendor/rustix/src/backend/linux_raw/process/wait.rs deleted file mode 100644 index 89b3eadb..00000000 --- a/vendor/rustix/src/backend/linux_raw/process/wait.rs +++ /dev/null @@ -1,123 +0,0 @@ -// The functions replacing the C macros use the same names as in libc. -#![allow(non_snake_case, unsafe_code)] - -use crate::ffi::c_int; -pub(crate) use linux_raw_sys::general::{ - siginfo_t, WCONTINUED, WEXITED, WNOHANG, WNOWAIT, WSTOPPED, WUNTRACED, -}; - -#[inline] -pub(crate) fn WIFSTOPPED(status: i32) -> bool { - (status & 0xff) == 0x7f -} - -#[inline] -pub(crate) fn WSTOPSIG(status: i32) -> i32 { - (status >> 8) & 0xff -} - -#[inline] -pub(crate) fn WIFCONTINUED(status: i32) -> bool { - status == 0xffff -} - -#[inline] -pub(crate) fn WIFSIGNALED(status: i32) -> bool { - ((status & 0x7f) + 1) as i8 >= 2 -} - -#[inline] -pub(crate) fn WTERMSIG(status: i32) -> i32 { - status & 0x7f -} - -#[inline] -pub(crate) fn WIFEXITED(status: i32) -> bool { - (status & 0x7f) == 0 -} - -#[inline] -pub(crate) fn WEXITSTATUS(status: i32) -> i32 { - (status >> 8) & 0xff -} - -pub(crate) trait SiginfoExt { - fn si_signo(&self) -> c_int; - fn si_errno(&self) -> c_int; - fn si_code(&self) -> c_int; - unsafe fn si_status(&self) -> c_int; -} - -impl SiginfoExt for siginfo_t { - #[inline] - fn si_signo(&self) -> c_int { - // SAFETY: This is technically a union access, but it's only a union - // with padding. - unsafe { self.__bindgen_anon_1.__bindgen_anon_1.si_signo } - } - - #[inline] - fn si_errno(&self) -> c_int { - // SAFETY: This is technically a union access, but it's only a union - // with padding. - unsafe { self.__bindgen_anon_1.__bindgen_anon_1.si_errno } - } - - #[inline] - fn si_code(&self) -> c_int { - // SAFETY: This is technically a union access, but it's only a union - // with padding. - unsafe { self.__bindgen_anon_1.__bindgen_anon_1.si_code } - } - - /// Return the exit status or signal number recorded in a `siginfo_t`. - /// - /// # Safety - /// - /// `si_signo` must equal `SIGCHLD` (as it is guaranteed to do after a - /// `waitid` call). - #[inline] - unsafe fn si_status(&self) -> c_int { - self.__bindgen_anon_1 - .__bindgen_anon_1 - ._sifields - ._sigchld - ._status - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_libc_correspondence() { - for status in [ - 0, - 1, - 63, - 64, - 65, - 127, - 128, - 129, - 255, - 256, - 257, - 4095, - 4096, - 4097, - i32::MAX, - i32::MIN, - u32::MAX as i32, - ] { - assert_eq!(WIFSTOPPED(status), libc::WIFSTOPPED(status)); - assert_eq!(WSTOPSIG(status), libc::WSTOPSIG(status)); - assert_eq!(WIFCONTINUED(status), libc::WIFCONTINUED(status)); - assert_eq!(WIFSIGNALED(status), libc::WIFSIGNALED(status)); - assert_eq!(WTERMSIG(status), libc::WTERMSIG(status)); - assert_eq!(WIFEXITED(status), libc::WIFEXITED(status)); - assert_eq!(WEXITSTATUS(status), libc::WEXITSTATUS(status)); - } - } -} diff --git a/vendor/rustix/src/backend/linux_raw/pty/mod.rs b/vendor/rustix/src/backend/linux_raw/pty/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/linux_raw/pty/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/pty/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pty/syscalls.rs deleted file mode 100644 index b64344fb..00000000 --- a/vendor/rustix/src/backend/linux_raw/pty/syscalls.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! linux_raw syscalls supporting `rustix::pty`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{by_ref, c_uint, ret}; -use crate::fd::BorrowedFd; -use crate::io; -use linux_raw_sys::ioctl::TIOCSPTLCK; -#[cfg(feature = "alloc")] -use { - crate::backend::c, crate::ffi::CString, crate::path::DecInt, alloc::vec::Vec, - core::mem::MaybeUninit, linux_raw_sys::ioctl::TIOCGPTN, -}; - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn ptsname(fd: BorrowedFd<'_>, mut buffer: Vec<u8>) -> io::Result<CString> { - unsafe { - let mut n = MaybeUninit::<c::c_int>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGPTN), &mut n))?; - - buffer.clear(); - buffer.extend_from_slice(b"/dev/pts/"); - buffer.extend_from_slice(DecInt::new(n.assume_init()).as_bytes()); - buffer.push(b'\0'); - Ok(CString::from_vec_with_nul_unchecked(buffer)) - } -} - -#[inline] -pub(crate) fn unlockpt(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(TIOCSPTLCK), - by_ref(&0) - )) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/rand/mod.rs b/vendor/rustix/src/backend/linux_raw/rand/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/rand/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs b/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs deleted file mode 100644 index acea3968..00000000 --- a/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! linux_raw syscalls supporting `rustix::rand`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{pass_usize, ret_usize}; -use crate::io; -use crate::rand::GetRandomFlags; - -#[inline] -pub(crate) unsafe fn getrandom(buf: (*mut u8, usize), flags: GetRandomFlags) -> io::Result<usize> { - ret_usize(syscall!(__NR_getrandom, buf.0, pass_usize(buf.1), flags)) -} diff --git a/vendor/rustix/src/backend/linux_raw/rand/types.rs b/vendor/rustix/src/backend/linux_raw/rand/types.rs deleted file mode 100644 index 9bc857fd..00000000 --- a/vendor/rustix/src/backend/linux_raw/rand/types.rs +++ /dev/null @@ -1,20 +0,0 @@ -use bitflags::bitflags; - -bitflags! { - /// `GRND_*` flags for use with [`getrandom`]. - /// - /// [`getrandom`]: crate::rand::getrandom - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct GetRandomFlags: u32 { - /// `GRND_RANDOM` - const RANDOM = linux_raw_sys::general::GRND_RANDOM; - /// `GRND_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::GRND_NONBLOCK; - /// `GRND_INSECURE` - const INSECURE = linux_raw_sys::general::GRND_INSECURE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/reg.rs b/vendor/rustix/src/backend/linux_raw/reg.rs deleted file mode 100644 index 57a8d269..00000000 --- a/vendor/rustix/src/backend/linux_raw/reg.rs +++ /dev/null @@ -1,259 +0,0 @@ -//! Encapsulation for system call arguments and return values. -//! -//! The inline-asm code paths do some amount of reordering of arguments; to -//! ensure that we don't accidentally misroute an argument or return value, we -//! use distinct types for each argument index and return value. -//! -//! # Safety -//! -//! The `ToAsm` and `FromAsm` traits are unsafe to use; they should only be -//! used by the syscall code which executes actual syscall machine -//! instructions. - -#![allow(unsafe_code)] - -use super::c; -use super::fd::RawFd; -use core::marker::PhantomData; -use core::ops::Range; - -pub(super) trait ToAsm: private::Sealed { - /// Convert `self` to a `usize` ready to be passed to a syscall - /// machine instruction. - /// - /// # Safety - /// - /// This should be used immediately before the syscall instruction, and the - /// returned value shouldn't be used for any other purpose. - #[must_use] - unsafe fn to_asm(self) -> *mut Opaque; -} - -pub(super) trait FromAsm: private::Sealed { - /// Convert `raw` from a value produced by a syscall machine instruction - /// into a `Self`. - /// - /// # Safety - /// - /// This should be used immediately after the syscall instruction, and the - /// operand value shouldn't be used for any other purpose. - #[must_use] - unsafe fn from_asm(raw: *mut Opaque) -> Self; -} - -/// To preserve provenance, syscall arguments and return values are passed as -/// pointer types. They need a type to point to, so we define a custom private -/// type, to prevent it from being used for anything else. -#[repr(transparent)] -#[allow(dead_code)] -pub(super) struct Opaque(c::c_void); - -// Argument numbers. -pub(super) struct A0(()); -pub(super) struct A1(()); -pub(super) struct A2(()); -pub(super) struct A3(()); -pub(super) struct A4(()); -pub(super) struct A5(()); -#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] -pub(super) struct A6(()); -#[cfg(target_arch = "x86")] -pub(super) struct SocketArg; - -pub(super) trait ArgNumber: private::Sealed {} -impl ArgNumber for A0 {} -impl ArgNumber for A1 {} -impl ArgNumber for A2 {} -impl ArgNumber for A3 {} -impl ArgNumber for A4 {} -impl ArgNumber for A5 {} -#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] -impl ArgNumber for A6 {} -#[cfg(target_arch = "x86")] -impl ArgNumber for SocketArg {} - -// Return value numbers. -pub(super) struct R0(()); - -pub(super) trait RetNumber: private::Sealed {} -impl RetNumber for R0 {} - -/// Syscall arguments use register-sized types. We use a newtype to -/// discourage accidental misuse of the raw integer values. -/// -/// This type doesn't implement `Clone` or `Copy`; it should be used exactly -/// once. And it has a lifetime to ensure that it doesn't outlive any resources -/// it might be pointing to. -#[repr(transparent)] -#[must_use] -pub(super) struct ArgReg<'a, Num: ArgNumber> { - raw: *mut Opaque, - _phantom: PhantomData<(&'a (), Num)>, -} - -impl<'a, Num: ArgNumber> ToAsm for ArgReg<'a, Num> { - #[inline] - unsafe fn to_asm(self) -> *mut Opaque { - self.raw - } -} - -/// Syscall return values use register-sized types. We use a newtype to -/// discourage accidental misuse of the raw integer values. -/// -/// This type doesn't implement `Clone` or `Copy`; it should be used exactly -/// once. -#[repr(transparent)] -#[must_use] -pub(super) struct RetReg<Num: RetNumber> { - raw: *mut Opaque, - _phantom: PhantomData<Num>, -} - -impl<Num: RetNumber> RetReg<Num> { - #[inline] - pub(super) fn decode_usize(self) -> usize { - debug_assert!(!(-4095..0).contains(&(self.raw as isize))); - self.raw as usize - } - - #[inline] - pub(super) fn decode_raw_fd(self) -> RawFd { - let bits = self.decode_usize(); - let raw_fd = bits as RawFd; - - // Converting `raw` to `RawFd` should be lossless. - debug_assert_eq!(raw_fd as usize, bits); - - raw_fd - } - - #[inline] - pub(super) fn decode_c_int(self) -> c::c_int { - let bits = self.decode_usize(); - let c_int_ = bits as c::c_int; - - // Converting `raw` to `c_int` should be lossless. - debug_assert_eq!(c_int_ as usize, bits); - - c_int_ - } - - #[inline] - pub(super) fn decode_c_uint(self) -> c::c_uint { - let bits = self.decode_usize(); - let c_uint_ = bits as c::c_uint; - - // Converting `raw` to `c_uint` should be lossless. - debug_assert_eq!(c_uint_ as usize, bits); - - c_uint_ - } - - #[inline] - pub(super) fn decode_void_star(self) -> *mut c::c_void { - self.raw.cast() - } - - #[cfg(target_pointer_width = "64")] - #[inline] - pub(super) fn decode_u64(self) -> u64 { - self.decode_usize() as u64 - } - - #[inline] - pub(super) fn decode_void(self) { - let ignore = self.decode_usize(); - debug_assert_eq!(ignore, 0); - } - - #[inline] - pub(super) fn decode_error_code(self) -> u16 { - let bits = self.raw as usize; - - // `raw` must be in `-4095..0`. Linux always returns errors in - // `-4095..0`, and we double-check it here. - debug_assert!((-4095..0).contains(&(bits as isize))); - - bits as u16 - } - - #[inline] - pub(super) fn is_nonzero(&self) -> bool { - !self.raw.is_null() - } - - #[inline] - pub(super) fn is_negative(&self) -> bool { - (self.raw as isize) < 0 - } - - #[inline] - pub(super) fn is_in_range(&self, range: Range<isize>) -> bool { - range.contains(&(self.raw as isize)) - } -} - -impl<Num: RetNumber> FromAsm for RetReg<Num> { - #[inline] - unsafe fn from_asm(raw: *mut Opaque) -> Self { - Self { - raw, - _phantom: PhantomData, - } - } -} - -#[repr(transparent)] -pub(super) struct SyscallNumber<'a> { - pub(super) nr: usize, - _phantom: PhantomData<&'a ()>, -} - -impl<'a> ToAsm for SyscallNumber<'a> { - #[inline] - unsafe fn to_asm(self) -> *mut Opaque { - self.nr as usize as *mut Opaque - } -} - -/// Encode a system call argument as an `ArgReg`. -#[inline] -pub(super) fn raw_arg<'a, Num: ArgNumber>(raw: *mut Opaque) -> ArgReg<'a, Num> { - ArgReg { - raw, - _phantom: PhantomData, - } -} - -/// Encode a system call number (a `__NR_*` constant) as a `SyscallNumber`. -#[inline] -pub(super) const fn nr<'a>(nr: u32) -> SyscallNumber<'a> { - SyscallNumber { - nr: nr as usize, - _phantom: PhantomData, - } -} - -/// Seal our various traits using the technique documented [here]. -/// -/// [here]: https://rust-lang.github.io/api-guidelines/future-proofing.html -mod private { - pub trait Sealed {} - - // Implement for those same types, but no others. - impl<'a, Num: super::ArgNumber> Sealed for super::ArgReg<'a, Num> {} - impl<Num: super::RetNumber> Sealed for super::RetReg<Num> {} - impl<'a> Sealed for super::SyscallNumber<'a> {} - impl Sealed for super::A0 {} - impl Sealed for super::A1 {} - impl Sealed for super::A2 {} - impl Sealed for super::A3 {} - impl Sealed for super::A4 {} - impl Sealed for super::A5 {} - #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] - impl Sealed for super::A6 {} - #[cfg(target_arch = "x86")] - impl Sealed for super::SocketArg {} - impl Sealed for super::R0 {} -} diff --git a/vendor/rustix/src/backend/linux_raw/runtime/mod.rs b/vendor/rustix/src/backend/linux_raw/runtime/mod.rs deleted file mode 100644 index 0b48649c..00000000 --- a/vendor/rustix/src/backend/linux_raw/runtime/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod tls; diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs deleted file mode 100644 index 1e00030c..00000000 --- a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs +++ /dev/null @@ -1,346 +0,0 @@ -//! linux_raw syscalls supporting `rustix::runtime`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -#[cfg(target_arch = "x86")] -use crate::backend::conv::by_mut; -#[cfg(target_arch = "x86_64")] -use crate::backend::conv::c_uint; -use crate::backend::conv::{ - by_ref, c_int, opt_ref, ret, ret_c_int, ret_c_int_infallible, ret_error, ret_infallible, - ret_void_star, size_of, zero, -}; -#[cfg(feature = "fs")] -use crate::fd::BorrowedFd; -use crate::ffi::CStr; -#[cfg(feature = "fs")] -use crate::fs::AtFlags; -use crate::io; -use crate::pid::{Pid, RawPid}; -use crate::runtime::{Fork, How, KernelSigSet, KernelSigaction, Siginfo, Stack}; -use crate::signal::Signal; -use crate::timespec::Timespec; -use core::ffi::c_void; -use core::mem::MaybeUninit; -#[cfg(all(target_pointer_width = "32", not(feature = "linux_5_1")))] -use linux_raw_sys::general::__kernel_old_timespec; -#[cfg(target_arch = "x86_64")] -use linux_raw_sys::general::ARCH_SET_FS; - -#[inline] -pub(crate) unsafe fn kernel_fork() -> io::Result<Fork> { - let mut child_pid = MaybeUninit::<RawPid>::uninit(); - - // Unix `fork` only returns the child PID in the parent; we'd like it in - // the child too, so set `CLONE_CHILD_SETTID` and pass in the address of a - // memory location to store it to in the child. - // - // Architectures differ on the order of the parameters. - #[cfg(target_arch = "x86_64")] - let pid = ret_c_int(syscall!( - __NR_clone, - c_int(c::SIGCHLD | c::CLONE_CHILD_SETTID), - zero(), - zero(), - &mut child_pid, - zero() - ))?; - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86" - ))] - let pid = ret_c_int(syscall!( - __NR_clone, - c_int(c::SIGCHLD | c::CLONE_CHILD_SETTID), - zero(), - zero(), - zero(), - &mut child_pid - ))?; - - Ok(if let Some(pid) = Pid::from_raw(pid) { - Fork::ParentOf(pid) - } else { - Fork::Child(Pid::from_raw_unchecked(child_pid.assume_init())) - }) -} - -#[cfg(feature = "fs")] -pub(crate) unsafe fn execveat( - dirfd: BorrowedFd<'_>, - path: &CStr, - args: *const *const u8, - env_vars: *const *const u8, - flags: AtFlags, -) -> io::Errno { - ret_error(syscall_readonly!( - __NR_execveat, - dirfd, - path, - args, - env_vars, - flags - )) -} - -pub(crate) unsafe fn execve( - path: &CStr, - args: *const *const u8, - env_vars: *const *const u8, -) -> io::Errno { - ret_error(syscall_readonly!(__NR_execve, path, args, env_vars)) -} - -pub(crate) mod tls { - use super::*; - #[cfg(target_arch = "x86")] - use crate::backend::runtime::tls::UserDesc; - - #[cfg(target_arch = "x86")] - #[inline] - pub(crate) unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { - ret(syscall!(__NR_set_thread_area, by_mut(u_info))) - } - - #[cfg(target_arch = "arm")] - #[inline] - pub(crate) unsafe fn arm_set_tls(data: *mut c::c_void) -> io::Result<()> { - ret(syscall_readonly!(__ARM_NR_set_tls, data)) - } - - #[cfg(target_arch = "x86_64")] - #[inline] - pub(crate) unsafe fn set_fs(data: *mut c::c_void) { - ret_infallible(syscall_readonly!( - __NR_arch_prctl, - c_uint(ARCH_SET_FS), - data, - zero(), - zero(), - zero() - )) - } - - #[inline] - pub(crate) unsafe fn set_tid_address(data: *mut c::c_void) -> Pid { - let tid: i32 = ret_c_int_infallible(syscall_readonly!(__NR_set_tid_address, data)); - Pid::from_raw_unchecked(tid) - } - - #[inline] - pub(crate) fn exit_thread(code: c::c_int) -> ! { - unsafe { syscall_noreturn!(__NR_exit, c_int(code)) } - } -} - -#[inline] -pub(crate) unsafe fn kernel_sigaction( - signal: Signal, - new: Option<KernelSigaction>, -) -> io::Result<KernelSigaction> { - let mut old = MaybeUninit::<KernelSigaction>::uninit(); - let new = opt_ref(new.as_ref()); - ret(syscall!( - __NR_rt_sigaction, - signal, - new, - &mut old, - size_of::<KernelSigSet, _>() - ))?; - Ok(old.assume_init()) -} - -#[inline] -pub(crate) unsafe fn kernel_sigaltstack(new: Option<Stack>) -> io::Result<Stack> { - let mut old = MaybeUninit::<Stack>::uninit(); - let new = opt_ref(new.as_ref()); - ret(syscall!(__NR_sigaltstack, new, &mut old))?; - Ok(old.assume_init()) -} - -#[inline] -pub(crate) unsafe fn tkill(tid: Pid, sig: Signal) -> io::Result<()> { - ret(syscall_readonly!(__NR_tkill, tid, sig)) -} - -#[inline] -pub(crate) unsafe fn kernel_sigprocmask( - how: How, - new: Option<&KernelSigSet>, -) -> io::Result<KernelSigSet> { - let mut old = MaybeUninit::<KernelSigSet>::uninit(); - let new = opt_ref(new); - ret(syscall!( - __NR_rt_sigprocmask, - how, - new, - &mut old, - size_of::<KernelSigSet, _>() - ))?; - Ok(old.assume_init()) -} - -#[inline] -pub(crate) fn kernel_sigpending() -> KernelSigSet { - let mut pending = MaybeUninit::<KernelSigSet>::uninit(); - unsafe { - ret_infallible(syscall!( - __NR_rt_sigpending, - &mut pending, - size_of::<KernelSigSet, _>() - )); - pending.assume_init() - } -} - -#[inline] -pub(crate) fn kernel_sigsuspend(set: &KernelSigSet) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_rt_sigsuspend, - by_ref(set), - size_of::<KernelSigSet, _>() - )) - } -} - -#[inline] -pub(crate) unsafe fn kernel_sigwait(set: &KernelSigSet) -> io::Result<Signal> { - Ok(Signal::from_raw_unchecked(ret_c_int(syscall_readonly!( - __NR_rt_sigtimedwait, - by_ref(set), - zero(), - zero(), - size_of::<KernelSigSet, _>() - ))?)) -} - -#[inline] -pub(crate) unsafe fn kernel_sigwaitinfo(set: &KernelSigSet) -> io::Result<Siginfo> { - let mut info = MaybeUninit::<Siginfo>::uninit(); - let _signum = ret_c_int(syscall!( - __NR_rt_sigtimedwait, - by_ref(set), - &mut info, - zero(), - size_of::<KernelSigSet, _>() - ))?; - Ok(info.assume_init()) -} - -#[inline] -pub(crate) unsafe fn kernel_sigtimedwait( - set: &KernelSigSet, - timeout: Option<&Timespec>, -) -> io::Result<Siginfo> { - let mut info = MaybeUninit::<Siginfo>::uninit(); - - // `rt_sigtimedwait_time64` was introduced in Linux 5.1. The old - // `rt_sigtimedwait` syscall is not y2038-compatible on 32-bit - // architectures. - #[cfg(target_pointer_width = "32")] - { - // If we don't have Linux 5.1, and the timeout fits in a - // `__kernel_old_timespec`, use plain `rt_sigtimedwait`. - // - // We do this unconditionally, rather than trying - // `rt_sigtimedwait_time64` and falling back on `Errno::NOSYS`, because - // seccomp configurations will sometimes abort the process on syscalls - // they don't recognize. - #[cfg(not(feature = "linux_5_1"))] - { - // If we don't have a timeout, or if we can convert the timeout to - // a `__kernel_old_timespec`, the use `__NR_futex`. - fn convert(timeout: &Timespec) -> Option<__kernel_old_timespec> { - Some(__kernel_old_timespec { - tv_sec: timeout.tv_sec.try_into().ok()?, - tv_nsec: timeout.tv_nsec.try_into().ok()?, - }) - } - let old_timeout = if let Some(timeout) = timeout { - match convert(timeout) { - // Could not convert timeout. - None => None, - // Could convert timeout. Ok! - Some(old_timeout) => Some(Some(old_timeout)), - } - } else { - // No timeout. Ok! - Some(None) - }; - if let Some(old_timeout) = old_timeout { - return ret_c_int(syscall!( - __NR_rt_sigtimedwait, - by_ref(set), - &mut info, - opt_ref(old_timeout.as_ref()), - size_of::<KernelSigSet, _>() - )) - .map(|sig| { - debug_assert_eq!( - sig, - info.assume_init_ref() - .__bindgen_anon_1 - .__bindgen_anon_1 - .si_signo - ); - info.assume_init() - }); - } - } - - ret_c_int(syscall!( - __NR_rt_sigtimedwait_time64, - by_ref(set), - &mut info, - opt_ref(timeout), - size_of::<KernelSigSet, _>() - )) - .map(|sig| { - debug_assert_eq!( - sig, - info.assume_init_ref() - .__bindgen_anon_1 - .__bindgen_anon_1 - .si_signo - ); - info.assume_init() - }) - } - - #[cfg(target_pointer_width = "64")] - { - let _signum = ret_c_int(syscall!( - __NR_rt_sigtimedwait, - by_ref(set), - &mut info, - opt_ref(timeout), - size_of::<KernelSigSet, _>() - ))?; - Ok(info.assume_init()) - } -} - -#[inline] -pub(crate) fn exit_group(code: c::c_int) -> ! { - unsafe { syscall_noreturn!(__NR_exit_group, c_int(code)) } -} - -#[inline] -pub(crate) unsafe fn kernel_brk(addr: *mut c::c_void) -> io::Result<*mut c_void> { - // This is non-`readonly`, to prevent loads from being reordered past it. - ret_void_star(syscall!(__NR_brk, addr)) -} diff --git a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs deleted file mode 100644 index bc04a706..00000000 --- a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! TLS utilities. - -/// For use with [`set_thread_area`]. -/// -/// [`set_thread_area`]: crate::runtime::set_thread_area -#[cfg(target_arch = "x86")] -pub type UserDesc = linux_raw_sys::general::user_desc; diff --git a/vendor/rustix/src/backend/linux_raw/shm/mod.rs b/vendor/rustix/src/backend/linux_raw/shm/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/shm/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs deleted file mode 100644 index 77b96d9e..00000000 --- a/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::ffi::CStr; - -use crate::backend::fs::syscalls::{open, unlink}; -use crate::backend::fs::types::{Mode, OFlags}; -use crate::fd::OwnedFd; -use crate::{io, shm}; - -const NAME_MAX: usize = 255; -const SHM_DIR: &[u8] = b"/dev/shm/"; - -fn get_shm_name(name: &CStr) -> io::Result<([u8; NAME_MAX + SHM_DIR.len() + 1], usize)> { - let name = name.to_bytes(); - - if name.len() > NAME_MAX { - return Err(io::Errno::NAMETOOLONG); - } - - let num_slashes = name.iter().take_while(|x| **x == b'/').count(); - let after_slashes = &name[num_slashes..]; - if after_slashes.is_empty() - || after_slashes == b"." - || after_slashes == b".." - || after_slashes.contains(&b'/') - { - return Err(io::Errno::INVAL); - } - - let mut path = [0; NAME_MAX + SHM_DIR.len() + 1]; - path[..SHM_DIR.len()].copy_from_slice(SHM_DIR); - path[SHM_DIR.len()..SHM_DIR.len() + name.len()].copy_from_slice(name); - Ok((path, SHM_DIR.len() + name.len() + 1)) -} - -pub(crate) fn shm_open(name: &CStr, oflags: shm::OFlags, mode: Mode) -> io::Result<OwnedFd> { - let (path, len) = get_shm_name(name)?; - open( - CStr::from_bytes_with_nul(&path[..len]).unwrap(), - OFlags::from_bits(oflags.bits()).unwrap() | OFlags::CLOEXEC, - mode, - ) -} - -pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> { - let (path, len) = get_shm_name(name)?; - unlink(CStr::from_bytes_with_nul(&path[..len]).unwrap()) -} diff --git a/vendor/rustix/src/backend/linux_raw/shm/types.rs b/vendor/rustix/src/backend/linux_raw/shm/types.rs deleted file mode 100644 index e1e8fc02..00000000 --- a/vendor/rustix/src/backend/linux_raw/shm/types.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `O_*` constants for use with [`shm::open`]. - /// - /// [`shm::open`]: crate:shm::open - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ShmOFlags: ffi::c_uint { - /// `O_CREAT` - #[doc(alias = "CREAT")] - const CREATE = linux_raw_sys::general::O_CREAT; - - /// `O_EXCL` - const EXCL = linux_raw_sys::general::O_EXCL; - - /// `O_RDONLY` - const RDONLY = linux_raw_sys::general::O_RDONLY; - - /// `O_RDWR` - const RDWR = linux_raw_sys::general::O_RDWR; - - /// `O_TRUNC` - const TRUNC = linux_raw_sys::general::O_TRUNC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} diff --git a/vendor/rustix/src/backend/linux_raw/system/mod.rs b/vendor/rustix/src/backend/linux_raw/system/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/system/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs deleted file mode 100644 index bbee2680..00000000 --- a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs +++ /dev/null @@ -1,91 +0,0 @@ -//! linux_raw syscalls supporting `rustix::system`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use super::types::RawUname; -use crate::backend::c; -use crate::backend::conv::{c_int, ret, ret_infallible, slice}; -use crate::fd::BorrowedFd; -use crate::ffi::CStr; -use crate::io; -use crate::system::{RebootCommand, Sysinfo}; -use core::mem::MaybeUninit; - -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::<RawUname>::uninit(); - unsafe { - ret_infallible(syscall!(__NR_uname, &mut uname)); - uname.assume_init() - } -} - -#[inline] -pub(crate) fn sysinfo() -> Sysinfo { - let mut info = MaybeUninit::<Sysinfo>::uninit(); - unsafe { - ret_infallible(syscall!(__NR_sysinfo, &mut info)); - info.assume_init() - } -} - -#[inline] -pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { - let (ptr, len) = slice(name); - unsafe { ret(syscall_readonly!(__NR_sethostname, ptr, len)) } -} - -#[inline] -pub(crate) fn setdomainname(name: &[u8]) -> io::Result<()> { - let (ptr, len) = slice(name); - unsafe { ret(syscall_readonly!(__NR_setdomainname, ptr, len)) } -} - -#[inline] -pub(crate) fn reboot(cmd: RebootCommand) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_reboot, - c_int(c::LINUX_REBOOT_MAGIC1), - c_int(c::LINUX_REBOOT_MAGIC2), - c_int(cmd as i32) - )) - } -} - -#[inline] -pub(crate) fn init_module(image: &[u8], param_values: &CStr) -> io::Result<()> { - let (image, len) = slice(image); - unsafe { - ret(syscall_readonly!( - __NR_init_module, - image, - len, - param_values - )) - } -} - -#[inline] -pub(crate) fn finit_module( - fd: BorrowedFd<'_>, - param_values: &CStr, - flags: c::c_int, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_finit_module, - fd, - param_values, - c_int(flags) - )) - } -} - -#[inline] -pub(crate) fn delete_module(name: &CStr, flags: c::c_int) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_delete_module, name, c_int(flags))) } -} diff --git a/vendor/rustix/src/backend/linux_raw/system/types.rs b/vendor/rustix/src/backend/linux_raw/system/types.rs deleted file mode 100644 index 92cc5278..00000000 --- a/vendor/rustix/src/backend/linux_raw/system/types.rs +++ /dev/null @@ -1,39 +0,0 @@ -use crate::ffi; -use core::mem::size_of; - -/// `sysinfo` -#[non_exhaustive] -#[repr(C)] -pub struct Sysinfo { - /// Seconds since boot - pub uptime: ffi::c_long, - /// 1, 5, and 15 minute load averages - pub loads: [ffi::c_ulong; 3], - /// Total usable main memory size - pub totalram: ffi::c_ulong, - /// Available memory size - pub freeram: ffi::c_ulong, - /// Amount of shared memory - pub sharedram: ffi::c_ulong, - /// Memory used by buffers - pub bufferram: ffi::c_ulong, - /// Total swap space size - pub totalswap: ffi::c_ulong, - /// Swap space still available - pub freeswap: ffi::c_ulong, - /// Number of current processes - pub procs: ffi::c_ushort, - - pub(crate) pad: ffi::c_ushort, - - /// Total high memory size - pub totalhigh: ffi::c_ulong, - /// Available high memory size - pub freehigh: ffi::c_ulong, - /// Memory unit size in bytes - pub mem_unit: ffi::c_uint, - - pub(crate) f: [u8; 20 - 2 * size_of::<ffi::c_long>() - size_of::<ffi::c_int>()], -} - -pub(crate) type RawUname = linux_raw_sys::system::new_utsname; diff --git a/vendor/rustix/src/backend/linux_raw/termios/mod.rs b/vendor/rustix/src/backend/linux_raw/termios/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/termios/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs deleted file mode 100644 index 07c3a3d9..00000000 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ /dev/null @@ -1,425 +0,0 @@ -//! linux_raw syscalls supporting `rustix::termios`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -use crate::backend::conv::{by_ref, c_uint, ret}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -use crate::ffi::CStr; -use crate::io; -use crate::pid::Pid; -use crate::termios::{ - speed, Action, ControlModes, InputModes, LocalModes, OptionalActions, OutputModes, - QueueSelector, SpecialCodeIndex, Termios, Winsize, -}; -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -use crate::{fs::FileType, path::DecInt}; -use core::mem::MaybeUninit; - -#[inline] -pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result<Winsize> { - unsafe { - let mut result = MaybeUninit::<Winsize>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(c::TIOCGWINSZ), &mut result))?; - Ok(result.assume_init()) - } -} - -#[inline] -pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { - let mut result = MaybeUninit::<Termios>::uninit(); - - // SAFETY: This invokes the `TCGETS2` ioctl, which initializes the full - // `Termios` structure. - unsafe { - match ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS2), &mut result)) { - Ok(()) => Ok(result.assume_init()), - - // A `NOTTY` or `ACCESS` might mean the OS doesn't support - // `TCGETS2`, for example a seccomp environment or WSL that only - // knows about `TCGETS`. Fall back to the old `TCGETS`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - Err(io::Errno::NOTTY) | Err(io::Errno::ACCESS) => tcgetattr_fallback(fd), - - Err(err) => Err(err), - } - } -} - -/// Implement `tcgetattr` using the old `TCGETS` ioctl. -#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] -#[cold] -fn tcgetattr_fallback(fd: BorrowedFd<'_>) -> io::Result<Termios> { - use core::ptr::{addr_of, addr_of_mut}; - - let mut result = MaybeUninit::<Termios>::uninit(); - - // SAFETY: This invokes the `TCGETS` ioctl which initializes the `Termios` - // structure except for the `input_speed` and `output_speed` fields, which - // we manually initialize before forming a reference to the full `Termios`. - unsafe { - // Do the old `TCGETS` call. - ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS), &mut result))?; - - // Read the `control_modes` field without forming a reference to the - // `Termios` because it isn't fully initialized yet. - let ptr = result.as_mut_ptr(); - let control_modes = addr_of!((*ptr).control_modes).read(); - - // Infer the output speed and set `output_speed`. - let encoded_out = control_modes.bits() & c::CBAUD; - let output_speed = match speed::decode(encoded_out) { - Some(output_speed) => output_speed, - None => return Err(io::Errno::RANGE), - }; - addr_of_mut!((*ptr).output_speed).write(output_speed); - - // Infer the input speed and set `input_speed`. `B0` is a special-case - // that means the input speed is the same as the output speed. - let encoded_in = (control_modes.bits() & c::CIBAUD) >> c::IBSHIFT; - let input_speed = if encoded_in == c::B0 { - output_speed - } else { - match speed::decode(encoded_in) { - Some(input_speed) => input_speed, - None => return Err(io::Errno::RANGE), - } - }; - addr_of_mut!((*ptr).input_speed).write(input_speed); - - // Now all the fields are set. - Ok(result.assume_init()) - } -} - -#[inline] -pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { - unsafe { - let mut result = MaybeUninit::<c::pid_t>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(c::TIOCGPGRP), &mut result))?; - let pid = result.assume_init(); - - // This doesn't appear to be documented, but it appears `tcsetpgrp` can - // succeed and set the pid to 0 if we pass it a pseudo-terminal device - // fd. For now, fail with `OPNOTSUPP`. - if pid == 0 { - return Err(io::Errno::OPNOTSUPP); - } - - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[inline] -pub(crate) fn tcsetattr( - fd: BorrowedFd<'_>, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - // Translate from `optional_actions` into a `TCSETS2` ioctl request code. - // On MIPS, `optional_actions` has `TCSETS` added to it. - let request = c::TCSETS2 - + if cfg!(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) { - optional_actions as u32 - c::TCSETS - } else { - optional_actions as u32 - }; - - // SAFETY: This invokes the `TCSETS2` ioctl. - unsafe { - match ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(request), - by_ref(termios) - )) { - Ok(()) => Ok(()), - - // Similar to `tcgetattr_fallback`, `NOTTY` or `ACCESS` might mean - // the OS doesn't support `TCSETS2`. Fall back to the old `TCSETS`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - Err(io::Errno::NOTTY) | Err(io::Errno::ACCESS) => { - tcsetattr_fallback(fd, optional_actions, termios) - } - - Err(err) => Err(err), - } - } -} - -/// Implement `tcsetattr` using the old `TCSETS` ioctl. -#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] -#[cold] -fn tcsetattr_fallback( - fd: BorrowedFd<'_>, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - // `TCSETS` silently accepts `BOTHER` in `c_cflag` even though it doesn't - // read `c_ispeed`/`c_ospeed`, so detect this case and fail if needed. - let control_modes_bits = termios.control_modes.bits(); - let encoded_out = control_modes_bits & c::CBAUD; - let encoded_in = (control_modes_bits & c::CIBAUD) >> c::IBSHIFT; - if encoded_out == c::BOTHER || encoded_in == c::BOTHER { - return Err(io::Errno::RANGE); - } - - // Translate from `optional_actions` into a `TCSETS` ioctl request code. On - // MIPS, `optional_actions` already has `TCSETS` added to it. - let request = if cfg!(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) { - optional_actions as u32 - } else { - optional_actions as u32 + c::TCSETS - }; - - // SAFETY: This invokes the `TCSETS` ioctl. - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(request), - by_ref(termios) - )) - } -} - -#[inline] -pub(crate) fn tcsendbreak(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCSBRK), - c_uint(0) - )) - } -} - -#[inline] -pub(crate) fn tcdrain(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCSBRK), - c_uint(1) - )) - } -} - -#[inline] -pub(crate) fn tcflush(fd: BorrowedFd<'_>, queue_selector: QueueSelector) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCFLSH), - c_uint(queue_selector as u32) - )) - } -} - -#[inline] -pub(crate) fn tcflow(fd: BorrowedFd<'_>, action: Action) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCXONC), - c_uint(action as u32) - )) - } -} - -#[inline] -pub(crate) fn tcgetsid(fd: BorrowedFd<'_>) -> io::Result<Pid> { - unsafe { - let mut result = MaybeUninit::<c::pid_t>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(c::TIOCGSID), &mut result))?; - let pid = result.assume_init(); - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[inline] -pub(crate) fn tcsetwinsize(fd: BorrowedFd<'_>, winsize: Winsize) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TIOCSWINSZ), - by_ref(&winsize) - )) - } -} - -#[inline] -pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { - let raw_pid: c::c_int = pid.as_raw_nonzero().get(); - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TIOCSPGRP), - by_ref(&raw_pid) - )) - } -} - -/// A wrapper around a conceptual `cfsetspeed` which handles an arbitrary -/// integer speed value. -#[inline] -pub(crate) fn set_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - let encoded_speed = speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD | c::CIBAUD); - termios.control_modes |= - ControlModes::from_bits_retain(encoded_speed | (encoded_speed << c::IBSHIFT)); - - termios.input_speed = arbitrary_speed; - termios.output_speed = arbitrary_speed; - - Ok(()) -} - -/// A wrapper around a conceptual `cfsetospeed` which handles an arbitrary -/// integer speed value. -#[inline] -pub(crate) fn set_output_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - let encoded_speed = speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD); - termios.control_modes |= ControlModes::from_bits_retain(encoded_speed); - - termios.output_speed = arbitrary_speed; - - Ok(()) -} - -/// A wrapper around a conceptual `cfsetispeed` which handles an arbitrary -/// integer speed value. -#[inline] -pub(crate) fn set_input_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - let encoded_speed = speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CIBAUD); - termios.control_modes |= ControlModes::from_bits_retain(encoded_speed << c::IBSHIFT); - - termios.input_speed = arbitrary_speed; - - Ok(()) -} - -#[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - // From the Linux [`cfmakeraw` manual page]: - // - // [`cfmakeraw` manual page]: https://man7.org/linux/man-pages/man3/cfmakeraw.3.html - termios.input_modes -= InputModes::IGNBRK - | InputModes::BRKINT - | InputModes::PARMRK - | InputModes::ISTRIP - | InputModes::INLCR - | InputModes::IGNCR - | InputModes::ICRNL - | InputModes::IXON; - termios.output_modes -= OutputModes::OPOST; - termios.local_modes -= LocalModes::ECHO - | LocalModes::ECHONL - | LocalModes::ICANON - | LocalModes::ISIG - | LocalModes::IEXTEN; - termios.control_modes -= ControlModes::CSIZE | ControlModes::PARENB; - termios.control_modes |= ControlModes::CS8; - - // Musl and glibc also do these: - termios.special_codes[SpecialCodeIndex::VMIN] = 1; - termios.special_codes[SpecialCodeIndex::VTIME] = 0; -} - -#[inline] -pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { - // On error, Linux will return either `EINVAL` (2.6.32) or `ENOTTY` - // (otherwise), because we assume we're never passing an invalid - // file descriptor (which would get `EBADF`). Either way, an error - // means we don't have a tty. - tcgetwinsize(fd).is_ok() -} - -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> { - let fd_stat = crate::backend::fs::syscalls::fstat(fd)?; - - // Quick check: if `fd` isn't a character device, it's not a tty. - if FileType::from_raw_mode(fd_stat.st_mode) != FileType::CharacterDevice { - return Err(io::Errno::NOTTY); - } - - // Check that `fd` is really a tty. - tcgetwinsize(fd)?; - - // Create the "/proc/self/fd/<fd>" string. - let mut proc_self_fd_buf: [u8; 25] = *b"/proc/self/fd/\0\0\0\0\0\0\0\0\0\0\0"; - let dec_int = DecInt::from_fd(fd); - let bytes_with_nul = dec_int.as_bytes_with_nul(); - proc_self_fd_buf[b"/proc/self/fd/".len()..][..bytes_with_nul.len()] - .copy_from_slice(bytes_with_nul); - - // SAFETY: We just wrote a valid C String. - let proc_self_fd_path = unsafe { CStr::from_ptr(proc_self_fd_buf.as_ptr().cast()) }; - - let ptr = buf.as_mut_ptr(); - let len = { - // Gather the ttyname by reading the "fd" file inside `proc_self_fd`. - let (init, uninit) = crate::fs::readlinkat_raw(crate::fs::CWD, proc_self_fd_path, buf)?; - - // If the number of bytes is equal to the buffer length, truncation may - // have occurred. This check also ensures that we have enough space for - // adding a NUL terminator. - if uninit.is_empty() { - return Err(io::Errno::RANGE); - } - - // `readlinkat` returns the number of bytes placed in the buffer. - // NUL-terminate the string at that offset. - uninit[0].write(b'\0'); - - init.len() - }; - - // Check that the path we read refers to the same file as `fd`. - { - // SAFETY: We just wrote the NUL byte above. - let path = unsafe { CStr::from_ptr(ptr.cast()) }; - - let path_stat = crate::backend::fs::syscalls::stat(path)?; - if path_stat.st_dev != fd_stat.st_dev || path_stat.st_ino != fd_stat.st_ino { - return Err(io::Errno::NODEV); - } - } - - // Return the length, excluding the NUL terminator. - Ok(len) -} diff --git a/vendor/rustix/src/backend/linux_raw/termios/types.rs b/vendor/rustix/src/backend/linux_raw/termios/types.rs deleted file mode 100644 index a8aaee39..00000000 --- a/vendor/rustix/src/backend/linux_raw/termios/types.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Types for the `termios` module. - -#![allow(non_camel_case_types)] - -use crate::ffi; - -// We don't want to use `tcflag_t` directly so we don't expose linux_raw_sys -// publicly. It appears to be `c_ulong `on SPARC and `c_uint` everywhere else. - -#[cfg(target_arch = "sparc")] -pub type tcflag_t = ffi::c_ulong; -#[cfg(not(target_arch = "sparc"))] -pub type tcflag_t = ffi::c_uint; diff --git a/vendor/rustix/src/backend/linux_raw/thread/cpu_set.rs b/vendor/rustix/src/backend/linux_raw/thread/cpu_set.rs deleted file mode 100644 index 8c39d57c..00000000 --- a/vendor/rustix/src/backend/linux_raw/thread/cpu_set.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! Rust implementation of the `CPU_*` macro API. - -#![allow(non_snake_case)] - -use super::types::RawCpuSet; -use core::mem::{size_of, size_of_val}; - -#[inline] -pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { - let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); // 32, 64 etc - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - cpuset.bits[idx] |= 1 << offset -} - -#[inline] -pub(crate) fn CPU_ZERO(cpuset: &mut RawCpuSet) { - cpuset.bits.fill(0) -} - -#[inline] -pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { - let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); // 32, 64 etc - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - cpuset.bits[idx] &= !(1 << offset) -} - -#[inline] -pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { - let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - (cpuset.bits[idx] & (1 << offset)) != 0 -} - -#[inline] -pub(crate) fn CPU_COUNT_S(size_in_bytes: usize, cpuset: &RawCpuSet) -> u32 { - let size_of_mask = size_of_val(&cpuset.bits[0]); - let idx = size_in_bytes / size_of_mask; - cpuset.bits[..idx] - .iter() - .fold(0, |acc, i| acc + i.count_ones()) -} - -#[inline] -pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { - CPU_COUNT_S(size_of::<RawCpuSet>(), cpuset) -} - -#[inline] -pub(crate) fn CPU_EQUAL(this: &RawCpuSet, that: &RawCpuSet) -> bool { - this.bits == that.bits -} diff --git a/vendor/rustix/src/backend/linux_raw/thread/futex.rs b/vendor/rustix/src/backend/linux_raw/thread/futex.rs deleted file mode 100644 index 726cea11..00000000 --- a/vendor/rustix/src/backend/linux_raw/thread/futex.rs +++ /dev/null @@ -1,89 +0,0 @@ -bitflags::bitflags! { - /// `FUTEX_*` flags for use with the functions in [`futex`]. - /// - /// [`futex`]: mod@crate::thread::futex - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct Flags: u32 { - /// `FUTEX_PRIVATE_FLAG` - const PRIVATE = linux_raw_sys::general::FUTEX_PRIVATE_FLAG; - /// `FUTEX_CLOCK_REALTIME` - const CLOCK_REALTIME = linux_raw_sys::general::FUTEX_CLOCK_REALTIME; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `FUTEX2_*` flags for use with the functions in [`Waitv`]. - /// - /// Not to be confused with [`WaitvFlags`], which is passed as an argument - /// to the `waitv` function. - /// - /// [`Waitv`]: crate::thread::futex::Waitv - /// [`WaitvFlags`]: crate::thread::futex::WaitvFlags - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitFlags: u32 { - /// `FUTEX_U8` - const SIZE_U8 = linux_raw_sys::general::FUTEX2_SIZE_U8; - /// `FUTEX_U16` - const SIZE_U16 = linux_raw_sys::general::FUTEX2_SIZE_U16; - /// `FUTEX_U32` - const SIZE_U32 = linux_raw_sys::general::FUTEX2_SIZE_U32; - /// `FUTEX_U64` - const SIZE_U64 = linux_raw_sys::general::FUTEX2_SIZE_U64; - /// `FUTEX_SIZE_MASK` - const SIZE_MASK = linux_raw_sys::general::FUTEX2_SIZE_MASK; - - /// `FUTEX2_NUMA` - const NUMA = linux_raw_sys::general::FUTEX2_NUMA; - - /// `FUTEX2_PRIVATE` - const PRIVATE = linux_raw_sys::general::FUTEX2_PRIVATE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `FUTEX_*` operations for use with the futex syscall wrappers. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub(crate) enum Operation { - /// `FUTEX_WAIT` - Wait = linux_raw_sys::general::FUTEX_WAIT, - /// `FUTEX_WAKE` - Wake = linux_raw_sys::general::FUTEX_WAKE, - /// `FUTEX_FD` - Fd = linux_raw_sys::general::FUTEX_FD, - /// `FUTEX_REQUEUE` - Requeue = linux_raw_sys::general::FUTEX_REQUEUE, - /// `FUTEX_CMP_REQUEUE` - CmpRequeue = linux_raw_sys::general::FUTEX_CMP_REQUEUE, - /// `FUTEX_WAKE_OP` - WakeOp = linux_raw_sys::general::FUTEX_WAKE_OP, - /// `FUTEX_LOCK_PI` - LockPi = linux_raw_sys::general::FUTEX_LOCK_PI, - /// `FUTEX_UNLOCK_PI` - UnlockPi = linux_raw_sys::general::FUTEX_UNLOCK_PI, - /// `FUTEX_TRYLOCK_PI` - TrylockPi = linux_raw_sys::general::FUTEX_TRYLOCK_PI, - /// `FUTEX_WAIT_BITSET` - WaitBitset = linux_raw_sys::general::FUTEX_WAIT_BITSET, - /// `FUTEX_WAKE_BITSET` - WakeBitset = linux_raw_sys::general::FUTEX_WAKE_BITSET, - /// `FUTEX_WAIT_REQUEUE_PI` - WaitRequeuePi = linux_raw_sys::general::FUTEX_WAIT_REQUEUE_PI, - /// `FUTEX_CMP_REQUEUE_PI` - CmpRequeuePi = linux_raw_sys::general::FUTEX_CMP_REQUEUE_PI, - /// `FUTEX_LOCK_PI2` - LockPi2 = linux_raw_sys::general::FUTEX_LOCK_PI2, -} - -/// `FUTEX_WAITERS` -pub const WAITERS: u32 = linux_raw_sys::general::FUTEX_WAITERS; - -/// `FUTEX_OWNER_DIED` -pub const OWNER_DIED: u32 = linux_raw_sys::general::FUTEX_OWNER_DIED; diff --git a/vendor/rustix/src/backend/linux_raw/thread/mod.rs b/vendor/rustix/src/backend/linux_raw/thread/mod.rs deleted file mode 100644 index c1843edd..00000000 --- a/vendor/rustix/src/backend/linux_raw/thread/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub(crate) mod cpu_set; -pub(crate) mod futex; -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs b/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs deleted file mode 100644 index 352e0615..00000000 --- a/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs +++ /dev/null @@ -1,549 +0,0 @@ -//! linux_raw syscalls supporting `rustix::thread`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use super::types::RawCpuSet; -use crate::backend::c; -use crate::backend::conv::{ - by_mut, by_ref, c_int, c_uint, opt_ref, ret, ret_c_int, ret_c_int_infallible, ret_c_uint, - ret_usize, size_of, slice, slice_just_addr, slice_just_addr_mut, zero, -}; -use crate::fd::BorrowedFd; -use crate::io; -use crate::pid::Pid; -use crate::thread::{ - futex, ClockId, Cpuid, MembarrierCommand, MembarrierQuery, NanosleepRelativeResult, Timespec, -}; -use crate::utils::as_mut_ptr; -use core::mem::MaybeUninit; -use core::sync::atomic::AtomicU32; -#[cfg(target_pointer_width = "32")] -use linux_raw_sys::general::timespec as __kernel_old_timespec; -use linux_raw_sys::general::{membarrier_cmd, membarrier_cmd_flag, TIMER_ABSTIME}; - -#[inline] -pub(crate) fn clock_nanosleep_relative(id: ClockId, req: &Timespec) -> NanosleepRelativeResult { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut rem = MaybeUninit::<Timespec>::uninit(); - match ret(syscall!( - __NR_clock_nanosleep_time64, - id, - c_int(0), - by_ref(req), - &mut rem - )) - .or_else(|err| { - // See the comments in `clock_gettime_via_syscall` about emulation. - if err == io::Errno::NOSYS { - clock_nanosleep_relative_old(id, req, &mut rem) - } else { - Err(err) - } - }) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut rem = MaybeUninit::<Timespec>::uninit(); - match ret(syscall!( - __NR_clock_nanosleep, - id, - c_int(0), - by_ref(req), - &mut rem - )) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn clock_nanosleep_relative_old( - id: ClockId, - req: &Timespec, - rem: &mut MaybeUninit<Timespec>, -) -> io::Result<()> { - let old_req = __kernel_old_timespec { - tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - let mut old_rem = MaybeUninit::<__kernel_old_timespec>::uninit(); - ret(syscall!( - __NR_clock_nanosleep, - id, - c_int(0), - by_ref(&old_req), - &mut old_rem - ))?; - let old_rem = old_rem.assume_init(); - rem.write(Timespec { - tv_sec: old_rem.tv_sec.into(), - tv_nsec: old_rem.tv_nsec.into(), - }); - Ok(()) -} - -#[inline] -pub(crate) fn clock_nanosleep_absolute(id: ClockId, req: &Timespec) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_clock_nanosleep_time64, - id, - c_uint(TIMER_ABSTIME), - by_ref(req), - zero() - )) - .or_else(|err| { - // See the comments in `clock_gettime_via_syscall` about emulation. - if err == io::Errno::NOSYS { - clock_nanosleep_absolute_old(id, req) - } else { - Err(err) - } - }) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_clock_nanosleep, - id, - c_uint(TIMER_ABSTIME), - by_ref(req), - zero() - )) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn clock_nanosleep_absolute_old(id: ClockId, req: &Timespec) -> io::Result<()> { - let old_req = __kernel_old_timespec { - tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - ret(syscall_readonly!( - __NR_clock_nanosleep, - id, - c_int(0), - by_ref(&old_req), - zero() - )) -} - -#[inline] -pub(crate) fn nanosleep(req: &Timespec) -> NanosleepRelativeResult { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut rem = MaybeUninit::<Timespec>::uninit(); - match ret(syscall!( - __NR_clock_nanosleep_time64, - ClockId::Realtime, - c_int(0), - by_ref(req), - &mut rem - )) - .or_else(|err| { - // See the comments in `clock_gettime_via_syscall` about emulation. - if err == io::Errno::NOSYS { - nanosleep_old(req, &mut rem) - } else { - Err(err) - } - }) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut rem = MaybeUninit::<Timespec>::uninit(); - match ret(syscall!(__NR_nanosleep, by_ref(req), &mut rem)) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn nanosleep_old(req: &Timespec, rem: &mut MaybeUninit<Timespec>) -> io::Result<()> { - let old_req = __kernel_old_timespec { - tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - let mut old_rem = MaybeUninit::<__kernel_old_timespec>::uninit(); - ret(syscall!(__NR_nanosleep, by_ref(&old_req), &mut old_rem))?; - let old_rem = old_rem.assume_init(); - rem.write(Timespec { - tv_sec: old_rem.tv_sec.into(), - tv_nsec: old_rem.tv_nsec.into(), - }); - Ok(()) -} - -#[inline] -#[must_use] -pub(crate) fn gettid() -> Pid { - unsafe { - let tid = ret_c_int_infallible(syscall_readonly!(__NR_gettid)); - Pid::from_raw_unchecked(tid) - } -} - -/// # Safety -/// -/// The raw pointers must point to valid aligned memory. -#[inline] -pub(crate) unsafe fn futex_val2( - uaddr: *const AtomicU32, - op: super::futex::Operation, - flags: futex::Flags, - val: u32, - val2: u32, - uaddr2: *const AtomicU32, - val3: u32, -) -> io::Result<usize> { - // Pass `val2` in the least-significant bytes of the `timeout` argument. - // [“the kernel casts the timeout value first to unsigned long, then to - // uint32_t”], so we perform that exact conversion in reverse to create - // the pointer. - // - // [“the kernel casts the timeout value first to unsigned long, then to uint32_t”]: https://man7.org/linux/man-pages/man2/futex.2.html - let timeout = val2 as usize as *const Timespec; - - #[cfg(target_pointer_width = "32")] - { - // Linux 5.1 added `futex_time64`; if we have that, use it. We don't - // need it here, because `timeout` is just passing `val2` and not a - // real timeout, but it's nice to use `futex_time64` for consistency - // with the other futex calls that do. - #[cfg(feature = "linux_5_1")] - { - ret_usize(syscall!( - __NR_futex_time64, - uaddr, - (op, flags), - c_uint(val), - timeout, - uaddr2, - c_uint(val3) - )) - } - - // If we don't have Linux 5.1, use plain `futex`. - #[cfg(not(feature = "linux_5_1"))] - { - ret_usize(syscall!( - __NR_futex, - uaddr, - (op, flags), - c_uint(val), - timeout, - uaddr2, - c_uint(val3) - )) - } - } - #[cfg(target_pointer_width = "64")] - ret_usize(syscall!( - __NR_futex, - uaddr, - (op, flags), - c_uint(val), - timeout, - uaddr2, - c_uint(val3) - )) -} - -/// # Safety -/// -/// The raw pointers must point to valid aligned memory. -#[inline] -pub(crate) unsafe fn futex_timeout( - uaddr: *const AtomicU32, - op: super::futex::Operation, - flags: futex::Flags, - val: u32, - timeout: Option<&Timespec>, - uaddr2: *const AtomicU32, - val3: u32, -) -> io::Result<usize> { - #[cfg(target_pointer_width = "32")] - { - // If we don't have Linux 5.1, and the timeout fits in a - // `__kernel_old_timespec`, use plain `futex`. - // - // We do this unconditionally, rather than trying `futex_time64` and - // falling back on `Errno::NOSYS`, because seccomp configurations will - // sometimes abort the process on syscalls they don't recognize. - #[cfg(not(feature = "linux_5_1"))] - { - // If we don't have a timeout, or if we can convert the timeout to - // a `__kernel_old_timespec`, the use `__NR_futex`. - fn convert(timeout: &Timespec) -> Option<__kernel_old_timespec> { - Some(__kernel_old_timespec { - tv_sec: timeout.tv_sec.try_into().ok()?, - tv_nsec: timeout.tv_nsec.try_into().ok()?, - }) - } - let old_timeout = if let Some(timeout) = timeout { - match convert(timeout) { - // Could not convert timeout. - None => None, - // Could convert timeout. Ok! - Some(old_timeout) => Some(Some(old_timeout)), - } - } else { - // No timeout. Ok! - Some(None) - }; - if let Some(old_timeout) = old_timeout { - return ret_usize(syscall!( - __NR_futex, - uaddr, - (op, flags), - c_uint(val), - opt_ref(old_timeout.as_ref()), - uaddr2, - c_uint(val3) - )); - } - } - - // We either have Linux 5.1 or the timeout didn't fit in - // `__kernel_old_timespec` so `__NR_futex_time64` will either succeed - // or fail due to our having no other options. - ret_usize(syscall!( - __NR_futex_time64, - uaddr, - (op, flags), - c_uint(val), - opt_ref(timeout), - uaddr2, - c_uint(val3) - )) - } - #[cfg(target_pointer_width = "64")] - ret_usize(syscall!( - __NR_futex, - uaddr, - (op, flags), - c_uint(val), - opt_ref(timeout), - uaddr2, - c_uint(val3) - )) -} - -#[inline] -pub(crate) fn futex_waitv( - waiters: &[futex::Wait], - flags: futex::WaitvFlags, - timeout: Option<&Timespec>, - clockid: ClockId, -) -> io::Result<usize> { - let (waiters_addr, waiters_len) = slice(waiters); - unsafe { - ret_usize(syscall!( - __NR_futex_waitv, - waiters_addr, - waiters_len, - c_uint(flags.bits()), - opt_ref(timeout), - clockid - )) - } -} - -#[inline] -pub(crate) fn setns(fd: BorrowedFd<'_>, nstype: c::c_int) -> io::Result<c::c_int> { - unsafe { ret_c_int(syscall_readonly!(__NR_setns, fd, c_int(nstype))) } -} - -#[inline] -pub(crate) fn unshare(flags: crate::thread::UnshareFlags) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_unshare, flags)) } -} - -#[inline] -pub(crate) fn capget( - header: &mut linux_raw_sys::general::__user_cap_header_struct, - data: &mut [MaybeUninit<linux_raw_sys::general::__user_cap_data_struct>], -) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_capget, - by_mut(header), - slice_just_addr_mut(data) - )) - } -} - -#[inline] -pub(crate) fn capset( - header: &mut linux_raw_sys::general::__user_cap_header_struct, - data: &[linux_raw_sys::general::__user_cap_data_struct], -) -> io::Result<()> { - unsafe { ret(syscall!(__NR_capset, by_mut(header), slice_just_addr(data))) } -} - -#[inline] -pub(crate) fn setuid_thread(uid: crate::ugid::Uid) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_setuid, uid)) } -} - -#[inline] -pub(crate) fn setresuid_thread( - ruid: crate::ugid::Uid, - euid: crate::ugid::Uid, - suid: crate::ugid::Uid, -) -> io::Result<()> { - #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))] - unsafe { - ret(syscall_readonly!(__NR_setresuid32, ruid, euid, suid)) - } - #[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))] - unsafe { - ret(syscall_readonly!(__NR_setresuid, ruid, euid, suid)) - } -} - -#[inline] -pub(crate) fn setgid_thread(gid: crate::ugid::Gid) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_setgid, gid)) } -} - -#[inline] -pub(crate) fn setresgid_thread( - rgid: crate::ugid::Gid, - egid: crate::ugid::Gid, - sgid: crate::ugid::Gid, -) -> io::Result<()> { - #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))] - unsafe { - ret(syscall_readonly!(__NR_setresgid32, rgid, egid, sgid)) - } - #[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))] - unsafe { - ret(syscall_readonly!(__NR_setresgid, rgid, egid, sgid)) - } -} - -#[inline] -pub(crate) fn setgroups_thread(gids: &[crate::ugid::Gid]) -> io::Result<()> { - let (addr, len) = slice(gids); - unsafe { ret(syscall_readonly!(__NR_setgroups, len, addr)) } -} - -// `sched_getcpu` has special optimizations via the vDSO on some architectures. -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x" -))] -pub(crate) use crate::backend::vdso_wrappers::sched_getcpu; - -// `sched_getcpu` on platforms without a vDSO entry for it. -#[cfg(not(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x" -)))] -#[inline] -pub(crate) fn sched_getcpu() -> usize { - let mut cpu = MaybeUninit::<u32>::uninit(); - unsafe { - let r = ret(syscall!(__NR_getcpu, &mut cpu, zero(), zero())); - debug_assert!(r.is_ok()); - cpu.assume_init() as usize - } -} - -#[inline] -pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - // The raw Linux syscall returns the size (in bytes) of the `cpumask_t` - // data type that is used internally by the kernel to represent the CPU - // set bit mask. - let size = ret_usize(syscall!( - __NR_sched_getaffinity, - c_int(Pid::as_raw(pid)), - size_of::<RawCpuSet, _>(), - by_mut(&mut cpuset.bits) - ))?; - let bytes = as_mut_ptr(cpuset).cast::<u8>(); - let rest = bytes.wrapping_add(size); - // Zero every byte in the cpuset not set by the kernel. - rest.write_bytes(0, core::mem::size_of::<RawCpuSet>() - size); - Ok(()) - } -} - -#[inline] -pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_sched_setaffinity, - c_int(Pid::as_raw(pid)), - size_of::<RawCpuSet, _>(), - slice_just_addr(&cpuset.bits) - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - // See the documentation for [`crate::thread::sched_yield`] for why - // errors are ignored. - syscall_readonly!(__NR_sched_yield).decode_void(); - } -} - -#[inline] -pub(crate) fn membarrier_query() -> MembarrierQuery { - unsafe { - match ret_c_uint(syscall!( - __NR_membarrier, - c_int(membarrier_cmd::MEMBARRIER_CMD_QUERY as _), - c_uint(0) - )) { - Ok(query) => MembarrierQuery::from_bits_retain(query), - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[inline] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { ret(syscall!(__NR_membarrier, cmd, c_uint(0))) } -} - -#[inline] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_membarrier, - cmd, - c_uint(membarrier_cmd_flag::MEMBARRIER_CMD_FLAG_CPU as _), - cpu - )) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/thread/types.rs b/vendor/rustix/src/backend/linux_raw/thread/types.rs deleted file mode 100644 index be92235e..00000000 --- a/vendor/rustix/src/backend/linux_raw/thread/types.rs +++ /dev/null @@ -1,62 +0,0 @@ -use linux_raw_sys::general::membarrier_cmd; - -/// A command for use with [`membarrier`] and [`membarrier_cpu`]. -/// -/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. -/// -/// [`membarrier`]: crate::thread::membarrier -/// [`membarrier_cpu`]: crate::thread::membarrier_cpu -/// [`membarrier_query`]: crate::thread::membarrier_query -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[repr(u32)] -#[non_exhaustive] -pub enum MembarrierCommand { - /// `MEMBARRIER_CMD_GLOBAL` - #[doc(alias = "Shared")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - Global = membarrier_cmd::MEMBARRIER_CMD_GLOBAL as _, - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - GlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_GLOBAL_EXPEDITED as _, - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - RegisterGlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - PrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - RegisterPrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - PrivateExpeditedSyncCore = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - RegisterPrivateExpeditedSyncCore = - membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - PrivateExpeditedRseq = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - RegisterPrivateExpeditedRseq = - membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as _, -} - -/// A CPU identifier as a raw integer. -pub type RawCpuid = u32; - -#[repr(transparent)] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub(crate) struct RawCpuSet { - #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] - pub(crate) bits: [u32; 32], - #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] - pub(crate) bits: [u64; 16], -} - -#[inline] -pub(crate) fn raw_cpu_set_new() -> RawCpuSet { - #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] - { - RawCpuSet { bits: [0; 32] } - } - #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] - { - RawCpuSet { bits: [0; 16] } - } -} - -pub(crate) const CPU_SETSIZE: usize = 8 * core::mem::size_of::<RawCpuSet>(); diff --git a/vendor/rustix/src/backend/linux_raw/time/mod.rs b/vendor/rustix/src/backend/linux_raw/time/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/time/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs deleted file mode 100644 index 58a969d1..00000000 --- a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs +++ /dev/null @@ -1,238 +0,0 @@ -//! linux_raw syscalls supporting `rustix::time`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::conv::{by_ref, ret, ret_infallible, ret_owned_fd}; -use crate::clockid::ClockId; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; -use crate::timespec::Timespec; -use core::mem::MaybeUninit; -#[cfg(target_pointer_width = "32")] -use linux_raw_sys::general::itimerspec as __kernel_old_itimerspec; -#[cfg(target_pointer_width = "32")] -use linux_raw_sys::general::timespec as __kernel_old_timespec; - -// `clock_gettime` has special optimizations via the vDSO. -pub(crate) use crate::backend::vdso_wrappers::{clock_gettime, clock_gettime_dynamic}; - -#[inline] -#[must_use] -pub(crate) fn clock_getres(id: ClockId) -> Timespec { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::<Timespec>::uninit(); - if let Err(err) = ret(syscall!(__NR_clock_getres_time64, id, &mut result)) { - // See the comments in `clock_gettime_via_syscall` about emulation. - debug_assert_eq!(err, io::Errno::NOSYS); - clock_getres_old(id, &mut result); - } - result.assume_init() - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut result = MaybeUninit::<Timespec>::uninit(); - ret_infallible(syscall!(__NR_clock_getres, id, &mut result)); - result.assume_init() - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn clock_getres_old(id: ClockId, result: &mut MaybeUninit<Timespec>) { - let mut old_result = MaybeUninit::<__kernel_old_timespec>::uninit(); - ret_infallible(syscall!(__NR_clock_getres, id, &mut old_result)); - let old_result = old_result.assume_init(); - result.write(Timespec { - tv_sec: old_result.tv_sec.into(), - tv_nsec: old_result.tv_nsec.into(), - }); -} - -#[inline] -pub(crate) fn clock_settime(id: ClockId, timespec: Timespec) -> io::Result<()> { - // `clock_settime64` was introduced in Linux 5.1. The old `clock_settime` - // syscall is not y2038-compatible on 32-bit architectures. - #[cfg(target_pointer_width = "32")] - unsafe { - match ret(syscall_readonly!( - __NR_clock_settime64, - id, - by_ref(×pec) - )) { - Err(io::Errno::NOSYS) => clock_settime_old(id, timespec), - otherwise => otherwise, - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!(__NR_clock_settime, id, by_ref(×pec))) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn clock_settime_old(id: ClockId, timespec: Timespec) -> io::Result<()> { - let old_timespec = __kernel_old_timespec { - tv_sec: timespec - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: timespec.tv_nsec as _, - }; - ret(syscall_readonly!( - __NR_clock_settime, - id, - by_ref(&old_timespec) - )) -} - -#[inline] -pub(crate) fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_timerfd_create, clockid, flags)) } -} - -#[inline] -pub(crate) fn timerfd_settime( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result<Itimerspec> { - let mut result = MaybeUninit::<Itimerspec>::uninit(); - - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall!( - __NR_timerfd_settime, - fd, - flags, - by_ref(new_value), - &mut result - ))?; - Ok(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_timerfd_settime64, - fd, - flags, - by_ref(new_value), - &mut result - )) - .or_else(|err| { - // See the comments in `clock_gettime_via_syscall` about emulation. - if err == io::Errno::NOSYS { - timerfd_settime_old(fd, flags, new_value, &mut result) - } else { - Err(err) - } - })?; - Ok(result.assume_init()) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn timerfd_settime_old( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, - result: &mut MaybeUninit<Itimerspec>, -) -> io::Result<()> { - let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); - - // Convert `new_value` to the old `__kernel_old_itimerspec` format. - let old_new_value = __kernel_old_itimerspec { - it_interval: __kernel_old_timespec { - tv_sec: new_value - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_interval - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - it_value: __kernel_old_timespec { - tv_sec: new_value - .it_value - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_value - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - }; - ret(syscall!( - __NR_timerfd_settime, - fd, - flags, - by_ref(&old_new_value), - &mut old_result - ))?; - let old_result = old_result.assume_init(); - result.write(Itimerspec { - it_interval: Timespec { - tv_sec: old_result.it_interval.tv_sec.into(), - tv_nsec: old_result.it_interval.tv_nsec.into(), - }, - it_value: Timespec { - tv_sec: old_result.it_value.tv_sec.into(), - tv_nsec: old_result.it_value.tv_nsec.into(), - }, - }); - Ok(()) -} - -#[inline] -pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { - let mut result = MaybeUninit::<Itimerspec>::uninit(); - - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall!(__NR_timerfd_gettime, fd, &mut result))?; - Ok(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!(__NR_timerfd_gettime64, fd, &mut result)).or_else(|err| { - // See the comments in `clock_gettime_via_syscall` about emulation. - if err == io::Errno::NOSYS { - timerfd_gettime_old(fd, &mut result) - } else { - Err(err) - } - })?; - Ok(result.assume_init()) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn timerfd_gettime_old( - fd: BorrowedFd<'_>, - result: &mut MaybeUninit<Itimerspec>, -) -> io::Result<()> { - let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); - ret(syscall!(__NR_timerfd_gettime, fd, &mut old_result))?; - let old_result = old_result.assume_init(); - result.write(Itimerspec { - it_interval: Timespec { - tv_sec: old_result.it_interval.tv_sec.into(), - tv_nsec: old_result.it_interval.tv_nsec.into(), - }, - it_value: Timespec { - tv_sec: old_result.it_value.tv_sec.into(), - tv_nsec: old_result.it_value.tv_nsec.into(), - }, - }); - Ok(()) -} diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs deleted file mode 100644 index ec6c91f5..00000000 --- a/vendor/rustix/src/backend/linux_raw/time/types.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::ffi; -use bitflags::bitflags; - -bitflags! { - /// `TFD_*` flags for use with [`timerfd_create`]. - /// - /// [`timerfd_create`]: crate::time::timerfd_create - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct TimerfdFlags: ffi::c_uint { - /// `TFD_NONBLOCK` - #[doc(alias = "TFD_NONBLOCK")] - const NONBLOCK = linux_raw_sys::general::TFD_NONBLOCK; - - /// `TFD_CLOEXEC` - #[doc(alias = "TFD_CLOEXEC")] - const CLOEXEC = linux_raw_sys::general::TFD_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. - /// - /// [`timerfd_settime`]: crate::time::timerfd_settime - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct TimerfdTimerFlags: ffi::c_uint { - /// `TFD_TIMER_ABSTIME` - #[doc(alias = "TFD_TIMER_ABSTIME")] - const ABSTIME = linux_raw_sys::general::TFD_TIMER_ABSTIME; - - /// `TFD_TIMER_CANCEL_ON_SET` - #[doc(alias = "TFD_TIMER_CANCEL_ON_SET")] - const CANCEL_ON_SET = linux_raw_sys::general::TFD_TIMER_CANCEL_ON_SET; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `CLOCK_*` constants for use with [`timerfd_create`]. -/// -/// [`timerfd_create`]: crate::time::timerfd_create -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum TimerfdClockId { - /// `CLOCK_REALTIME`—A clock that tells the “real” time. - /// - /// This is a clock that tells the amount of time elapsed since the Unix - /// epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so it is - /// not monotonic. Successive reads may see decreasing times, so it isn't - /// reliable for measuring durations. - #[doc(alias = "CLOCK_REALTIME")] - Realtime = linux_raw_sys::general::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. - /// - /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so - /// individual times aren't meaningful. However, since it isn't settable, - /// it is reliable for measuring durations. - /// - /// This clock does not advance while the system is suspended; see - /// `Boottime` for a clock that does. - #[doc(alias = "CLOCK_MONOTONIC")] - Monotonic = linux_raw_sys::general::CLOCK_MONOTONIC, - - /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. - /// - /// This clock is similar to `Monotonic`, but does advance while the system - /// is suspended. - #[doc(alias = "CLOCK_BOOTTIME")] - Boottime = linux_raw_sys::general::CLOCK_BOOTTIME, - - /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. - /// - /// This clock is like `Realtime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - #[doc(alias = "CLOCK_REALTIME_ALARM")] - RealtimeAlarm = linux_raw_sys::general::CLOCK_REALTIME_ALARM, - - /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. - /// - /// This clock is like `Boottime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - #[doc(alias = "CLOCK_BOOTTIME_ALARM")] - BoottimeAlarm = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM, -} diff --git a/vendor/rustix/src/backend/linux_raw/ugid/mod.rs b/vendor/rustix/src/backend/linux_raw/ugid/mod.rs deleted file mode 100644 index ef944f04..00000000 --- a/vendor/rustix/src/backend/linux_raw/ugid/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/ugid/syscalls.rs b/vendor/rustix/src/backend/linux_raw/ugid/syscalls.rs deleted file mode 100644 index 4aac5f24..00000000 --- a/vendor/rustix/src/backend/linux_raw/ugid/syscalls.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! linux_raw syscalls for UIDs and GIDs -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] - -use crate::backend::c; -use crate::backend::conv::ret_usize_infallible; -use crate::ugid::{Gid, Uid}; - -#[inline] -#[must_use] -pub(crate) fn getuid() -> Uid { - #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_getuid32)) as c::uid_t; - Uid::from_raw(uid) - } - #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_getuid)) as c::uid_t; - Uid::from_raw(uid) - } -} - -#[inline] -#[must_use] -pub(crate) fn geteuid() -> Uid { - #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_geteuid32)) as c::uid_t; - Uid::from_raw(uid) - } - #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_geteuid)) as c::uid_t; - Uid::from_raw(uid) - } -} - -#[inline] -#[must_use] -pub(crate) fn getgid() -> Gid { - #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getgid32)) as c::gid_t; - Gid::from_raw(gid) - } - #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getgid)) as c::gid_t; - Gid::from_raw(gid) - } -} - -#[inline] -#[must_use] -pub(crate) fn getegid() -> Gid { - #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getegid32)) as c::gid_t; - Gid::from_raw(gid) - } - #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getegid)) as c::gid_t; - Gid::from_raw(gid) - } -} diff --git a/vendor/rustix/src/backend/linux_raw/vdso.rs b/vendor/rustix/src/backend/linux_raw/vdso.rs deleted file mode 100644 index 4fa1d1cc..00000000 --- a/vendor/rustix/src/backend/linux_raw/vdso.rs +++ /dev/null @@ -1,545 +0,0 @@ -//! Parse the Linux vDSO. -//! -//! The following code is transliterated from -//! tools/testing/selftests/vDSO/parse_vdso.c in Linux 6.13, which is licensed -//! with Creative Commons Zero License, version 1.0, -//! available at <https://creativecommons.org/publicdomain/zero/1.0/legalcode> -//! -//! It also incorporates the patch at: -//! <https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git/commit/tools/testing/selftests/vDSO?h=next&id=01587d80b04f29747b6fd6d766c3bfa632f14eb0>, -//! with changes to fix the pointer arithmetic on s390x. -//! -//! # Safety -//! -//! Parsing the vDSO involves a lot of raw pointer manipulation. This -//! implementation follows Linux's reference implementation, and adds several -//! additional safety checks. -#![allow(unsafe_code)] - -use super::c; -use crate::ffi::CStr; -use crate::utils::check_raw_pointer; -use core::ffi::c_void; -use core::mem::size_of; -use core::ptr::{null, null_mut}; -use linux_raw_sys::elf::*; - -#[cfg(target_arch = "s390x")] -type ElfHashEntry = u64; -#[cfg(not(target_arch = "s390x"))] -type ElfHashEntry = u32; - -pub(super) struct Vdso { - // Load information - load_addr: *const Elf_Ehdr, - load_end: *const c_void, // the end of the `PT_LOAD` segment - pv_offset: usize, // recorded paddr - recorded vaddr - - // Symbol table - symtab: *const Elf_Sym, - symstrings: *const u8, - gnu_hash: *const u32, - bucket: *const ElfHashEntry, - chain: *const ElfHashEntry, - nbucket: ElfHashEntry, - //nchain: ElfHashEntry, - - // Version table - versym: *const u16, - verdef: *const Elf_Verdef, -} - -/// Straight from the ELF specification…and then tweaked slightly, in order to -/// avoid a few clang warnings. -/// (And then translated to Rust). -fn elf_hash(name: &CStr) -> u32 { - let mut h: u32 = 0; - for b in name.to_bytes() { - h = (h << 4).wrapping_add(u32::from(*b)); - let g = h & 0xf000_0000; - if g != 0 { - h ^= g >> 24; - } - h &= !g; - } - h -} - -fn gnu_hash(name: &CStr) -> u32 { - let mut h: u32 = 5381; - for s in name.to_bytes() { - h = h - .wrapping_add(h.wrapping_mul(32)) - .wrapping_add(u32::from(*s)); - } - h -} - -/// Create a `Vdso` value by parsing the vDSO at the `sysinfo_ehdr` address. -fn init_from_sysinfo_ehdr() -> Option<Vdso> { - // SAFETY: The auxv initialization code does extensive checks to ensure - // that the value we get really is an `AT_SYSINFO_EHDR` value from the - // kernel. - unsafe { - let hdr = super::param::auxv::sysinfo_ehdr(); - - // If the platform doesn't provide a `AT_SYSINFO_EHDR`, we can't locate - // the vDSO. - if hdr.is_null() { - return None; - } - - let mut vdso = Vdso { - load_addr: hdr, - load_end: hdr.cast(), - pv_offset: 0, - symtab: null(), - symstrings: null(), - gnu_hash: null(), - bucket: null(), - chain: null(), - nbucket: 0, - //nchain: 0, - versym: null(), - verdef: null(), - }; - - let hdr = &*hdr; - let pt = check_raw_pointer::<Elf_Phdr>(vdso.base_plus(hdr.e_phoff)? as *mut _)?.as_ptr(); - let mut dyn_: *const Elf_Dyn = null(); - let mut num_dyn = 0; - - // We need two things from the segment table: the load offset - // and the dynamic table. - let mut found_vaddr = false; - for i in 0..hdr.e_phnum { - let phdr = &*pt.add(i as usize); - if phdr.p_type == PT_LOAD && !found_vaddr { - // The segment should be readable and executable, because it - // contains the symbol table and the function bodies. - if phdr.p_flags & (PF_R | PF_X) != (PF_R | PF_X) { - return None; - } - found_vaddr = true; - vdso.load_end = vdso.base_plus(phdr.p_offset.checked_add(phdr.p_memsz)?)?; - vdso.pv_offset = phdr.p_offset.wrapping_sub(phdr.p_vaddr); - } else if phdr.p_type == PT_DYNAMIC { - // If `p_offset` is zero, it's more likely that we're looking - // at memory that has been zeroed than that the kernel has - // somehow aliased the `Ehdr` and the `Elf_Dyn` array. - if phdr.p_offset < size_of::<Elf_Ehdr>() { - return None; - } - - dyn_ = check_raw_pointer::<Elf_Dyn>(vdso.base_plus(phdr.p_offset)? as *mut _)? - .as_ptr(); - num_dyn = phdr.p_memsz / size_of::<Elf_Dyn>(); - } else if phdr.p_type == PT_INTERP || phdr.p_type == PT_GNU_RELRO { - // Don't trust any ELF image that has an “interpreter” or - // that uses RELRO, which is likely to be a user ELF image - // rather and not the kernel vDSO. - return None; - } - } - - if !found_vaddr || dyn_.is_null() { - return None; // Failed - } - - // Fish out the useful bits of the dynamic table. - let mut hash: *const ElfHashEntry = null(); - vdso.symstrings = null(); - vdso.symtab = null(); - vdso.versym = null(); - vdso.verdef = null(); - let mut i = 0; - loop { - if i == num_dyn { - return None; - } - let d = &*dyn_.add(i); - match d.d_tag { - DT_STRTAB => { - vdso.symstrings = - check_raw_pointer::<u8>(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? - .as_ptr(); - } - DT_SYMTAB => { - vdso.symtab = - check_raw_pointer::<Elf_Sym>(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? - .as_ptr(); - } - DT_HASH => { - hash = check_raw_pointer::<ElfHashEntry>( - vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _ - )? - .as_ptr(); - } - DT_GNU_HASH => { - vdso.gnu_hash = - check_raw_pointer::<u32>(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? - .as_ptr() - } - DT_VERSYM => { - vdso.versym = - check_raw_pointer::<u16>(vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _)? - .as_ptr(); - } - DT_VERDEF => { - vdso.verdef = check_raw_pointer::<Elf_Verdef>( - vdso.addr_from_elf(d.d_un.d_ptr)? as *mut _, - )? - .as_ptr(); - } - DT_SYMENT => { - if d.d_un.d_ptr != size_of::<Elf_Sym>() { - return None; // Failed - } - } - DT_NULL => break, - _ => {} - } - i = i.checked_add(1)?; - } - // `check_raw_pointer` will have checked these pointers for null, - // however they could still be null if the expected dynamic table - // entries are absent. - if vdso.symstrings.is_null() - || vdso.symtab.is_null() - || (hash.is_null() && vdso.gnu_hash.is_null()) - { - return None; // Failed - } - - if vdso.verdef.is_null() { - vdso.versym = null(); - } - - // Parse the hash table header. - if !vdso.gnu_hash.is_null() { - vdso.nbucket = ElfHashEntry::from(*vdso.gnu_hash); - // The bucket array is located after the header (4 uint32) and the - // bloom filter (size_t array of gnu_hash[2] elements). - vdso.bucket = vdso - .gnu_hash - .add(4) - .add(size_of::<c::size_t>() / 4 * *vdso.gnu_hash.add(2) as usize) - .cast(); - } else { - vdso.nbucket = *hash.add(0); - //vdso.nchain = *hash.add(1); - vdso.bucket = hash.add(2); - vdso.chain = hash.add(vdso.nbucket as usize + 2); - } - - // That's all we need. - Some(vdso) - } -} - -impl Vdso { - /// Parse the vDSO. - /// - /// Returns `None` if the vDSO can't be located or if it doesn't conform to - /// our expectations. - #[inline] - pub(super) fn new() -> Option<Self> { - init_from_sysinfo_ehdr() - } - - /// Check the version for a symbol. - /// - /// # Safety - /// - /// The raw pointers inside `self` must be valid. - unsafe fn match_version(&self, mut ver: u16, name: &CStr, hash: u32) -> bool { - // This is a helper function to check if the version indexed by - // ver matches name (which hashes to hash). - // - // The version definition table is a mess, and I don't know how - // to do this in better than linear time without allocating memory - // to build an index. I also don't know why the table has - // variable size entries in the first place. - // - // For added fun, I can't find a comprehensible specification of how - // to parse all the weird flags in the table. - // - // So I just parse the whole table every time. - - // First step: find the version definition - ver &= 0x7fff; // Apparently bit 15 means "hidden" - let mut def = self.verdef; - loop { - if (*def).vd_version != VER_DEF_CURRENT { - return false; // Failed - } - - if ((*def).vd_flags & VER_FLG_BASE) == 0 && ((*def).vd_ndx & 0x7fff) == ver { - break; - } - - if (*def).vd_next == 0 { - return false; // No definition. - } - - def = def - .cast::<u8>() - .add((*def).vd_next as usize) - .cast::<Elf_Verdef>(); - } - - // Now figure out whether it matches. - let aux = &*(def.cast::<u8>()) - .add((*def).vd_aux as usize) - .cast::<Elf_Verdaux>(); - (*def).vd_hash == hash - && (name == CStr::from_ptr(self.symstrings.add(aux.vda_name as usize).cast())) - } - - /// Check to see if the symbol is the one we're looking for. - /// - /// # Safety - /// - /// The raw pointers inside `self` must be valid. - unsafe fn check_sym( - &self, - sym: &Elf_Sym, - i: ElfHashEntry, - name: &CStr, - version: &CStr, - ver_hash: u32, - ) -> bool { - // Check for a defined global or weak function w/ right name. - // - // Accept `STT_NOTYPE` in addition to `STT_FUNC` for the symbol - // type, for compatibility with some versions of Linux on - // PowerPC64. See [this commit] in Linux for more background. - // - // [this commit]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/tools/testing/selftests/vDSO/parse_vdso.c?id=0161bd38c24312853ed5ae9a425a1c41c4ac674a - if ELF_ST_TYPE(sym.st_info) != STT_FUNC && ELF_ST_TYPE(sym.st_info) != STT_NOTYPE { - return false; - } - if ELF_ST_BIND(sym.st_info) != STB_GLOBAL && ELF_ST_BIND(sym.st_info) != STB_WEAK { - return false; - } - if name != CStr::from_ptr(self.symstrings.add(sym.st_name as usize).cast()) { - return false; - } - - // Check symbol version. - if !self.versym.is_null() - && !self.match_version(*self.versym.add(i as usize), version, ver_hash) - { - return false; - } - - true - } - - /// Look up a symbol in the vDSO. - pub(super) fn sym(&self, version: &CStr, name: &CStr) -> *mut c::c_void { - let ver_hash = elf_hash(version); - - // SAFETY: The pointers in `self` must be valid. - unsafe { - if !self.gnu_hash.is_null() { - let mut h1: u32 = gnu_hash(name); - - // Changes to fix the pointer arithmetic on s390x: cast - // `self.bucket` to `*const u32` here, because even though - // s390x's `ElfHashEntry` is 64-bit for `DT_HASH` tables, - // it uses 32-bit entries for `DT_GNU_HASH` tables. - let mut i = *self - .bucket - .cast::<u32>() - .add((ElfHashEntry::from(h1) % self.nbucket) as usize); - if i == 0 { - return null_mut(); - } - h1 |= 1; - // Changes to fix the pointer arithmetic on s390x: As above, - // cast `self.bucket` to `*const u32`. - let mut hashval = self - .bucket - .cast::<u32>() - .add(self.nbucket as usize) - .add((i - *self.gnu_hash.add(1)) as usize); - loop { - let sym: &Elf_Sym = &*self.symtab.add(i as usize); - let h2 = *hashval; - hashval = hashval.add(1); - if h1 == (h2 | 1) - && self.check_sym(sym, ElfHashEntry::from(i), name, version, ver_hash) - { - let sum = self.addr_from_elf(sym.st_value).unwrap(); - assert!( - sum as usize >= self.load_addr as usize - && sum as usize <= self.load_end as usize - ); - return sum as *mut c::c_void; - } - if (h2 & 1) != 0 { - break; - } - i += 1; - } - } else { - let mut i = *self - .bucket - .add((ElfHashEntry::from(elf_hash(name)) % self.nbucket) as usize); - while i != 0 { - let sym: &Elf_Sym = &*self.symtab.add(i as usize); - if sym.st_shndx != SHN_UNDEF && self.check_sym(sym, i, name, version, ver_hash) - { - let sum = self.addr_from_elf(sym.st_value).unwrap(); - assert!( - sum as usize >= self.load_addr as usize - && sum as usize <= self.load_end as usize - ); - return sum as *mut c::c_void; - } - i = *self.chain.add(i as usize); - } - } - } - - null_mut() - } - - /// Add the given address to the vDSO base address. - unsafe fn base_plus(&self, offset: usize) -> Option<*const c_void> { - // Check for overflow. - let _ = (self.load_addr as usize).checked_add(offset)?; - // Add the offset to the base. - Some(self.load_addr.cast::<u8>().add(offset).cast()) - } - - /// Translate an ELF-address-space address into a usable virtual address. - unsafe fn addr_from_elf(&self, elf_addr: usize) -> Option<*const c_void> { - self.base_plus(elf_addr.wrapping_add(self.pv_offset)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - // Disable on MIPS since QEMU on MIPS doesn't provide a vDSO. - #[cfg(linux_raw)] - #[test] - #[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)] - #[allow(unused_variables)] - fn test_vdso() { - let vdso = Vdso::new().unwrap(); - assert!(!vdso.symtab.is_null()); - assert!(!vdso.symstrings.is_null()); - - { - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); - #[cfg(target_arch = "arm")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "aarch64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_clock_gettime")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_clock_gettime")); - #[cfg(target_arch = "powerpc")] - let _ptr = vdso.sym(cstr!("LINUX_5.11"), cstr!("__kernel_clock_gettime64")); - #[cfg(target_arch = "powerpc64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_clock_gettime")); - #[cfg(target_arch = "s390x")] - let ptr = vdso.sym(cstr!("LINUX_2.6.29"), cstr!("__kernel_clock_gettime")); - #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); - - // On PowerPC, "__kernel_clock_gettime64" isn't available in - // Linux < 5.11. - // On x86, "__vdso_clock_gettime64" isn't available in - // Linux < 5.3. - #[cfg(not(any(target_arch = "powerpc", target_arch = "x86")))] - assert!(!ptr.is_null()); - } - - { - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_getres")); - #[cfg(target_arch = "arm")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_getres")); - #[cfg(target_arch = "aarch64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_clock_getres")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_getres")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_clock_getres")); - #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_clock_getres")); - #[cfg(target_arch = "s390x")] - let ptr = vdso.sym(cstr!("LINUX_2.6.29"), cstr!("__kernel_clock_getres")); - #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_getres")); - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_getres")); - - // Some versions of Linux appear to lack "__vdso_clock_getres" on x86. - #[cfg(not(target_arch = "x86"))] - assert!(!ptr.is_null()); - } - - { - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_gettimeofday")); - #[cfg(target_arch = "arm")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_gettimeofday")); - #[cfg(target_arch = "aarch64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_gettimeofday")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_gettimeofday")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_gettimeofday")); - #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_gettimeofday")); - #[cfg(target_arch = "s390x")] - let ptr = vdso.sym(cstr!("LINUX_2.6.29"), cstr!("__kernel_gettimeofday")); - #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_gettimeofday")); - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_gettimeofday")); - - // Some versions of Linux appear to lack "__vdso_gettimeofday" on x86. - #[cfg(not(target_arch = "x86"))] - assert!(!ptr.is_null()); - } - - #[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", - ))] - { - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_getcpu")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_getcpu")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_getcpu")); - #[cfg(target_arch = "powerpc")] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_getcpu")); - #[cfg(target_arch = "powerpc64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_getcpu")); - #[cfg(target_arch = "s390x")] - let ptr = vdso.sym(cstr!("LINUX_2.6.29"), cstr!("__kernel_getcpu")); - - // On PowerPC, "__kernel_getcpu" isn't available in 32-bit kernels. - // Some versions of Linux appear to lack "__vdso_getcpu" on x86. - #[cfg(not(any(target_arch = "powerpc", target_arch = "x86")))] - assert!(!ptr.is_null()); - } - } -} diff --git a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs deleted file mode 100644 index 338f4548..00000000 --- a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs +++ /dev/null @@ -1,623 +0,0 @@ -//! Implement syscalls using the vDSO. -//! -//! <https://man7.org/linux/man-pages/man7/vdso.7.html> -//! -//! # Safety -//! -//! Similar to syscalls.rs, this file performs raw system calls, and sometimes -//! passes them uninitialized memory buffers. This file also calls vDSO -//! functions. -#![allow(unsafe_code)] -#![allow(clippy::missing_transmute_annotations)] - -#[cfg(target_arch = "x86")] -use super::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; -use super::vdso; -#[cfg(target_arch = "x86")] -use core::arch::global_asm; -#[cfg(feature = "thread")] -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", -))] -use core::ffi::c_void; -use core::mem::transmute; -use core::ptr::null_mut; -use core::sync::atomic::AtomicPtr; -use core::sync::atomic::Ordering::Relaxed; -#[cfg(target_pointer_width = "32")] -#[cfg(feature = "time")] -use linux_raw_sys::general::timespec as __kernel_old_timespec; -#[cfg(any( - all( - feature = "thread", - any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x" - ) - ), - feature = "time" -))] -use {super::c, super::conv::ret, core::mem::MaybeUninit}; -#[cfg(feature = "time")] -use { - super::conv::c_int, - crate::clockid::{ClockId, DynamicClockId}, - crate::io, - crate::timespec::Timespec, - linux_raw_sys::general::__kernel_clockid_t, -}; - -#[cfg(feature = "time")] -#[inline] -#[must_use] -pub(crate) fn clock_gettime(id: ClockId) -> Timespec { - // SAFETY: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has the - // side effect of writing to the result buffer, and no others. - unsafe { - let mut result = MaybeUninit::<Timespec>::uninit(); - let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { - Some(callee) => callee, - None => init_clock_gettime(), - }; - let r0 = callee(id as c::c_int, result.as_mut_ptr()); - // The `ClockId` enum only contains clocks which never fail. It may be - // tempting to change this to `debug_assert_eq`, however they can still - // fail on uncommon kernel configs, so we leave this in place to ensure - // that we don't execute undefined behavior if they ever do fail. - assert_eq!(r0, 0); - result.assume_init() - } -} - -#[cfg(feature = "time")] -#[inline] -pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timespec> { - let id = match id { - DynamicClockId::Known(id) => id as __kernel_clockid_t, - - DynamicClockId::Dynamic(fd) => { - // See `FD_TO_CLOCKID` in Linux's `clock_gettime` documentation. - use crate::backend::fd::AsRawFd as _; - const CLOCKFD: i32 = 3; - ((!fd.as_raw_fd() << 3) | CLOCKFD) as __kernel_clockid_t - } - - DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM as __kernel_clockid_t, - DynamicClockId::Tai => c::CLOCK_TAI as __kernel_clockid_t, - DynamicClockId::Boottime => c::CLOCK_BOOTTIME as __kernel_clockid_t, - DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM as __kernel_clockid_t, - }; - - // SAFETY: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has the - // side effect of writing to the result buffer, and no others. - unsafe { - const EINVAL: c::c_int = -(c::EINVAL as c::c_int); - let mut timespec = MaybeUninit::<Timespec>::uninit(); - let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { - Some(callee) => callee, - None => init_clock_gettime(), - }; - match callee(id, timespec.as_mut_ptr()) { - 0 => (), - EINVAL => return Err(io::Errno::INVAL), - _ => _clock_gettime_via_syscall(id, timespec.as_mut_ptr())?, - } - Ok(timespec.assume_init()) - } -} - -#[cfg(feature = "thread")] -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", -))] -#[inline] -pub(crate) fn sched_getcpu() -> usize { - // SAFETY: `GETCPU` contains either null or the address of a function with - // an ABI like libc `getcpu`, and calling it has the side effect of writing - // to the result buffers, and no others. - unsafe { - let mut cpu = MaybeUninit::<u32>::uninit(); - let callee = match transmute(GETCPU.load(Relaxed)) { - Some(callee) => callee, - None => init_getcpu(), - }; - let r0 = callee(cpu.as_mut_ptr(), null_mut(), null_mut()); - debug_assert_eq!(r0, 0); - cpu.assume_init() as usize - } -} - -#[cfg(target_arch = "x86")] -pub(super) mod x86_via_vdso { - use super::{transmute, ArgReg, Relaxed, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; - use crate::backend::arch::asm; - - #[inline] - pub(in crate::backend) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall0(callee, nr) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall1<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - ) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall1(callee, nr, a0) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall1_noreturn<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - ) -> ! { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall1_noreturn(callee, nr, a0) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall2<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - ) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall2(callee, nr, a0, a1) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall3<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - ) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall3(callee, nr, a0, a1, a2) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall4<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - a3: ArgReg<'a, A3>, - ) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall4(callee, nr, a0, a1, a2, a3) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall5<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - a3: ArgReg<'a, A3>, - a4: ArgReg<'a, A4>, - ) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall5(callee, nr, a0, a1, a2, a3, a4) - } - - #[inline] - pub(in crate::backend) unsafe fn syscall6<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - a3: ArgReg<'a, A3>, - a4: ArgReg<'a, A4>, - a5: ArgReg<'a, A5>, - ) -> RetReg<R0> { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall6(callee, nr, a0, a1, a2, a3, a4, a5) - } - - // With the indirect call, it isn't meaningful to do a separate - // `_readonly` optimization. - #[allow(unused_imports)] - pub(in crate::backend) use { - syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, - syscall2 as syscall2_readonly, syscall3 as syscall3_readonly, - syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, - syscall6 as syscall6_readonly, - }; -} - -#[cfg(feature = "time")] -type ClockGettimeType = unsafe extern "C" fn(c::c_int, *mut Timespec) -> c::c_int; - -#[cfg(feature = "thread")] -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", -))] -type GetcpuType = unsafe extern "C" fn(*mut u32, *mut u32, *mut c_void) -> c::c_int; - -/// The underlying syscall functions are only called from asm, using the -/// special syscall calling convention to pass arguments and return values, -/// which the signature here doesn't reflect. -#[cfg(target_arch = "x86")] -pub(super) type SyscallType = unsafe extern "C" fn(); - -/// Initialize `CLOCK_GETTIME` and return its value. -#[cfg(feature = "time")] -#[cold] -fn init_clock_gettime() -> ClockGettimeType { - init(); - // SAFETY: Load the function address from static storage that we just - // initialized. - unsafe { transmute(CLOCK_GETTIME.load(Relaxed)) } -} - -/// Initialize `GETCPU` and return its value. -#[cfg(feature = "thread")] -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", -))] -#[cold] -fn init_getcpu() -> GetcpuType { - init(); - // SAFETY: Load the function address from static storage that we just - // initialized. - unsafe { transmute(GETCPU.load(Relaxed)) } -} - -/// Initialize `SYSCALL` and return its value. -#[cfg(target_arch = "x86")] -#[cold] -fn init_syscall() -> SyscallType { - init(); - // SAFETY: Load the function address from static storage that we just - // initialized. - unsafe { transmute(SYSCALL.load(Relaxed)) } -} - -/// `AtomicPtr` can't hold a `fn` pointer, so we use a `*` pointer to this -/// placeholder type, and cast it as needed. -struct Function; -#[cfg(feature = "time")] -static CLOCK_GETTIME: AtomicPtr<Function> = AtomicPtr::new(null_mut()); -#[cfg(feature = "thread")] -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", -))] -static GETCPU: AtomicPtr<Function> = AtomicPtr::new(null_mut()); -#[cfg(target_arch = "x86")] -static SYSCALL: AtomicPtr<Function> = AtomicPtr::new(null_mut()); - -#[cfg(feature = "time")] -#[must_use] -unsafe extern "C" fn clock_gettime_via_syscall(clockid: c::c_int, res: *mut Timespec) -> c::c_int { - match _clock_gettime_via_syscall(clockid, res) { - Ok(()) => 0, - Err(err) => err.raw_os_error().wrapping_neg(), - } -} - -#[cfg(feature = "time")] -#[cfg(target_pointer_width = "32")] -unsafe fn _clock_gettime_via_syscall(clockid: c::c_int, res: *mut Timespec) -> io::Result<()> { - let r0 = syscall!(__NR_clock_gettime64, c_int(clockid), res); - match ret(r0) { - Err(io::Errno::NOSYS) => _clock_gettime_via_syscall_old(clockid, res), - otherwise => otherwise, - } -} - -#[cfg(feature = "time")] -#[cfg(target_pointer_width = "32")] -unsafe fn _clock_gettime_via_syscall_old(clockid: c::c_int, res: *mut Timespec) -> io::Result<()> { - // Ordinarily `rustix` doesn't like to emulate system calls, but in the - // case of time APIs, it's specific to Linux, specific to 32-bit - // architectures *and* specific to old kernel versions, and it's not that - // hard to fix up here, so that no other code needs to worry about this. - let mut old_result = MaybeUninit::<__kernel_old_timespec>::uninit(); - let r0 = syscall!(__NR_clock_gettime, c_int(clockid), &mut old_result); - match ret(r0) { - Ok(()) => { - let old_result = old_result.assume_init(); - *res = Timespec { - tv_sec: old_result.tv_sec.into(), - tv_nsec: old_result.tv_nsec.into(), - }; - Ok(()) - } - otherwise => otherwise, - } -} - -#[cfg(feature = "time")] -#[cfg(target_pointer_width = "64")] -unsafe fn _clock_gettime_via_syscall(clockid: c::c_int, res: *mut Timespec) -> io::Result<()> { - ret(syscall!(__NR_clock_gettime, c_int(clockid), res)) -} - -#[cfg(feature = "thread")] -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", -))] -unsafe extern "C" fn getcpu_via_syscall( - cpu: *mut u32, - node: *mut u32, - unused: *mut c_void, -) -> c::c_int { - match ret(syscall!(__NR_getcpu, cpu, node, unused)) { - Ok(()) => 0, - Err(err) => err.raw_os_error().wrapping_neg(), - } -} - -#[cfg(target_arch = "x86")] -extern "C" { - /// A symbol pointing to an x86 `int 0x80` instruction. This “function” - /// is only called from assembly, and only with the x86 syscall calling - /// convention, so its signature here is not its true signature. - /// - /// This extern block and the `global_asm!` below can be replaced with - /// `#[naked]` if it's stabilized. - fn rustix_x86_int_0x80(); -} - -// This uses `.weak` so that it doesn't conflict if multiple versions of rustix -// are linked in in non-lto builds, and `.ifndef` so that it doesn't conflict -// if multiple versions of rustix are linked in in lto builds. -#[cfg(target_arch = "x86")] -global_asm!( - r#" - .ifndef rustix_x86_int_0x80 - .section .text.rustix_x86_int_0x80,"ax",@progbits - .p2align 4 - .weak rustix_x86_int_0x80 - .hidden rustix_x86_int_0x80 - .type rustix_x86_int_0x80, @function -rustix_x86_int_0x80: - .cfi_startproc - int 0x80 - ret - .cfi_endproc - .size rustix_x86_int_0x80, .-rustix_x86_int_0x80 - .endif -"# -); - -fn minimal_init() { - // Store default function addresses in static storage so that if we - // end up making any system calls while we read the vDSO, they'll work. If - // the memory happens to already be initialized, this is redundant, but not - // harmful. - #[cfg(feature = "time")] - { - CLOCK_GETTIME - .compare_exchange( - null_mut(), - clock_gettime_via_syscall as *mut Function, - Relaxed, - Relaxed, - ) - .ok(); - } - - #[cfg(feature = "thread")] - #[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", - ))] - { - GETCPU - .compare_exchange( - null_mut(), - getcpu_via_syscall as *mut Function, - Relaxed, - Relaxed, - ) - .ok(); - } - - #[cfg(target_arch = "x86")] - { - SYSCALL - .compare_exchange( - null_mut(), - rustix_x86_int_0x80 as *mut Function, - Relaxed, - Relaxed, - ) - .ok(); - } -} - -fn init() { - minimal_init(); - - if let Some(vdso) = vdso::Vdso::new() { - #[cfg(feature = "time")] - { - // Look up the platform-specific `clock_gettime` symbol as - // documented [here], except on 32-bit platforms where we look up - // the `64`-suffixed variant and fail if we don't find it. - // - // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); - #[cfg(target_arch = "arm")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "aarch64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_clock_gettime")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_clock_gettime")); - #[cfg(target_arch = "powerpc")] - let ptr = vdso.sym(cstr!("LINUX_5.11"), cstr!("__kernel_clock_gettime64")); - #[cfg(target_arch = "powerpc64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_clock_gettime")); - #[cfg(target_arch = "s390x")] - let ptr = vdso.sym(cstr!("LINUX_2.6.29"), cstr!("__kernel_clock_gettime")); - #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); - - // On all 64-bit platforms, the 64-bit `clock_gettime` symbols are - // always available. - #[cfg(target_pointer_width = "64")] - let ok = true; - - // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are - // not available on older kernel versions. - #[cfg(any( - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "powerpc", - target_arch = "x86" - ))] - let ok = !ptr.is_null(); - - if ok { - assert!(!ptr.is_null()); - - // Store the computed function addresses in static storage so - // that we don't need to compute them again (but if we do, it - // doesn't hurt anything). - CLOCK_GETTIME.store(ptr.cast(), Relaxed); - } - } - - #[cfg(feature = "thread")] - #[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", - ))] - { - // Look up the platform-specific `getcpu` symbol as documented - // [here]. - // - // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_getcpu")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_getcpu")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_getcpu")); - #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_getcpu")); - #[cfg(target_arch = "s390x")] - let ptr = vdso.sym(cstr!("LINUX_2.6.29"), cstr!("__kernel_getcpu")); - - #[cfg(any( - target_arch = "x86_64", - target_arch = "riscv64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x" - ))] - let ok = true; - - // On 32-bit x86, the symbol doesn't appear present sometimes. - #[cfg(target_arch = "x86")] - let ok = !ptr.is_null(); - - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - ))] - let ok = false; - - if ok { - assert!(!ptr.is_null()); - - // Store the computed function addresses in static storage so - // that we don't need to compute them again (but if we do, it - // doesn't hurt anything). - GETCPU.store(ptr.cast(), Relaxed); - } - } - - // On x86, also look up the vsyscall entry point. - #[cfg(target_arch = "x86")] - { - let ptr = vdso.sym(cstr!("LINUX_2.5"), cstr!("__kernel_vsyscall")); - assert!(!ptr.is_null()); - - // As above, store the computed function addresses in - // static storage. - SYSCALL.store(ptr.cast(), Relaxed); - } - } -} diff --git a/vendor/rustix/src/bitcast.rs b/vendor/rustix/src/bitcast.rs deleted file mode 100644 index db17c7cb..00000000 --- a/vendor/rustix/src/bitcast.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! The `bitcast` and `bitflags_bits` macros. - -#![allow(unused_macros)] - -// Ensure that the source and destination types are both primitive integer -// types and the same size, and then bitcast. -macro_rules! bitcast { - ($x:expr) => {{ - if false { - // Ensure the source and destinations are primitive integer types. - let _ = !$x; - let _ = $x as u8; - 0 - } else if false { - // Ensure that the source and destinations are the same size. - #[allow( - unsafe_code, - unused_unsafe, - clippy::useless_transmute, - clippy::missing_transmute_annotations - )] - // SAFETY: This code is under an `if false`. - unsafe { - ::core::mem::transmute($x) - } - } else { - // Do the conversion. - $x as _ - } - }}; -} - -/// Return a [`bitcast`] of the value of `$x.bits()`, where `$x` is a -/// `bitflags` type. -macro_rules! bitflags_bits { - ($x:expr) => {{ - bitcast!($x.bits()) - }}; -} diff --git a/vendor/rustix/src/buffer.rs b/vendor/rustix/src/buffer.rs deleted file mode 100644 index 6c86826f..00000000 --- a/vendor/rustix/src/buffer.rs +++ /dev/null @@ -1,448 +0,0 @@ -//! Utilities for functions that return data via buffers. - -#![allow(unsafe_code)] - -#[cfg(feature = "alloc")] -use alloc::vec::Vec; -use core::mem::MaybeUninit; -use core::slice; - -/// A memory buffer that may be uninitialized. -/// -/// There are three types that implement the `Buffer` trait, and the type you -/// use determines the return type of the functions that use it: -/// -/// | If you pass a… | You get back a… | -/// | ------------------------ | --------------- | -/// | `&mut [u8]` | `usize`, indicating the number of elements initialized. | -/// | `&mut [MaybeUninit<u8>]` | `(&mut [u8], &mut [MaybeUninit<u8>])`, holding the initialized and uninitialized subslices. | -/// | [`SpareCapacity`] | `usize`, indicating the number of elements initialized. And the `Vec` is extended. | -/// -/// # Examples -/// -/// Passing a `&mut [u8]`: -/// -/// ``` -/// # use rustix::io::read; -/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// let mut buf = [0_u8; 64]; -/// let nread = read(fd, &mut buf)?; -/// // `nread` is the number of bytes read. -/// # Ok(()) -/// # } -/// ``` -/// -/// Passing a `&mut [MaybeUninit<u8>]`: -/// -/// ``` -/// # use rustix::io::read; -/// # use std::mem::MaybeUninit; -/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// let mut buf = [MaybeUninit::<u8>::uninit(); 64]; -/// let (init, uninit) = read(fd, &mut buf)?; -/// // `init` is a `&mut [u8]` with the initialized bytes. -/// // `uninit` is a `&mut [MaybeUninit<u8>]` with the remaining bytes. -/// # Ok(()) -/// # } -/// ``` -/// -/// Passing a [`SpareCapacity`], via the [`spare_capacity`] helper function: -/// -/// ``` -/// # use rustix::io::read; -/// # use rustix::buffer::spare_capacity; -/// # fn example(fd: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// let mut buf = Vec::with_capacity(64); -/// let nread = read(fd, spare_capacity(&mut buf))?; -/// // `nread` is the number of bytes read. -/// // Also, `buf.len()` is now `nread` elements longer than it was before. -/// # Ok(()) -/// # } -/// ``` -/// -/// # Guide to error messages -/// -/// Sometimes code using `Buffer` can encounter non-obvious error messages. -/// Here are some we've encountered, along with ways to fix them. -/// -/// If you see errors like -/// "cannot move out of `self` which is behind a mutable reference" -/// and -/// "move occurs because `x` has type `&mut [u8]`, which does not implement the `Copy` trait", -/// replace `x` with `&mut *x`. See `error_buffer_wrapper` in -/// examples/buffer_errors.rs. -/// -/// If you see errors like -/// "type annotations needed" -/// and -/// "cannot infer type of the type parameter `Buf` declared on the function `read`", -/// you may need to change a `&mut []` to `&mut [0_u8; 0]`. See -/// `error_empty_slice` in examples/buffer_errors.rs. -/// -/// If you see errors like -/// "the trait bound `[MaybeUninit<u8>; 1]: Buffer<u8>` is not satisfied", -/// add a `&mut` to pass the array by reference instead of by value. See -/// `error_array_by_value` in examples/buffer_errors.rs. -/// -/// If you see errors like -/// "cannot move out of `x`, a captured variable in an `FnMut` closure", -/// try replacing `x` with `&mut *x`, or, if that doesn't work, try moving a -/// `let` into the closure body. See `error_retry_closure` and -/// `error_retry_indirect_closure` in examples/buffer_errors.rs. -/// -/// If you see errors like -/// "captured variable cannot escape `FnMut` closure body", -/// use an explicit loop instead of `retry_on_intr`, assuming you're using -/// that. See `error_retry_closure_uninit` in examples/buffer_errors.rs. -pub trait Buffer<T>: private::Sealed<T> {} - -// Implement `Buffer` for all the types that implement `Sealed`. -impl<T> Buffer<T> for &mut [T] {} -impl<T, const N: usize> Buffer<T> for &mut [T; N] {} -#[cfg(feature = "alloc")] -impl<T> Buffer<T> for &mut Vec<T> {} -impl<T> Buffer<T> for &mut [MaybeUninit<T>] {} -impl<T, const N: usize> Buffer<T> for &mut [MaybeUninit<T>; N] {} -#[cfg(feature = "alloc")] -impl<T> Buffer<T> for &mut Vec<MaybeUninit<T>> {} -#[cfg(feature = "alloc")] -impl<'a, T> Buffer<T> for SpareCapacity<'a, T> {} - -impl<T> private::Sealed<T> for &mut [T] { - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - len - } -} - -impl<T, const N: usize> private::Sealed<T> for &mut [T; N] { - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr(), N) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - len - } -} - -// `Vec` implements `DerefMut` to `&mut [T]`, however it doesn't get -// auto-derefed in a `impl Buffer<u8>`, so we add this `impl` so that our users -// don't have to add an extra `*` in these situations. -#[cfg(feature = "alloc")] -impl<T> private::Sealed<T> for &mut Vec<T> { - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - len - } -} - -impl<'a, T> private::Sealed<T> for &'a mut [MaybeUninit<T>] { - type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]); - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr().cast(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - let (init, uninit) = self.split_at_mut(len); - - // SAFETY: The user asserts that the slice is now initialized. - let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len()); - - (init, uninit) - } -} - -impl<'a, T, const N: usize> private::Sealed<T> for &'a mut [MaybeUninit<T>; N] { - type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]); - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr().cast(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - let (init, uninit) = self.split_at_mut(len); - - // SAFETY: The user asserts that the slice is now initialized. - let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len()); - - (init, uninit) - } -} - -#[cfg(feature = "alloc")] -impl<'a, T> private::Sealed<T> for &'a mut Vec<MaybeUninit<T>> { - type Output = (&'a mut [T], &'a mut [MaybeUninit<T>]); - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - (self.as_mut_ptr().cast(), self.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - let (init, uninit) = self.split_at_mut(len); - - // SAFETY: The user asserts that the slice is now initialized. - let init = slice::from_raw_parts_mut(init.as_mut_ptr().cast::<T>(), init.len()); - - (init, uninit) - } -} - -/// A type that implements [`Buffer`] by appending to a `Vec`, up to its -/// capacity. -/// -/// To use this, use the [`spare_capacity`] function. -/// -/// Because this uses the capacity, and never reallocates, the `Vec` should -/// have some non-empty spare capacity. -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub struct SpareCapacity<'a, T>(&'a mut Vec<T>); - -/// Construct an [`SpareCapacity`], which implements [`Buffer`]. -/// -/// This wraps a `Vec` and uses the spare capacity of the `Vec` as the buffer -/// to receive data in, automatically calling `set_len` on the `Vec` to set the -/// length to include the received elements. -/// -/// This uses the existing capacity, and never allocates, so the `Vec` should -/// have some non-empty spare capacity! -/// -/// # Examples -/// -/// ``` -/// # fn test(input: rustix::fd::BorrowedFd) -> rustix::io::Result<()> { -/// use rustix::buffer::spare_capacity; -/// use rustix::io::{read, Errno}; -/// -/// let mut buf = Vec::with_capacity(1024); -/// match read(input, spare_capacity(&mut buf)) { -/// Ok(0) => { /* end of stream */ } -/// Ok(n) => { /* `buf` is now `n` bytes longer */ } -/// Err(Errno::INTR) => { /* `buf` is unmodified */ } -/// Err(e) => { -/// return Err(e); -/// } -/// } -/// -/// # Ok(()) -/// # } -/// ``` -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn spare_capacity<'a, T>(v: &'a mut Vec<T>) -> SpareCapacity<'a, T> { - debug_assert_ne!( - v.capacity(), - 0, - "`extend` uses spare capacity, and never allocates new memory, so the `Vec` passed to it \ - should have some spare capacity." - ); - - SpareCapacity(v) -} - -#[cfg(feature = "alloc")] -impl<'a, T> private::Sealed<T> for SpareCapacity<'a, T> { - /// The mutated `Vec` reflects the number of bytes read. We also return - /// this number, and a value of 0 indicates the end of the stream has - /// been reached. - type Output = usize; - - #[inline] - fn parts_mut(&mut self) -> (*mut T, usize) { - let spare = self.0.spare_capacity_mut(); - (spare.as_mut_ptr().cast(), spare.len()) - } - - #[inline] - unsafe fn assume_init(self, len: usize) -> Self::Output { - // We initialized `len` elements; extend the `Vec` to include them. - self.0.set_len(self.0.len() + len); - len - } -} - -mod private { - pub trait Sealed<T> { - /// The result of the process operation. - type Output; - - /// Return a pointer and length for this buffer. - /// - /// The length is the number of elements of type `T`, not a number of - /// bytes. - /// - /// It's tempting to have this return `&mut [MaybeUninit<T>]` instead, - /// however that would require this function to be `unsafe`, because - /// callers could use the `&mut [MaybeUninit<T>]` slice to set elements - /// to `MaybeUninit::<T>::uninit()`, which would be a problem if `Self` - /// is `&mut [T]` or similar. - fn parts_mut(&mut self) -> (*mut T, usize); - - /// Convert a finished buffer pointer into its result. - /// - /// # Safety - /// - /// At least `len` elements of the buffer must now be initialized. - #[must_use] - unsafe fn assume_init(self, len: usize) -> Self::Output; - } -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - - #[cfg(not(windows))] - #[test] - fn test_compilation() { - use crate::io::read; - use core::mem::MaybeUninit; - - // We need to obtain input stream, so open our own source file. - let input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = vec![0_u8; 3]; - buf.reserve(32); - let _x: usize = read(&input, spare_capacity(&mut buf)).unwrap(); - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = - read(&input, buf.spare_capacity_mut()).unwrap(); - let _x: usize = read(&input, &mut buf).unwrap(); - let _x: usize = read(&input, &mut *buf).unwrap(); - let _x: usize = read(&input, &mut buf[..]).unwrap(); - let _x: usize = read(&input, &mut (*buf)[..]).unwrap(); - - let mut buf = [0, 0, 0]; - let _x: usize = read(&input, &mut buf).unwrap(); - let _x: usize = read(&input, &mut buf[..]).unwrap(); - - let mut buf = [ - MaybeUninit::uninit(), - MaybeUninit::uninit(), - MaybeUninit::uninit(), - ]; - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf).unwrap(); - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf[..]).unwrap(); - - let mut buf = vec![ - MaybeUninit::uninit(), - MaybeUninit::uninit(), - MaybeUninit::uninit(), - ]; - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf).unwrap(); - let _x: (&mut [u8], &mut [MaybeUninit<u8>]) = read(&input, &mut buf[..]).unwrap(); - } - - #[cfg(not(windows))] - #[test] - fn test_slice() { - use crate::io::read; - use std::io::{Seek, SeekFrom}; - - // We need to obtain input stream with contents that we can compare - // against, so open our own source file. - let mut input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = [0_u8; 64]; - let nread = read(&input, &mut buf).unwrap(); - assert_eq!(nread, buf.len()); - assert_eq!( - &buf[..58], - b"//! Utilities for functions that return data via buffers.\n" - ); - input.seek(SeekFrom::End(-1)).unwrap(); - let nread = read(&input, &mut buf).unwrap(); - assert_eq!(nread, 1); - input.seek(SeekFrom::End(0)).unwrap(); - let nread = read(&input, &mut buf).unwrap(); - assert_eq!(nread, 0); - } - - #[cfg(not(windows))] - #[test] - fn test_slice_uninit() { - use crate::io::read; - use core::mem::MaybeUninit; - use std::io::{Seek, SeekFrom}; - - // We need to obtain input stream with contents that we can compare - // against, so open our own source file. - let mut input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = [MaybeUninit::<u8>::uninit(); 64]; - let (init, uninit) = read(&input, &mut buf).unwrap(); - assert_eq!(uninit.len(), 0); - assert_eq!( - &init[..58], - b"//! Utilities for functions that return data via buffers.\n" - ); - assert_eq!(init.len(), buf.len()); - assert_eq!( - unsafe { core::mem::transmute::<&mut [MaybeUninit<u8>], &mut [u8]>(&mut buf[..58]) }, - b"//! Utilities for functions that return data via buffers.\n" - ); - input.seek(SeekFrom::End(-1)).unwrap(); - let (init, uninit) = read(&input, &mut buf).unwrap(); - assert_eq!(init.len(), 1); - assert_eq!(uninit.len(), buf.len() - 1); - input.seek(SeekFrom::End(0)).unwrap(); - let (init, uninit) = read(&input, &mut buf).unwrap(); - assert_eq!(init.len(), 0); - assert_eq!(uninit.len(), buf.len()); - } - - #[cfg(not(windows))] - #[test] - fn test_spare_capacity() { - use crate::io::read; - use std::io::{Seek, SeekFrom}; - - // We need to obtain input stream with contents that we can compare - // against, so open our own source file. - let mut input = std::fs::File::open("src/buffer.rs").unwrap(); - - let mut buf = Vec::with_capacity(64); - let nread = read(&input, spare_capacity(&mut buf)).unwrap(); - assert_eq!(nread, buf.capacity()); - assert_eq!(nread, buf.len()); - assert_eq!( - &buf[..58], - b"//! Utilities for functions that return data via buffers.\n" - ); - buf.clear(); - input.seek(SeekFrom::End(-1)).unwrap(); - let nread = read(&input, spare_capacity(&mut buf)).unwrap(); - assert_eq!(nread, 1); - assert_eq!(buf.len(), 1); - buf.clear(); - input.seek(SeekFrom::End(0)).unwrap(); - let nread = read(&input, spare_capacity(&mut buf)).unwrap(); - assert_eq!(nread, 0); - assert!(buf.is_empty()); - } -} diff --git a/vendor/rustix/src/check_types.rs b/vendor/rustix/src/check_types.rs deleted file mode 100644 index fb7e7a28..00000000 --- a/vendor/rustix/src/check_types.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! Macros for checking that types have the same layout as other types. - -#![allow(unused_macros)] - -/// Check that the size and alignment of a type match the `sys` bindings. -macro_rules! check_type { - ($struct:ident) => { - assert_eq_size!($struct, c::$struct); - assert_eq_align!($struct, c::$struct); - }; -} - -/// The same as `check_type`, but for unions and anonymous structs we've -/// renamed to avoid having types like `bindgen_ty_1` in the API. -macro_rules! check_renamed_type { - ($to:ident, $from:ident) => { - assert_eq_size!($to, c::$from); - assert_eq_align!($to, c::$from); - }; -} - -/// Check that the field of a struct has the same offset as the corresponding -/// field in the `sys` bindings. -macro_rules! check_struct_field { - ($struct:ident, $field:ident) => { - const_assert_eq!( - memoffset::offset_of!($struct, $field), - memoffset::offset_of!(c::$struct, $field) - ); - - // This can't use `const_assert_eq` because `span_of` returns a - // `Range`, which can't be compared in const contexts. - assert_eq!( - memoffset::span_of!($struct, $field), - memoffset::span_of!(c::$struct, $field) - ); - }; -} - -/// The same as `check_struct_field`, but for unions and anonymous structs -/// we've renamed to avoid having types like `bindgen_ty_1` in the API. -macro_rules! check_struct_renamed_field { - ($struct:ident, $to:ident, $from:ident) => { - const_assert_eq!( - memoffset::offset_of!($struct, $to), - memoffset::offset_of!(c::$struct, $from) - ); - - // As above, this can't use `const_assert_eq`. - assert_eq!( - memoffset::span_of!($struct, $to), - memoffset::span_of!(c::$struct, $from) - ); - }; -} - -/// The same as `check_struct_field`, but for when the struct is renamed -/// but the field is not. -macro_rules! check_renamed_struct_field { - ($to_struct:ident, $from_struct:ident, $field:ident) => { - const_assert_eq!( - memoffset::offset_of!($to_struct, $field), - memoffset::offset_of!(c::$from_struct, $field) - ); - - // As above, this can't use `const_assert_eq`. - assert_eq!( - memoffset::span_of!($to_struct, $field), - memoffset::span_of!(c::$from_struct, $field) - ); - }; -} - -/// The same as `check_struct_renamed_field`, but for when both the struct and -/// a field are renamed. -macro_rules! check_renamed_struct_renamed_field { - ($to_struct:ident, $from_struct:ident, $to:ident, $from:ident) => { - const_assert_eq!( - memoffset::offset_of!($to_struct, $to), - memoffset::offset_of!(c::$from_struct, $from) - ); - - // As above, this can't use `const_assert_eq`. - assert_eq!( - memoffset::span_of!($to_struct, $to), - memoffset::span_of!(c::$from_struct, $from) - ); - }; -} - -/// For the common case of no renaming, check all fields of a struct. -macro_rules! check_struct { - ($name:ident, $($field:ident),*) => { - // Check the size and alignment. - check_type!($name); - - // Check that we have all the fields. - if false { - #[allow(unreachable_code)] - let _test = $name { - $($field: panic!()),* - }; - #[allow(unreachable_code)] - let _test = c::$name { - $($field: panic!()),* - }; - } - - // Check that the fields have the right sizes and offsets. - $(check_struct_field!($name, $field));* - }; -} - -/// For the case of renaming, check all fields of a struct. -macro_rules! check_renamed_struct { - ($to_struct:ident, $from_struct:ident, $($field:ident),*) => { - // Check the size and alignment. - check_renamed_type!($to_struct, $from_struct); - - // Check that we have all the fields. - if false { - #[allow(unreachable_code)] - let _test = $to_struct { - $($field: panic!()),* - }; - #[allow(unreachable_code)] - let _test = c::$from_struct { - $($field: panic!()),* - }; - } - - // Check that the fields have the right sizes and offsets. - $(check_renamed_struct_field!($to_struct, $from_struct, $field));* - }; -} diff --git a/vendor/rustix/src/clockid.rs b/vendor/rustix/src/clockid.rs deleted file mode 100644 index ae300f2b..00000000 --- a/vendor/rustix/src/clockid.rs +++ /dev/null @@ -1,171 +0,0 @@ -use crate::backend::c; -use crate::fd::BorrowedFd; - -/// `CLOCK_*` constants for use with [`clock_gettime`]. -/// -/// These constants are always supported at runtime, so `clock_gettime` never -/// has to fail with `INVAL` due to an unsupported clock. See -/// [`DynamicClockId`] for a greater set of clocks, with the caveat that not -/// all of them are always supported. -/// -/// [`clock_gettime`]: crate::time::clock_gettime -#[cfg(not(any(apple, target_os = "wasi")))] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[cfg_attr( - not(any(target_os = "aix", target_os = "cygwin", target_os = "dragonfly")), - repr(i32) -)] -#[cfg_attr(any(target_os = "cygwin", target_os = "dragonfly"), repr(u64))] -#[cfg_attr(target_os = "aix", repr(i64))] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - #[doc(alias = "CLOCK_REALTIME")] - Realtime = bitcast!(c::CLOCK_REALTIME), - - /// `CLOCK_MONOTONIC` - #[doc(alias = "CLOCK_MONOTONIC")] - Monotonic = bitcast!(c::CLOCK_MONOTONIC), - - /// `CLOCK_UPTIME` - /// - /// On FreeBSD, this is an alias for [`Self::Boottime`]. - /// - /// On OpenBSD, this differs from `Self::Boottime`; it only advances when - /// the system is not suspended. - /// - /// [`Self::Uptime`]: https://docs.rs/rustix/*/x86_64-unknown-freebsd/rustix/time/enum.ClockId.html#variant.Uptime - #[cfg(any(freebsdlike, target_os = "openbsd"))] - #[doc(alias = "CLOCK_UPTIME")] - Uptime = c::CLOCK_UPTIME, - - /// `CLOCK_PROCESS_CPUTIME_ID` - #[cfg(not(any( - solarish, - target_os = "horizon", - target_os = "netbsd", - target_os = "redox", - target_os = "vita" - )))] - #[doc(alias = "CLOCK_PROCESS_CPUTIME_ID")] - ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, - - /// `CLOCK_THREAD_CPUTIME_ID` - #[cfg(not(any( - solarish, - target_os = "horizon", - target_os = "netbsd", - target_os = "redox", - target_os = "vita" - )))] - #[doc(alias = "CLOCK_THREAD_CPUTIME_ID")] - ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, - - /// `CLOCK_REALTIME_COARSE` - #[cfg(any(linux_kernel, target_os = "freebsd"))] - #[doc(alias = "CLOCK_REALTIME_COARSE")] - RealtimeCoarse = c::CLOCK_REALTIME_COARSE, - - /// `CLOCK_MONOTONIC_COARSE` - #[cfg(any(linux_kernel, target_os = "freebsd"))] - #[doc(alias = "CLOCK_MONOTONIC_COARSE")] - MonotonicCoarse = c::CLOCK_MONOTONIC_COARSE, - - /// `CLOCK_MONOTONIC_RAW` - #[cfg(linux_kernel)] - #[doc(alias = "CLOCK_MONOTONIC_RAW")] - MonotonicRaw = c::CLOCK_MONOTONIC_RAW, - - /// `CLOCK_REALTIME_ALARM` - #[cfg(linux_kernel)] - #[doc(alias = "CLOCK_REALTIME_ALARM")] - RealtimeAlarm = bitcast!(c::CLOCK_REALTIME_ALARM), - - /// `CLOCK_TAI`, available on Linux ≥ 3.10 - #[cfg(all(linux_kernel, feature = "linux_4_11"))] - #[doc(alias = "CLOCK_TAI")] - Tai = bitcast!(c::CLOCK_TAI), - - /// `CLOCK_BOOTTIME` - #[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "openbsd"))] - #[doc(alias = "CLOCK_BOOTTIME")] - Boottime = bitcast!(c::CLOCK_BOOTTIME), - - /// `CLOCK_BOOTTIME_ALARM` - #[cfg(any(linux_kernel, target_os = "fuchsia"))] - #[doc(alias = "CLOCK_BOOTTIME_ALARM")] - BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM), -} - -/// `CLOCK_*` constants for use with [`clock_gettime`]. -/// -/// These constants are always supported at runtime, so `clock_gettime` never -/// has to fail with `INVAL` due to an unsupported clock. See -/// [`DynamicClockId`] for a greater set of clocks, with the caveat that not -/// all of them are always supported. -/// -/// [`clock_gettime`]: crate::time::clock_gettime -#[cfg(apple)] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - #[doc(alias = "CLOCK_REALTIME")] - Realtime = c::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC` - #[doc(alias = "CLOCK_MONOTONIC")] - Monotonic = c::CLOCK_MONOTONIC, - - /// `CLOCK_PROCESS_CPUTIME_ID` - #[doc(alias = "CLOCK_PROCESS_CPUTIME_ID")] - ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, - - /// `CLOCK_THREAD_CPUTIME_ID` - #[doc(alias = "CLOCK_THREAD_CPUTIME_ID")] - ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, -} - -/// `CLOCK_*` constants for use with [`clock_gettime_dynamic`]. -/// -/// These constants may be unsupported at runtime, depending on the OS version, -/// and `clock_gettime_dynamic` may fail with `INVAL`. See [`ClockId`] for -/// clocks which are always supported at runtime. -/// -/// [`clock_gettime_dynamic`]: crate::time::clock_gettime_dynamic -#[cfg(not(target_os = "wasi"))] -#[derive(Debug, Copy, Clone)] -#[non_exhaustive] -pub enum DynamicClockId<'a> { - /// `ClockId` values that are always supported at runtime. - Known(ClockId), - - /// Linux dynamic clocks. - Dynamic(BorrowedFd<'a>), - - /// `CLOCK_REALTIME_ALARM` - #[cfg(linux_kernel)] - #[doc(alias = "CLOCK_REALTIME_ALARM")] - RealtimeAlarm, - - /// `CLOCK_TAI`, available on Linux ≥ 3.10 - #[cfg(linux_kernel)] - #[doc(alias = "CLOCK_TAI")] - Tai, - - /// `CLOCK_BOOTTIME` - #[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd" - ))] - #[doc(alias = "CLOCK_BOOTTIME")] - Boottime, - - /// `CLOCK_BOOTTIME_ALARM` - #[cfg(any(linux_kernel, target_os = "fuchsia"))] - #[doc(alias = "CLOCK_BOOTTIME_ALARM")] - BoottimeAlarm, -} diff --git a/vendor/rustix/src/cstr.rs b/vendor/rustix/src/cstr.rs deleted file mode 100644 index 75eb61b9..00000000 --- a/vendor/rustix/src/cstr.rs +++ /dev/null @@ -1,86 +0,0 @@ -/// A macro for [`CStr`] literals. -/// -/// This can make passing string literals to rustix APIs more efficient, since -/// most underlying system calls with string arguments expect NUL-terminated -/// strings, and passing strings to rustix as `CStr`s means that rustix doesn't -/// need to copy them into a separate buffer to NUL-terminate them. -/// -/// In Rust ≥ 1.77, users can use [C-string literals] instead of this macro. -/// -/// [`CStr`]: crate::ffi::CStr -/// [C-string literals]: https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html#c-string-literals -/// -/// # Examples -/// -/// ``` -/// # #[cfg(feature = "fs")] -/// # fn main() -> rustix::io::Result<()> { -/// use rustix::cstr; -/// use rustix::fs::{statat, AtFlags, CWD}; -/// -/// let metadata = statat(CWD, cstr!("Cargo.toml"), AtFlags::empty())?; -/// # Ok(()) -/// # } -/// # #[cfg(not(feature = "fs"))] -/// # fn main() {} -/// ``` -#[allow(unused_macros)] -#[macro_export] -macro_rules! cstr { - ($str:literal) => {{ - // Check for NUL manually, to ensure safety. - // - // In release builds, with strings that don't contain NULs, this - // constant-folds away. - // - // We don't use std's `CStr::from_bytes_with_nul`; as of this writing, - // that function isn't defined as `#[inline]` in std and doesn't - // constant-fold away. - assert!( - !$str.bytes().any(|b| b == b'\0'), - "cstr argument contains embedded NUL bytes", - ); - - #[allow(unsafe_code, unused_unsafe)] - { - // Now that we know the string doesn't have embedded NULs, we can - // call `from_bytes_with_nul_unchecked`, which as of this writing - // is defined as `#[inline]` and completely optimizes away. - // - // SAFETY: We have manually checked that the string does not - // contain embedded NULs above, and we append or own NUL terminator - // here. - unsafe { - $crate::ffi::CStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes()) - } - } - }}; -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - - #[test] - fn test_cstr() { - use crate::ffi::CString; - use alloc::borrow::ToOwned as _; - assert_eq!(cstr!(""), &*CString::new("").unwrap()); - assert_eq!(cstr!("").to_owned(), CString::new("").unwrap()); - assert_eq!(cstr!("hello"), &*CString::new("hello").unwrap()); - assert_eq!(cstr!("hello").to_owned(), CString::new("hello").unwrap()); - } - - #[test] - #[should_panic] - fn test_invalid_cstr() { - let _ = cstr!("hello\0world"); - } - - #[test] - #[should_panic] - fn test_invalid_empty_cstr() { - let _ = cstr!("\0"); - } -} diff --git a/vendor/rustix/src/event/epoll.rs b/vendor/rustix/src/event/epoll.rs deleted file mode 100644 index 839f05de..00000000 --- a/vendor/rustix/src/event/epoll.rs +++ /dev/null @@ -1,347 +0,0 @@ -//! Linux `epoll` support. -//! -//! # Examples -//! -//! ```no_run -//! # #[cfg(feature = "net")] -//! # fn main() -> std::io::Result<()> { -//! use rustix::buffer::spare_capacity; -//! use rustix::event::epoll; -//! use rustix::fd::AsFd; -//! use rustix::io::{ioctl_fionbio, read, write}; -//! use rustix::net::{ -//! accept, bind, listen, socket, AddressFamily, Ipv4Addr, SocketAddrV4, SocketType, -//! }; -//! use std::collections::HashMap; -//! use std::os::unix::io::AsRawFd; -//! -//! // Create a socket and listen on it. -//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, None)?; -//! bind(&listen_sock, &SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?; -//! listen(&listen_sock, 1)?; -//! -//! // Create an epoll object. Using `Owning` here means the epoll object will -//! // take ownership of the file descriptors registered with it. -//! let epoll = epoll::create(epoll::CreateFlags::CLOEXEC)?; -//! -//! // Register the socket with the epoll object. -//! epoll::add( -//! &epoll, -//! &listen_sock, -//! epoll::EventData::new_u64(1), -//! epoll::EventFlags::IN, -//! )?; -//! -//! // Keep track of the sockets we've opened. -//! let mut next_id = epoll::EventData::new_u64(2); -//! let mut sockets = HashMap::new(); -//! -//! // Process events. -//! let mut event_list = Vec::with_capacity(4); -//! loop { -//! epoll::wait(&epoll, spare_capacity(&mut event_list), None)?; -//! for event in event_list.drain(..) { -//! let target = event.data; -//! if target.u64() == 1 { -//! // Accept a new connection, set it to non-blocking, and -//! // register to be notified when it's ready to write to. -//! let conn_sock = accept(&listen_sock)?; -//! ioctl_fionbio(&conn_sock, true)?; -//! epoll::add( -//! &epoll, -//! &conn_sock, -//! next_id, -//! epoll::EventFlags::OUT | epoll::EventFlags::ET, -//! )?; -//! -//! // Keep track of the socket. -//! sockets.insert(next_id, conn_sock); -//! next_id = epoll::EventData::new_u64(next_id.u64() + 1); -//! } else { -//! // Write a message to the stream and then unregister it. -//! let target = sockets.remove(&target).unwrap(); -//! write(&target, b"hello\n")?; -//! let _ = epoll::delete(&epoll, &target)?; -//! } -//! } -//! } -//! # } -//! # #[cfg(not(feature = "net"))] -//! # fn main() {} -//! ``` - -#![allow(unsafe_code)] -#![allow(unused_qualifications)] - -use super::epoll; -pub use crate::backend::event::epoll::*; -use crate::backend::event::syscalls; -use crate::buffer::Buffer; -use crate::fd::{AsFd, OwnedFd}; -use crate::io; -use crate::timespec::Timespec; -use core::ffi::c_void; -use core::hash::{Hash, Hasher}; - -/// `epoll_create1(flags)`—Creates a new epoll object. -/// -/// Use the [`epoll::CreateFlags::CLOEXEC`] flag to prevent the resulting file -/// descriptor from being implicitly passed across `exec` boundaries. -/// -/// # References -/// - [Linux] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_create.2.html -/// [illumos]: https://www.illumos.org/man/3C/epoll_create -#[inline] -#[doc(alias = "epoll_create1")] -pub fn create(flags: epoll::CreateFlags) -> io::Result<OwnedFd> { - syscalls::epoll_create(flags) -} - -/// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an epoll -/// object. -/// -/// This registers interest in any of the events set in `event_flags` occurring -/// on the file descriptor associated with `data`. -/// -/// `close`ing a file descriptor does not necessarily unregister interest which -/// can lead to spurious events being returned from [`epoll::wait`]. If a file -/// descriptor is an `Arc<dyn SystemResource>`, then `epoll` can be thought to -/// maintain a `Weak<dyn SystemResource>` to the file descriptor. Check the -/// [faq] for details. -/// -/// # References -/// - [Linux] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html -/// [illumos]: https://www.illumos.org/man/3C/epoll_ctl -/// [faq]: https://man7.org/linux/man-pages/man7/epoll.7.html#:~:text=Will%20closing%20a%20file%20descriptor%20cause%20it%20to%20be%20removed%20from%20all%0A%20%20%20%20%20%20%20%20%20%20epoll%20interest%20lists%3F -#[doc(alias = "epoll_ctl")] -#[inline] -pub fn add<EpollFd: AsFd, SourceFd: AsFd>( - epoll: EpollFd, - source: SourceFd, - data: epoll::EventData, - event_flags: epoll::EventFlags, -) -> io::Result<()> { - syscalls::epoll_add( - epoll.as_fd(), - source.as_fd(), - &Event { - flags: event_flags, - data, - #[cfg(all(libc, target_os = "redox"))] - _pad: 0, - }, - ) -} - -/// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in a -/// given epoll object. -/// -/// This sets the events of interest with `target` to `events`. -/// -/// # References -/// - [Linux] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html -/// [illumos]: https://www.illumos.org/man/3C/epoll_ctl -#[doc(alias = "epoll_ctl")] -#[inline] -pub fn modify<EpollFd: AsFd, SourceFd: AsFd>( - epoll: EpollFd, - source: SourceFd, - data: epoll::EventData, - event_flags: epoll::EventFlags, -) -> io::Result<()> { - syscalls::epoll_mod( - epoll.as_fd(), - source.as_fd(), - &Event { - flags: event_flags, - data, - #[cfg(all(libc, target_os = "redox"))] - _pad: 0, - }, - ) -} - -/// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in a -/// given epoll object. -/// -/// # References -/// - [Linux] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_ctl.2.html -/// [illumos]: https://www.illumos.org/man/3C/epoll_ctl -#[doc(alias = "epoll_ctl")] -#[inline] -pub fn delete<EpollFd: AsFd, SourceFd: AsFd>(epoll: EpollFd, source: SourceFd) -> io::Result<()> { - syscalls::epoll_del(epoll.as_fd(), source.as_fd()) -} - -/// `epoll_wait(self, events, timeout)`—Waits for registered events of -/// interest. -/// -/// For each event of interest, an element is written to `events`. -/// -/// Linux versions older than 5.11 (those that don't support `epoll_pwait2`) -/// don't support timeouts greater than `c_int::MAX` milliseconds; if an -/// unsupported timeout is passed, this function fails with -/// [`io::Errno::INVAL`]. Enable the "linux_5_11" feature to enable the full -/// range of timeouts. -/// -/// # References -/// - [Linux] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/epoll_wait.2.html -/// [illumos]: https://www.illumos.org/man/3C/epoll_wait -#[doc(alias = "epoll_wait")] -#[inline] -pub fn wait<EpollFd: AsFd, Buf: Buffer<Event>>( - epoll: EpollFd, - mut event_list: Buf, - timeout: Option<&Timespec>, -) -> io::Result<Buf::Output> { - // SAFETY: `epoll_wait` behaves. - let nfds = unsafe { syscalls::epoll_wait(epoll.as_fd(), event_list.parts_mut(), timeout)? }; - // SAFETY: `epoll_wait` behaves. - unsafe { Ok(event_list.assume_init(nfds)) } -} - -/// A record of an event that occurred. -#[repr(C)] -#[cfg_attr(all(not(libc), target_arch = "x86_64"), repr(packed))] -#[cfg_attr( - all( - libc, - linux_kernel, - any( - all( - target_arch = "x86", - not(target_env = "musl"), - not(target_os = "android"), - ), - target_arch = "x86_64", - ) - ), - repr(packed) -)] -#[cfg_attr( - all(solarish, any(target_arch = "x86", target_arch = "x86_64")), - repr(packed(4)) -)] -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct Event { - /// Which specific event(s) occurred. - pub flags: EventFlags, - /// User data. - pub data: EventData, - - #[cfg(all(libc, target_os = "redox"))] - _pad: u64, -} - -/// Data associated with an [`epoll::Event`]. This can either be a 64-bit -/// integer value or a pointer which preserves pointer provenance. -#[repr(C)] -#[derive(Copy, Clone)] -pub union EventData { - /// A 64-bit integer value. - as_u64: u64, - - /// A `*mut c_void` which preserves pointer provenance, extended to be - /// 64-bit so that if we read the value as a `u64` union field, we don't - /// get uninitialized memory. - sixty_four_bit_pointer: SixtyFourBitPointer, -} - -impl EventData { - /// Construct a new value containing a `u64`. - #[inline] - pub const fn new_u64(value: u64) -> Self { - Self { as_u64: value } - } - - /// Construct a new value containing a `*mut c_void`. - #[inline] - pub const fn new_ptr(value: *mut c_void) -> Self { - Self { - sixty_four_bit_pointer: SixtyFourBitPointer { - pointer: value, - #[cfg(target_pointer_width = "32")] - _padding: 0, - }, - } - } - - /// Return the value as a `u64`. - /// - /// If the stored value was a pointer, the pointer is zero-extended to a - /// `u64`. - #[inline] - pub fn u64(self) -> u64 { - unsafe { self.as_u64 } - } - - /// Return the value as a `*mut c_void`. - /// - /// If the stored value was a `u64`, the least-significant bits of the - /// `u64` are returned as a pointer value. - #[inline] - pub fn ptr(self) -> *mut c_void { - unsafe { self.sixty_four_bit_pointer.pointer } - } -} - -impl PartialEq for EventData { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.u64() == other.u64() - } -} - -impl Eq for EventData {} - -impl Hash for EventData { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - self.u64().hash(state) - } -} - -#[repr(C)] -#[derive(Copy, Clone)] -struct SixtyFourBitPointer { - #[cfg(target_endian = "big")] - #[cfg(target_pointer_width = "32")] - _padding: u32, - - pointer: *mut c_void, - - #[cfg(target_endian = "little")] - #[cfg(target_pointer_width = "32")] - _padding: u32, -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::backend::c; - - #[test] - fn test_epoll_layouts() { - check_renamed_type!(Event, epoll_event); - check_renamed_struct_renamed_field!(Event, epoll_event, flags, events); - #[cfg(libc)] - check_renamed_struct_renamed_field!(Event, epoll_event, data, u64); - #[cfg(not(libc))] - check_renamed_struct_renamed_field!(Event, epoll_event, data, data); - } -} diff --git a/vendor/rustix/src/event/eventfd.rs b/vendor/rustix/src/event/eventfd.rs deleted file mode 100644 index a76f2cfc..00000000 --- a/vendor/rustix/src/event/eventfd.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::fd::OwnedFd; -use crate::{backend, io}; - -pub use backend::event::types::EventfdFlags; - -/// `eventfd(initval, flags)`—Creates a file descriptor for event -/// notification. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/eventfd.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?eventfd -/// [illumos]: https://illumos.org/man/3C/eventfd -#[inline] -pub fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { - backend::event::syscalls::eventfd(initval, flags) -} diff --git a/vendor/rustix/src/event/kqueue.rs b/vendor/rustix/src/event/kqueue.rs deleted file mode 100644 index 897d9398..00000000 --- a/vendor/rustix/src/event/kqueue.rs +++ /dev/null @@ -1,466 +0,0 @@ -//! An API for interfacing with `kqueue`. - -use crate::buffer::Buffer; -use crate::fd::{AsFd, OwnedFd, RawFd}; -use crate::pid::Pid; -use crate::signal::Signal; -use crate::timespec::Timespec; -use crate::{backend, io}; - -use backend::c::{self, intptr_t, kevent as kevent_t, uintptr_t}; -use backend::event::syscalls; - -use core::mem::zeroed; -use core::time::Duration; - -/// A `kqueue` event for use with [`kevent`]. -#[repr(transparent)] -#[derive(Copy, Clone)] -pub struct Event { - // The layout varies between BSDs and macOS. - inner: kevent_t, -} - -impl Event { - /// Create a new `Event`. - #[allow(clippy::needless_update)] - pub fn new(filter: EventFilter, flags: EventFlags, udata: *mut c::c_void) -> Event { - let (ident, data, filter, fflags) = match filter { - EventFilter::Read(fd) => (fd as uintptr_t, 0, c::EVFILT_READ, 0), - EventFilter::Write(fd) => (fd as _, 0, c::EVFILT_WRITE, 0), - #[cfg(target_os = "freebsd")] - EventFilter::Empty(fd) => (fd as _, 0, c::EVFILT_EMPTY, 0), - EventFilter::Vnode { vnode, flags } => (vnode as _, 0, c::EVFILT_VNODE, flags.bits()), - EventFilter::Proc { pid, flags } => { - (Pid::as_raw(Some(pid)) as _, 0, c::EVFILT_PROC, flags.bits()) - } - EventFilter::Signal { signal, times: _ } => { - (signal.as_raw() as _, 0, c::EVFILT_SIGNAL, 0) - } - EventFilter::Timer { ident, timer } => { - #[cfg(any(apple, target_os = "freebsd", target_os = "netbsd"))] - let (data, fflags) = match timer { - Some(timer) => { - if timer.subsec_millis() == 0 { - (timer.as_secs() as _, c::NOTE_SECONDS) - } else if timer.subsec_nanos() == 0 { - (timer.as_micros() as _, c::NOTE_USECONDS) - } else { - (timer.as_nanos() as _, c::NOTE_NSECONDS) - } - } - None => (intptr_t::MAX, c::NOTE_SECONDS), - }; - #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] - let (data, fflags) = match timer { - Some(timer) => (timer.as_millis() as _, 0), - None => (intptr_t::MAX, 0), - }; - - (ident as _, data, c::EVFILT_TIMER, fflags) - } - #[cfg(any(apple, freebsdlike))] - EventFilter::User { - ident, - flags, - user_flags, - } => (ident as _, 0, c::EVFILT_USER, flags.bits() | user_flags.0), - EventFilter::Unknown => panic!("unknown filter"), - }; - - Event { - inner: kevent_t { - ident, - filter: filter as _, - flags: flags.bits() as _, - fflags, - data: { - // On OpenBSD, data is an `i64` and not an `isize`. - data as _ - }, - udata: { - // On NetBSD, udata is an `isize` and not a pointer. - udata as _ - }, - ..unsafe { zeroed() } - }, - } - } - - /// Get the event flags for this event. - pub fn flags(&self) -> EventFlags { - EventFlags::from_bits_retain(self.inner.flags as _) - } - - /// Get the user data for this event. - pub fn udata(&self) -> *mut c::c_void { - // On NetBSD, udata is an isize and not a pointer. - self.inner.udata as _ - } - - /// Get the raw data for this event. - pub fn data(&self) -> i64 { - // On some BSDs, data is an `isize` and not an `i64`. - self.inner.data as _ - } - - /// Get the filter of this event. - pub fn filter(&self) -> EventFilter { - match self.inner.filter as _ { - c::EVFILT_READ => EventFilter::Read(self.inner.ident as _), - c::EVFILT_WRITE => EventFilter::Write(self.inner.ident as _), - #[cfg(target_os = "freebsd")] - c::EVFILT_EMPTY => EventFilter::Empty(self.inner.ident as _), - c::EVFILT_VNODE => EventFilter::Vnode { - vnode: self.inner.ident as _, - flags: VnodeEvents::from_bits_retain(self.inner.fflags), - }, - c::EVFILT_PROC => EventFilter::Proc { - pid: Pid::from_raw(self.inner.ident as _).unwrap(), - flags: ProcessEvents::from_bits_retain(self.inner.fflags), - }, - c::EVFILT_SIGNAL => EventFilter::Signal { - // SAFETY: `EventFilter::new` requires a valid `Signal`. - signal: unsafe { Signal::from_raw_unchecked(self.inner.ident as _) }, - times: self.inner.data as _, - }, - c::EVFILT_TIMER => EventFilter::Timer { - ident: self.inner.ident as _, - timer: { - let (data, fflags) = (self.inner.data, self.inner.fflags); - #[cfg(not(any(apple, target_os = "freebsd", target_os = "netbsd")))] - let _ = fflags; - #[cfg(any(apple, target_os = "freebsd", target_os = "netbsd"))] - match fflags as _ { - c::NOTE_SECONDS => Some(Duration::from_secs(data as _)), - c::NOTE_USECONDS => Some(Duration::from_micros(data as _)), - c::NOTE_NSECONDS => Some(Duration::from_nanos(data as _)), - _ => { - // Unknown timer flags. - None - } - } - #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] - Some(Duration::from_millis(data as _)) - }, - }, - #[cfg(any(apple, freebsdlike))] - c::EVFILT_USER => EventFilter::User { - ident: self.inner.ident as _, - flags: UserFlags::from_bits_retain(self.inner.fflags), - user_flags: UserDefinedFlags(self.inner.fflags & EVFILT_USER_FLAGS), - }, - _ => EventFilter::Unknown, - } - } -} - -/// Bottom 24 bits of a `u32`. -#[cfg(any(apple, freebsdlike))] -const EVFILT_USER_FLAGS: u32 = 0x00ff_ffff; - -/// The possible filters for a `kqueue`. -#[repr(i16)] -#[non_exhaustive] -pub enum EventFilter { - /// A read filter. - Read(RawFd), - - /// A write filter. - Write(RawFd), - - /// An empty filter. - #[cfg(target_os = "freebsd")] - Empty(RawFd), - - /// A VNode filter. - Vnode { - /// The file descriptor we looked for events in. - vnode: RawFd, - - /// The flags for this event. - flags: VnodeEvents, - }, - - /// A process filter. - Proc { - /// The process ID we waited on. - pid: Pid, - - /// The flags for this event. - flags: ProcessEvents, - }, - - /// A signal filter. - Signal { - /// The signal number we waited on. - signal: Signal, - - /// The number of times the signal has been received since the last - /// call to kevent. - times: usize, - }, - - /// A timer filter. - Timer { - /// The identifier for this event. - ident: intptr_t, - - /// The duration for this event. - timer: Option<Duration>, - }, - - /// A user filter. - #[cfg(any(apple, freebsdlike))] - User { - /// The identifier for this event. - ident: intptr_t, - - /// The flags for this event. - flags: UserFlags, - - /// The user-defined flags for this event. - user_flags: UserDefinedFlags, - }, - - /// This filter is unknown. - /// - /// # Panics - /// - /// Passing this into `Event::new()` will result in a panic. - Unknown, -} - -bitflags::bitflags! { - /// The flags for a `kqueue` event specifying actions to perform. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct EventFlags: u16 { - /// Add the event to the `kqueue`. - const ADD = c::EV_ADD as _; - - /// Enable the event. - const ENABLE = c::EV_ENABLE as _; - - /// Disable the event. - const DISABLE = c::EV_DISABLE as _; - - /// Delete the event from the `kqueue`. - const DELETE = c::EV_DELETE as _; - - /// TODO - const RECEIPT = c::EV_RECEIPT as _; - - /// Clear the event after it is triggered. - const ONESHOT = c::EV_ONESHOT as _; - - /// TODO - const CLEAR = c::EV_CLEAR as _; - - /// TODO - const EOF = c::EV_EOF as _; - - /// TODO - const ERROR = c::EV_ERROR as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// The flags for a virtual node event. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct VnodeEvents: u32 { - /// The file was deleted. - const DELETE = c::NOTE_DELETE; - - /// The file was written to. - const WRITE = c::NOTE_WRITE; - - /// The file was extended. - const EXTEND = c::NOTE_EXTEND; - - /// The file had its attributes changed. - const ATTRIBUTES = c::NOTE_ATTRIB; - - /// The file was renamed. - const RENAME = c::NOTE_RENAME; - - /// Access to the file was revoked. - const REVOKE = c::NOTE_REVOKE; - - /// The link count of the file has changed. - const LINK = c::NOTE_LINK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// The flags for a process event. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ProcessEvents: u32 { - /// The process exited. - const EXIT = c::NOTE_EXIT; - - /// The process forked itself. - const FORK = c::NOTE_FORK; - - /// The process executed a new process. - const EXEC = c::NOTE_EXEC; - - /// Follow the process through `fork` calls (write only). - const TRACK = c::NOTE_TRACK; - - /// An error has occurred with following the process. - const TRACKERR = c::NOTE_TRACKERR; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(any(apple, freebsdlike))] -bitflags::bitflags! { - /// The flags for a user event. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UserFlags: u32 { - /// Ignore the user input flags. - #[doc(alias = "NOP")] - const NOINPUT = c::NOTE_FFNOP; - - /// Bitwise AND `fflags`. - const AND = c::NOTE_FFAND; - - /// Bitwise OR `fflags`. - const OR = c::NOTE_FFOR; - - /// Copy `fflags`. - const COPY = c::NOTE_FFCOPY; - - /// Control mask for operations. - const CTRLMASK = c::NOTE_FFCTRLMASK; - - /// User defined flags for masks. - const UDFMASK = c::NOTE_FFLAGSMASK; - - /// Trigger the event. - const TRIGGER = c::NOTE_TRIGGER; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// User-defined flags. -/// -/// Only the lower 24 bits are used in this struct. -#[repr(transparent)] -#[cfg(any(apple, freebsdlike))] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct UserDefinedFlags(u32); - -#[cfg(any(apple, freebsdlike))] -impl UserDefinedFlags { - /// Create a new `UserDefinedFlags` from a `u32`. - pub fn new(flags: u32) -> Self { - Self(flags & EVFILT_USER_FLAGS) - } - - /// Get the underlying `u32`. - pub fn get(self) -> u32 { - self.0 - } -} - -/// `kqueue()`—Create a new `kqueue` file descriptor. -/// -/// # References -/// - [Apple] -/// - [FreeBSD] -/// - [OpenBSD] -/// - [NetBSD] -/// - [DragonFly BSD] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kqueue.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 -/// [OpenBSD]: https://man.openbsd.org/kqueue.2 -/// [NetBSD]: https://man.netbsd.org/kqueue.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=kqueue§ion=2 -pub fn kqueue() -> io::Result<OwnedFd> { - syscalls::kqueue() -} - -/// `kevent(kqueue, changelist, eventlist, timeout)`—Wait for events on a -/// `kqueue`. -/// -/// If an unsupported timeout is passed, this function fails with -/// [`io::Errno::INVAL`]. -/// -/// # Safety -/// -/// The file descriptors referred to by the `Event` structs must be valid for -/// the lifetime of the `kqueue` file descriptor. -/// -/// # References -/// - [Apple] -/// - [FreeBSD] -/// - [OpenBSD] -/// - [NetBSD] -/// - [DragonFly BSD] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kevent.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=kevent&sektion=2 -/// [OpenBSD]: https://man.openbsd.org/kevent.2 -/// [NetBSD]: https://man.netbsd.org/kevent.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=kevent§ion=2 -pub unsafe fn kevent_timespec<Fd: AsFd, Buf: Buffer<Event>>( - kqueue: Fd, - changelist: &[Event], - mut eventlist: Buf, - timeout: Option<&Timespec>, -) -> io::Result<Buf::Output> { - // Populate the event list with events. - let len = syscalls::kevent(kqueue.as_fd(), changelist, eventlist.parts_mut(), timeout) - .map(|res| res as _)?; - - Ok(eventlist.assume_init(len)) -} - -/// `kevent(kqueue, changelist, eventlist, timeout)`—Wait for events on a -/// `kqueue`. -/// -/// This is a wrapper around [`kevent_timespec`] which takes a `Duration` -/// instead of a `Timespec` for the timemout value. `Timespec` has a signed -/// `i64` seconds field; if converting `Duration` to `Timespec` overflows, -/// `None` is passed as the timeout instead, such such a large timeout would -/// be effectively infinite in practice. -/// -/// # Safety -/// -/// The file descriptors referred to by the `Event` structs must be valid for -/// the lifetime of the `kqueue` file descriptor. -pub unsafe fn kevent<Fd: AsFd, Buf: Buffer<Event>>( - kqueue: Fd, - changelist: &[Event], - eventlist: Buf, - timeout: Option<Duration>, -) -> io::Result<Buf::Output> { - let timeout = match timeout { - Some(timeout) => match timeout.as_secs().try_into() { - Ok(tv_sec) => Some(Timespec { - tv_sec, - tv_nsec: timeout.subsec_nanos() as _, - }), - Err(_) => None, - }, - None => None, - }; - - kevent_timespec(kqueue, changelist, eventlist, timeout.as_ref()) -} diff --git a/vendor/rustix/src/event/mod.rs b/vendor/rustix/src/event/mod.rs deleted file mode 100644 index 29dfc227..00000000 --- a/vendor/rustix/src/event/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Event operations. - -#[cfg(any(linux_kernel, target_os = "illumos", target_os = "redox"))] -pub mod epoll; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf" -))] -mod eventfd; -#[cfg(bsd)] -pub mod kqueue; -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] -mod pause; -mod poll; -#[cfg(solarish)] -pub mod port; -#[cfg(any(bsd, linux_kernel, windows, target_os = "wasi"))] -mod select; - -pub use crate::timespec::{Nsecs, Secs, Timespec}; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "illumos", - target_os = "espidf" -))] -pub use eventfd::{eventfd, EventfdFlags}; -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] -pub use pause::*; -pub use poll::{poll, PollFd, PollFlags}; -#[cfg(any(bsd, linux_kernel, windows, target_os = "wasi"))] -pub use select::*; diff --git a/vendor/rustix/src/event/pause.rs b/vendor/rustix/src/event/pause.rs deleted file mode 100644 index 41103011..00000000 --- a/vendor/rustix/src/event/pause.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::backend; - -/// `pause()`—Sleep until interrupted by a signal. -/// -/// The POSIX `pause` interface returns an error code, but the only thing -/// `pause` does is sleep until interrupted by a signal. If it were exposed in -/// the API here it would always return `Errno::INTR`, so for simplicity the -/// return value is omitted. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pause.html -/// [Linux]: https://man7.org/linux/man-pages/man2/pause.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/pause.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pause&sektion=3 -/// [NetBSD]: https://man.netbsd.org/pause.3 -/// [OpenBSD]: https://man.openbsd.org/pause.3 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pause§ion=3 -/// [illumos]: https://illumos.org/man/2/pause -#[inline] -pub fn pause() { - backend::event::syscalls::pause() -} diff --git a/vendor/rustix/src/event/poll.rs b/vendor/rustix/src/event/poll.rs deleted file mode 100644 index bf25fd5d..00000000 --- a/vendor/rustix/src/event/poll.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::event::Timespec; -use crate::{backend, io}; - -pub use backend::event::poll_fd::{PollFd, PollFlags}; - -/// `poll(self.fds, timeout)`—Wait for events on lists of file descriptors. -/// -/// Some platforms (those that don't support `ppoll`) don't support timeouts -/// greater than `c_int::MAX` milliseconds; if an unsupported timeout is -/// passed, this function fails with [`io::Errno::INVAL`]. -/// -/// On macOS, `poll` doesn't work on fds for /dev/tty or /dev/null, however -/// [`select`] is available and does work on these fds. -/// -/// [`select`]: crate::event::select() -/// -/// This function does not use the [`Buffer`] trait because the `fds` list is -/// both an input and output buffer. -/// -/// [`Buffer`]: crate::buffer::Buffer -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/slightly-advanced-techniques.html#poll -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/poll.html -/// [Linux]: https://man7.org/linux/man-pages/man2/poll.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/poll.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=poll&sektion=2 -/// [NetBSD]: https://man.netbsd.org/poll.2 -/// [OpenBSD]: https://man.openbsd.org/poll.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=poll§ion=2 -/// [illumos]: https://illumos.org/man/2/poll -#[inline] -pub fn poll(fds: &mut [PollFd<'_>], timeout: Option<&Timespec>) -> io::Result<usize> { - backend::event::syscalls::poll(fds, timeout) -} diff --git a/vendor/rustix/src/event/port.rs b/vendor/rustix/src/event/port.rs deleted file mode 100644 index 7cc5f939..00000000 --- a/vendor/rustix/src/event/port.rs +++ /dev/null @@ -1,197 +0,0 @@ -//! Solaris/illumos event ports. -//! -//! # Examples -//! -//! ``` -//! # fn test() -> std::io::Result<()> { -//! use rustix::event::port; -//! use rustix::stdio::stdout; -//! use std::io; -//! -//! let some_fd = stdout(); -//! let some_userdata = 7 as *mut _; -//! -//! // Create a port. -//! let port = port::create()?; -//! -//! // Associate `some_fd` with the port. -//! unsafe { -//! port::associate_fd(&port, some_fd, port::PollFlags::IN, some_userdata)?; -//! } -//! -//! // Get a single event. -//! let event = port::get(&port, None)?; -//! -//! assert_eq!(event.userdata(), some_userdata); -//! # Ok(()) -//! # } -//! ``` - -use crate::backend::c; -use crate::backend::event::syscalls; -use crate::buffer::Buffer; -use crate::fd::{AsFd, AsRawFd, OwnedFd}; -use crate::timespec::Timespec; -use crate::{ffi, io}; - -pub use super::PollFlags; - -/// The structure representing a port event. -#[repr(transparent)] -#[doc(alias = "port_event")] -pub struct Event(pub(crate) c::port_event); - -impl Event { - /// Get the events associated with this event. - pub fn events(&self) -> i32 { - self.0.portev_events - } - - /// Get the event source associated with this event. - pub fn object(&self) -> usize { - self.0.portev_object - } - - /// Get the userdata associated with this event. - pub fn userdata(&self) -> *mut ffi::c_void { - self.0.portev_user - } -} - -/// `port_create()`—Creates a new port. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_create/ -/// [illumos]: https://illumos.org/man/3C/port_create -#[doc(alias = "port_create")] -pub fn create() -> io::Result<OwnedFd> { - syscalls::port_create() -} - -/// `port_associate(_, PORT_SOURCE_FD, _, _, _)`—Associates a file descriptor -/// with a port. -/// -/// # Safety -/// -/// Any `object`s passed into the `port` must be valid for the lifetime of the -/// `port`. Logically, `port` keeps a borrowed reference to the `object` until -/// it is removed via [`dissociate_fd`]. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_associate/ -/// [illumos]: https://illumos.org/man/3C/port_associate -#[doc(alias = "port_associate")] -pub unsafe fn associate_fd<Fd: AsFd, RawFd: AsRawFd>( - port: Fd, - object: RawFd, - events: PollFlags, - userdata: *mut ffi::c_void, -) -> io::Result<()> { - syscalls::port_associate( - port.as_fd(), - c::PORT_SOURCE_FD, - object.as_raw_fd() as _, - events.bits() as _, - userdata.cast(), - ) -} - -/// `port_dissociate(_, PORT_SOURCE_FD, _)`—Dissociates a file descriptor -/// from a port. -/// -/// # Safety -/// -/// The file descriptor passed into this function must have been previously -/// associated with the port via [`associate_fd`]. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_dissociate -/// [illumos]: https://illumos.org/man/3C/port_dissociate -#[doc(alias = "port_dissociate")] -pub unsafe fn dissociate_fd<Fd: AsFd, RawFd: AsRawFd>(port: Fd, object: RawFd) -> io::Result<()> { - syscalls::port_dissociate(port.as_fd(), c::PORT_SOURCE_FD, object.as_raw_fd() as _) -} - -/// `port_get(port, timeout)`—Gets an event from a port. -/// -/// If an unsupported timeout is passed, this function fails with -/// [`io::Errno::INVAL`]. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_get/ -/// [illumos]: https://illumos.org/man/3C/port_get -#[doc(alias = "port_get")] -pub fn get<Fd: AsFd>(port: Fd, timeout: Option<&Timespec>) -> io::Result<Event> { - syscalls::port_get(port.as_fd(), timeout) -} - -/// `port_getn(port, events, min_events, timeout)`—Gets multiple events from -/// a port. -/// -/// If `events` is empty, this does nothing and returns immediately. -/// -/// To query the number of events without retrieving any, use [`getn_query`]. -/// -/// If an unsupported timeout is passed, this function fails with -/// [`io::Errno::INVAL`]. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_getn/ -/// [illumos]: https://illumos.org/man/3C/port_getn -#[doc(alias = "port_getn")] -pub fn getn<Fd: AsFd, Buf: Buffer<Event>>( - port: Fd, - mut events: Buf, - min_events: u32, - timeout: Option<&Timespec>, -) -> io::Result<Buf::Output> { - // SAFETY: `port_getn` behaves. - let nevents = - unsafe { syscalls::port_getn(port.as_fd(), events.parts_mut(), min_events, timeout)? }; - // SAFETY: `port_getn` behaves. - unsafe { Ok(events.assume_init(nevents)) } -} - -/// `port_getn(port, NULL, 0, NULL)`—Queries the number of events -/// available from a port. -/// -/// To retrieve the events, use [`getn`]. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_getn/ -/// [illumos]: https://illumos.org/man/3C/port_getn -#[doc(alias = "port_getn")] -pub fn getn_query<Fd: AsFd>(port: Fd) -> io::Result<u32> { - syscalls::port_getn_query(port.as_fd()) -} - -/// `port_send(port, events, userdata)`—Sends an event to a port. -/// -/// # References -/// - [OpenSolaris] -/// - [illumos] -/// -/// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_send/ -/// [illumos]: https://illumos.org/man/3C/port_send -#[doc(alias = "port_send")] -pub fn send<Fd: AsFd>(port: Fd, events: i32, userdata: *mut ffi::c_void) -> io::Result<()> { - syscalls::port_send(port.as_fd(), events, userdata.cast()) -} diff --git a/vendor/rustix/src/event/select.rs b/vendor/rustix/src/event/select.rs deleted file mode 100644 index 6bb93b53..00000000 --- a/vendor/rustix/src/event/select.rs +++ /dev/null @@ -1,391 +0,0 @@ -//! The `select` function. -//! -//! # Safety -//! -//! `select` is unsafe due to I/O safety. -#![allow(unsafe_code)] - -#[cfg(any(linux_like, target_os = "wasi"))] -use crate::backend::c; -use crate::event::Timespec; -use crate::fd::RawFd; -use crate::{backend, io}; -#[cfg(any(windows, target_os = "wasi"))] -use core::mem::align_of; -use core::mem::size_of; - -/// wasi-libc's `fd_set` type. The libc bindings for it have private fields, so -/// we redeclare it for ourselves so that we can access the fields. They're -/// publicly exposed in wasi-libc. -#[cfg(target_os = "wasi")] -#[repr(C)] -struct FD_SET { - /// The wasi-libc headers call this `__nfds`. - fd_count: usize, - /// The wasi-libc headers call this `__fds`. - fd_array: [i32; c::FD_SETSIZE], -} - -#[cfg(windows)] -use windows_sys::Win32::Networking::WinSock::FD_SET; - -/// Storage element type for use with [`select`]. -#[cfg(all( - target_pointer_width = "64", - any(windows, target_os = "freebsd", target_os = "dragonfly") -))] -#[repr(transparent)] -#[derive(Copy, Clone, Default)] -pub struct FdSetElement(pub(crate) u64); - -/// Storage element type for use with [`select`]. -#[cfg(linux_like)] -#[repr(transparent)] -#[derive(Copy, Clone, Default)] -pub struct FdSetElement(pub(crate) c::c_ulong); - -/// Storage element type for use with [`select`]. -#[cfg(not(any( - linux_like, - target_os = "wasi", - all( - target_pointer_width = "64", - any(windows, target_os = "freebsd", target_os = "dragonfly") - ) -)))] -#[repr(transparent)] -#[derive(Copy, Clone, Default)] -pub struct FdSetElement(pub(crate) u32); - -/// Storage element type for use with [`select`]. -#[cfg(target_os = "wasi")] -#[repr(transparent)] -#[derive(Copy, Clone, Default)] -pub struct FdSetElement(pub(crate) usize); - -/// `select(nfds, readfds, writefds, exceptfds, timeout)`—Wait for events on -/// sets of file descriptors. -/// -/// `readfds`, `writefds`, `exceptfds` must point to arrays of `FdSetElement` -/// containing at least `nfds.div_ceil(size_of::<FdSetElement>())` elements. -/// -/// If an unsupported timeout is passed, this function fails with -/// [`io::Errno::INVAL`]. -/// -/// This `select` wrapper differs from POSIX in that `nfds` is not limited to -/// `FD_SETSIZE`. Instead of using the fixed-sized `fd_set` type, this function -/// takes raw pointers to arrays of `fd_set_num_elements(max_fd + 1, num_fds)`, -/// where `max_fd` is the maximum value of any fd that will be inserted into -/// the set, and `num_fds` is the maximum number of fds that will be inserted -/// into the set. -/// -/// In particular, on Apple platforms, this function behaves as if -/// `_DARWIN_UNLIMITED_SELECT` were predefined. -/// -/// On illumos, this function is not defined because the `select` function on -/// this platform always has an `FD_SETSIZE` limitation, following POSIX. This -/// platform's documentation recommends using [`poll`] instead. -/// -/// [`fd_set_insert`], [`fd_set_remove`], and [`FdSetIter`] are provided for -/// setting, clearing, and iterating with sets. -/// -/// [`poll`]: crate::event::poll() -/// -/// # Safety -/// -/// All fds in all the sets must correspond to open file descriptors. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [Winsock] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/select.html -/// [Linux]: https://man7.org/linux/man-pages/man2/select.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/select.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=select&sektion=2 -/// [NetBSD]: https://man.netbsd.org/select.2 -/// [OpenBSD]: https://man.openbsd.org/select.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=select§ion=2 -/// [Winsock]: https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Waiting-for-I_002fO.html#index-select -pub unsafe fn select( - nfds: i32, - readfds: Option<&mut [FdSetElement]>, - writefds: Option<&mut [FdSetElement]>, - exceptfds: Option<&mut [FdSetElement]>, - timeout: Option<&Timespec>, -) -> io::Result<i32> { - backend::event::syscalls::select(nfds, readfds, writefds, exceptfds, timeout) -} - -#[cfg(not(any(windows, target_os = "wasi")))] -const BITS: usize = size_of::<FdSetElement>() * 8; - -/// Set `fd` in the set pointed to by `fds`. -#[doc(alias = "FD_SET")] -#[inline] -pub fn fd_set_insert(fds: &mut [FdSetElement], fd: RawFd) { - #[cfg(not(any(windows, target_os = "wasi")))] - { - let fd = fd as usize; - fds[fd / BITS].0 |= 1 << (fd % BITS); - } - - #[cfg(any(windows, target_os = "wasi"))] - { - let set = unsafe { &mut *fds.as_mut_ptr().cast::<FD_SET>() }; - let fd_count = set.fd_count; - let fd_array = &set.fd_array[..fd_count as usize]; - - if !fd_array.contains(&(fd as _)) { - let fd_array = &mut set.fd_array[..fd_count as usize + 1]; - set.fd_count = fd_count + 1; - fd_array[fd_count as usize] = fd as _; - } - } -} - -/// Clear `fd` in the set pointed to by `fds`. -#[doc(alias = "FD_CLR")] -#[inline] -pub fn fd_set_remove(fds: &mut [FdSetElement], fd: RawFd) { - #[cfg(not(any(windows, target_os = "wasi")))] - { - let fd = fd as usize; - fds[fd / BITS].0 &= !(1 << (fd % BITS)); - } - - #[cfg(any(windows, target_os = "wasi"))] - { - let set = unsafe { &mut *fds.as_mut_ptr().cast::<FD_SET>() }; - let fd_count = set.fd_count; - let fd_array = &set.fd_array[..fd_count as usize]; - - if let Some(pos) = fd_array.iter().position(|p| *p as RawFd == fd) { - set.fd_count = fd_count - 1; - set.fd_array[pos] = *set.fd_array.last().unwrap(); - } - } -} - -/// Compute the minimum `nfds` value needed for the set pointed to by `fds`. -#[inline] -pub fn fd_set_bound(fds: &[FdSetElement]) -> RawFd { - #[cfg(not(any(windows, target_os = "wasi")))] - { - if let Some(position) = fds.iter().rposition(|element| element.0 != 0) { - let element = fds[position].0; - (position * BITS + (BITS - element.leading_zeros() as usize)) as RawFd - } else { - 0 - } - } - - #[cfg(any(windows, target_os = "wasi"))] - { - let set = unsafe { &*fds.as_ptr().cast::<FD_SET>() }; - let fd_count = set.fd_count; - let fd_array = &set.fd_array[..fd_count as usize]; - let mut max = 0; - for fd in fd_array { - if *fd >= max { - max = *fd + 1; - } - } - max as RawFd - } -} - -/// Compute the number of `FdSetElement`s needed to hold a set which can -/// contain up to `set_count` file descriptors with values less than `nfds`. -#[inline] -pub fn fd_set_num_elements(set_count: usize, nfds: RawFd) -> usize { - #[cfg(any(windows, target_os = "wasi"))] - { - let _ = nfds; - - fd_set_num_elements_for_fd_array(set_count) - } - - #[cfg(not(any(windows, target_os = "wasi")))] - { - let _ = set_count; - - fd_set_num_elements_for_bitvector(nfds) - } -} - -/// `fd_set_num_elements` implementation on platforms with fd array -/// implementations. -#[cfg(any(windows, target_os = "wasi"))] -#[inline] -pub(crate) fn fd_set_num_elements_for_fd_array(set_count: usize) -> usize { - // Ensure that we always have a big enough set to dereference an `FD_SET`. - core::cmp::max( - fd_set_num_elements_for_fd_array_raw(set_count), - div_ceil(size_of::<FD_SET>(), size_of::<FdSetElement>()), - ) -} - -/// Compute the raw `fd_set_num_elements` value, before ensuring the value is -/// big enough to dereference an `FD_SET`. -#[cfg(any(windows, target_os = "wasi"))] -#[inline] -fn fd_set_num_elements_for_fd_array_raw(set_count: usize) -> usize { - // Allocate space for an `fd_count` field, plus `set_count` elements - // for the `fd_array` field. - div_ceil( - core::cmp::max(align_of::<FD_SET>(), align_of::<RawFd>()) + set_count * size_of::<RawFd>(), - size_of::<FdSetElement>(), - ) -} - -/// `fd_set_num_elements` implementation on platforms with bitvector -/// implementations. -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub(crate) fn fd_set_num_elements_for_bitvector(nfds: RawFd) -> usize { - // Allocate space for a dense bitvector for `nfds` bits. - let nfds = nfds as usize; - div_ceil(nfds, BITS) -} - -fn div_ceil(lhs: usize, rhs: usize) -> usize { - let d = lhs / rhs; - let r = lhs % rhs; - if r > 0 { - d + 1 - } else { - d - } -} - -/// An iterator over the fds in a set. -#[doc(alias = "FD_ISSET")] -#[cfg(not(any(windows, target_os = "wasi")))] -pub struct FdSetIter<'a> { - current: RawFd, - fds: &'a [FdSetElement], -} - -/// An iterator over the fds in a set. -#[doc(alias = "FD_ISSET")] -#[cfg(any(windows, target_os = "wasi"))] -pub struct FdSetIter<'a> { - current: usize, - fds: &'a [FdSetElement], -} - -impl<'a> FdSetIter<'a> { - /// Construct a `FdSetIter` for the given set. - pub fn new(fds: &'a [FdSetElement]) -> Self { - Self { current: 0, fds } - } -} - -#[cfg(not(any(windows, target_os = "wasi")))] -impl<'a> Iterator for FdSetIter<'a> { - type Item = RawFd; - - fn next(&mut self) -> Option<Self::Item> { - if let Some(element) = self.fds.get(self.current as usize / BITS) { - // Test whether the current element has more bits set. - let shifted = element.0 >> ((self.current as usize % BITS) as u32); - if shifted != 0 { - let fd = self.current + shifted.trailing_zeros() as RawFd; - self.current = fd + 1; - return Some(fd); - } - - // Search through the array for the next element with bits set. - if let Some(index) = self.fds[(self.current as usize / BITS) + 1..] - .iter() - .position(|element| element.0 != 0) - { - let index = index + (self.current as usize / BITS) + 1; - let element = self.fds[index].0; - let fd = (index * BITS) as RawFd + element.trailing_zeros() as RawFd; - self.current = fd + 1; - return Some(fd); - } - } - None - } -} - -#[cfg(any(windows, target_os = "wasi"))] -impl<'a> Iterator for FdSetIter<'a> { - type Item = RawFd; - - fn next(&mut self) -> Option<Self::Item> { - let current = self.current; - - let set = unsafe { &*self.fds.as_ptr().cast::<FD_SET>() }; - let fd_count = set.fd_count; - let fd_array = &set.fd_array[..fd_count as usize]; - - if current == fd_count as usize { - return None; - } - let fd = fd_array[current as usize]; - self.current = current + 1; - Some(fd as RawFd) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use core::mem::{align_of, size_of}; - - #[test] - #[cfg(any(windows, target_os = "wasi"))] - fn layouts() { - // The `FdSetElement` array should be suitably aligned. - assert_eq!(align_of::<FdSetElement>(), align_of::<FD_SET>()); - - // The layout of `FD_SET` should match our layout of a set of the same - // size. - assert_eq!( - fd_set_num_elements_for_fd_array_raw( - memoffset::span_of!(FD_SET, fd_array).len() / size_of::<RawFd>() - ) * size_of::<FdSetElement>(), - size_of::<FD_SET>() - ); - assert_eq!( - fd_set_num_elements_for_fd_array( - memoffset::span_of!(FD_SET, fd_array).len() / size_of::<RawFd>() - ) * size_of::<FdSetElement>(), - size_of::<FD_SET>() - ); - - // Don't create fd sets smaller than `FD_SET`. - assert_eq!( - fd_set_num_elements_for_fd_array(0) * size_of::<FdSetElement>(), - size_of::<FD_SET>() - ); - } - - #[test] - #[cfg(any(bsd, linux_kernel))] - fn layouts() { - use crate::backend::c; - - // The `FdSetElement` array should be suitably aligned. - assert_eq!(align_of::<FdSetElement>(), align_of::<c::fd_set>()); - - // The layout of `fd_set` should match our layout of a set of the same - // size. - assert_eq!( - fd_set_num_elements_for_bitvector(c::FD_SETSIZE as RawFd) * size_of::<FdSetElement>(), - size_of::<c::fd_set>() - ); - } -} diff --git a/vendor/rustix/src/ffi.rs b/vendor/rustix/src/ffi.rs deleted file mode 100644 index 073b6b12..00000000 --- a/vendor/rustix/src/ffi.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Utilities related to FFI bindings. - -// If we have std, use it. -#[cfg(not(windows))] -#[cfg(feature = "std")] -pub use std::ffi::{CStr, CString, FromBytesWithNulError, NulError}; -#[cfg(feature = "std")] -pub use std::os::raw::{ - c_char, c_int, c_long, c_longlong, c_short, c_uint, c_ulong, c_ulonglong, c_ushort, c_void, -}; - -// If we don't have std, we can depend on core and alloc having these features -// in Rust 1.64+. -#[cfg(not(windows))] -#[cfg(all(feature = "alloc", not(feature = "std")))] -pub use alloc::ffi::{CString, NulError}; -#[cfg(not(feature = "std"))] -pub use core::ffi::{ - c_char, c_int, c_long, c_longlong, c_short, c_uint, c_ulong, c_ulonglong, c_ushort, c_void, -}; -#[cfg(not(windows))] -#[cfg(not(feature = "std"))] -pub use core::ffi::{CStr, FromBytesWithNulError}; diff --git a/vendor/rustix/src/fs/abs.rs b/vendor/rustix/src/fs/abs.rs deleted file mode 100644 index 236a833a..00000000 --- a/vendor/rustix/src/fs/abs.rs +++ /dev/null @@ -1,304 +0,0 @@ -//! POSIX-style filesystem functions which operate on bare paths. - -use crate::fd::OwnedFd; -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -use crate::fs::Access; -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use crate::fs::StatFs; -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -use crate::fs::StatVfs; -use crate::fs::{Mode, OFlags, Stat}; -#[cfg(not(target_os = "wasi"))] -use crate::ugid::{Gid, Uid}; -use crate::{backend, io, path}; -#[cfg(feature = "alloc")] -use { - crate::ffi::{CStr, CString}, - crate::path::SMALL_PATH_BUFFER_SIZE, - alloc::vec::Vec, -}; - -/// `open(path, oflags, mode)`—Opens a file. -/// -/// POSIX guarantees that `open` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// The `Mode` argument is only significant when creating a file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/open.html -/// [Linux]: https://man7.org/linux/man-pages/man2/open.2.html -#[inline] -pub fn open<P: path::Arg>(path: P, flags: OFlags, mode: Mode) -> io::Result<OwnedFd> { - path.into_with_c_str(|path| backend::fs::syscalls::open(path, flags, mode)) -} - -/// `chmod(path, mode)`—Sets file or directory permissions. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chmod.html -/// [Linux]: https://man7.org/linux/man-pages/man2/chmod.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn chmod<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::chmod(path, mode)) -} - -/// `stat(path)`—Queries metadata for a file or directory. -/// -/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to -/// interpret the `st_mode` field. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/stat.2.html -/// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode -/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode -#[inline] -pub fn stat<P: path::Arg>(path: P) -> io::Result<Stat> { - path.into_with_c_str(backend::fs::syscalls::stat) -} - -/// `lstat(path)`—Queries metadata for a file or directory, without following -/// symlinks. -/// -/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to -/// interpret the `st_mode` field. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/lstat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/lstat.2.html -/// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode -/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode -#[inline] -pub fn lstat<P: path::Arg>(path: P) -> io::Result<Stat> { - path.into_with_c_str(backend::fs::syscalls::lstat) -} - -/// `readlink(path)`—Reads the contents of a symlink. -/// -/// If `reuse` is non-empty, reuse its buffer to store the result if possible. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlink.html -/// [Linux]: https://man7.org/linux/man-pages/man2/readlink.2.html -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -#[inline] -pub fn readlink<P: path::Arg, B: Into<Vec<u8>>>(path: P, reuse: B) -> io::Result<CString> { - path.into_with_c_str(|path| _readlink(path, reuse.into())) -} - -#[cfg(feature = "alloc")] -fn _readlink(path: &CStr, mut buffer: Vec<u8>) -> io::Result<CString> { - // This code would benefit from having a better way to read into - // uninitialized memory, but that requires `unsafe`. - buffer.clear(); - buffer.reserve(SMALL_PATH_BUFFER_SIZE); - buffer.resize(buffer.capacity(), 0_u8); - - loop { - let nread = backend::fs::syscalls::readlink(path, &mut buffer)?; - - let nread = nread as usize; - assert!(nread <= buffer.len()); - if nread < buffer.len() { - buffer.resize(nread, 0_u8); - return Ok(CString::new(buffer).unwrap()); - } - // Use `Vec` reallocation strategy to grow capacity exponentially. - buffer.reserve(1); - buffer.resize(buffer.capacity(), 0_u8); - } -} - -/// `rename(old_path, new_path)`—Renames a file or directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/rename.html -/// [Linux]: https://man7.org/linux/man-pages/man2/rename.2.html -#[inline] -pub fn rename<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| backend::fs::syscalls::rename(old_path, new_path)) - }) -} - -/// `unlink(path)`—Unlinks a file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlink.html -/// [Linux]: https://man7.org/linux/man-pages/man2/unlink.2.html -#[inline] -pub fn unlink<P: path::Arg>(path: P) -> io::Result<()> { - path.into_with_c_str(backend::fs::syscalls::unlink) -} - -/// `rmdir(path)`—Removes a directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/rmdir.html -/// [Linux]: https://man7.org/linux/man-pages/man2/rmdir.2.html -#[inline] -pub fn rmdir<P: path::Arg>(path: P) -> io::Result<()> { - path.into_with_c_str(backend::fs::syscalls::rmdir) -} - -/// `link(old_path, new_path)`—Creates a hard link. -/// -/// POSIX leaves it implementation-defined whether `link` follows a symlink in -/// `old_path`, or creates a new link to the symbolic link itself. On platforms -/// which have it, [`linkat`] avoids this problem since it has an [`AtFlags`] -/// parameter and the [`AtFlags::SYMLINK_FOLLOW`] flag determines whether -/// symlinks should be followed. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/link.html -/// [Linux]: https://man7.org/linux/man-pages/man2/link.2.html -/// [`linkat`]: crate::fs::linkat -/// [`AtFlags`]: crate::fs::AtFlags -/// [`AtFlags::SYMLINK_FOLLOW`]: crate::fs::AtFlags::SYMLINK_FOLLOW -#[inline] -pub fn link<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| backend::fs::syscalls::link(old_path, new_path)) - }) -} - -/// `symlink(old_path, new_path)`—Creates a symlink. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/symlink.html -/// [Linux]: https://man7.org/linux/man-pages/man2/symlink.2.html -#[inline] -pub fn symlink<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| backend::fs::syscalls::symlink(old_path, new_path)) - }) -} - -/// `mkdir(path, mode)`—Creates a directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdir.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mkdir.2.html -#[inline] -pub fn mkdir<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::mkdir(path, mode)) -} - -/// `access(path, access)`—Tests permissions for a file or directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/access.html -/// [Linux]: https://man7.org/linux/man-pages/man2/access.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -#[inline] -pub fn access<P: path::Arg>(path: P, access: Access) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::access(path, access)) -} - -/// `statfs`—Queries filesystem metadata. -/// -/// Compared to [`statvfs`], this function often provides more information, -/// though it's less portable. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/statfs.2.html -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub fn statfs<P: path::Arg>(path: P) -> io::Result<StatFs> { - path.into_with_c_str(backend::fs::syscalls::statfs) -} - -/// `statvfs`—Queries filesystem metadata, POSIX version. -/// -/// Compared to [`statfs`], this function often provides less information, but -/// it is more portable. But even so, filesystems are very diverse and not all -/// the fields are meaningful for every filesystem. And `f_fsid` doesn't seem -/// to have a clear meaning anywhere. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/statvfs.html -/// [Linux]: https://man7.org/linux/man-pages/man2/statvfs.2.html -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -#[inline] -pub fn statvfs<P: path::Arg>(path: P) -> io::Result<StatVfs> { - path.into_with_c_str(backend::fs::syscalls::statvfs) -} - -/// `chown(path, owner, group)`—Sets open file or directory ownership. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chown.html -/// [Linux]: https://man7.org/linux/man-pages/man2/chown.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn chown<P: path::Arg>(path: P, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::chown(path, owner, group)) -} diff --git a/vendor/rustix/src/fs/at.rs b/vendor/rustix/src/fs/at.rs deleted file mode 100644 index 4ad2df89..00000000 --- a/vendor/rustix/src/fs/at.rs +++ /dev/null @@ -1,494 +0,0 @@ -//! POSIX-style `*at` functions. -//! -//! The `dirfd` argument to these functions may be a file descriptor for a -//! directory, the special value [`CWD`], or the special value [`ABS`]. -//! -//! [`CWD`]: crate::fs::CWD -//! [`ABS`]: crate::fs::ABS - -#![allow(unsafe_code)] - -use crate::buffer::Buffer; -use crate::fd::OwnedFd; -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -use crate::fs::Access; -#[cfg(not(target_os = "espidf"))] -use crate::fs::AtFlags; -#[cfg(apple)] -use crate::fs::CloneFlags; -#[cfg(any(linux_kernel, apple))] -use crate::fs::RenameFlags; -#[cfg(not(target_os = "espidf"))] -use crate::fs::Stat; -#[cfg(not(any(apple, target_os = "espidf", target_os = "vita", target_os = "wasi")))] -use crate::fs::{Dev, FileType}; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -use crate::fs::{Gid, Uid}; -use crate::fs::{Mode, OFlags}; -use crate::{backend, io, path}; -use backend::fd::AsFd; -#[cfg(feature = "alloc")] -use { - crate::ffi::{CStr, CString}, - crate::path::SMALL_PATH_BUFFER_SIZE, - alloc::vec::Vec, - backend::fd::BorrowedFd, -}; -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] -use {crate::fs::Timestamps, crate::timespec::Nsecs}; - -/// `UTIME_NOW` for use with [`utimensat`]. -/// -/// [`utimensat`]: crate::fs::utimensat -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub const UTIME_NOW: Nsecs = backend::c::UTIME_NOW as Nsecs; - -/// `UTIME_OMIT` for use with [`utimensat`]. -/// -/// [`utimensat`]: crate::fs::utimensat -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub const UTIME_OMIT: Nsecs = backend::c::UTIME_OMIT as Nsecs; - -/// `openat(dirfd, path, oflags, mode)`—Opens a file. -/// -/// POSIX guarantees that `openat` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// The `Mode` argument is only significant when creating a file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/openat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/openat.2.html -#[inline] -pub fn openat<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - oflags: OFlags, - create_mode: Mode, -) -> io::Result<OwnedFd> { - path.into_with_c_str(|path| { - backend::fs::syscalls::openat(dirfd.as_fd(), path, oflags, create_mode) - }) -} - -/// `readlinkat(fd, path)`—Reads the contents of a symlink. -/// -/// If `reuse` already has available capacity, reuse it if possible. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlinkat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/readlinkat.2.html -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -#[inline] -pub fn readlinkat<P: path::Arg, Fd: AsFd, B: Into<Vec<u8>>>( - dirfd: Fd, - path: P, - reuse: B, -) -> io::Result<CString> { - path.into_with_c_str(|path| _readlinkat(dirfd.as_fd(), path, reuse.into())) -} - -#[cfg(feature = "alloc")] -#[allow(unsafe_code)] -fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec<u8>) -> io::Result<CString> { - buffer.clear(); - buffer.reserve(SMALL_PATH_BUFFER_SIZE); - - loop { - let buf = buffer.spare_capacity_mut(); - - // SAFETY: `readlinkat` behaves. - let nread = unsafe { - backend::fs::syscalls::readlinkat( - dirfd.as_fd(), - path, - (buf.as_mut_ptr().cast(), buf.len()), - )? - }; - - debug_assert!(nread <= buffer.capacity()); - if nread < buffer.capacity() { - // SAFETY: From the [documentation]: “On success, these calls - // return the number of bytes placed in buf.” - // - // [documentation]: https://man7.org/linux/man-pages/man2/readlinkat.2.html - unsafe { - buffer.set_len(nread); - } - - // SAFETY: - // - “readlink places the contents of the symbolic link pathname - // in the buffer buf” - // - [POSIX definition 3.271: Pathname]: “A string that is used - // to identify a file.” - // - [POSIX definition 3.375: String]: “A contiguous sequence of - // bytes terminated by and including the first null byte.” - // - “readlink does not append a terminating null byte to buf.” - // - // Thus, there will be no NUL bytes in the string. - // - // [POSIX definition 3.271: Pathname]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_271 - // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_375 - unsafe { - return Ok(CString::from_vec_unchecked(buffer)); - } - } - - // Use `Vec` reallocation strategy to grow capacity exponentially. - buffer.reserve(buffer.capacity() + 1); - } -} - -/// `readlinkat(fd, path)`—Reads the contents of a symlink, without -/// allocating. -/// -/// This is the "raw" version which avoids allocating, but which truncates the -/// string if it doesn't fit in the provided buffer, and doesn't NUL-terminate -/// the string. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlinkat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/readlinkat.2.html -#[inline] -pub fn readlinkat_raw<P: path::Arg, Fd: AsFd, Buf: Buffer<u8>>( - dirfd: Fd, - path: P, - mut buf: Buf, -) -> io::Result<Buf::Output> { - // SAFETY: `readlinkat` behaves. - let len = path.into_with_c_str(|path| unsafe { - backend::fs::syscalls::readlinkat(dirfd.as_fd(), path, buf.parts_mut()) - })?; - // SAFETY: `readlinkat` behaves. - unsafe { Ok(buf.assume_init(len)) } -} - -/// `mkdirat(fd, path, mode)`—Creates a directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdirat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mkdirat.2.html -#[inline] -pub fn mkdirat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode)) -} - -/// `linkat(old_dirfd, old_path, new_dirfd, new_path, flags)`—Creates a hard -/// link. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/linkat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/linkat.2.html -#[cfg(not(target_os = "espidf"))] -#[inline] -pub fn linkat<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>( - old_dirfd: PFd, - old_path: P, - new_dirfd: QFd, - new_path: Q, - flags: AtFlags, -) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| { - backend::fs::syscalls::linkat( - old_dirfd.as_fd(), - old_path, - new_dirfd.as_fd(), - new_path, - flags, - ) - }) - }) -} - -/// `unlinkat(fd, path, flags)`—Unlinks a file or remove a directory. -/// -/// With the [`REMOVEDIR`] flag, this removes a directory. This is in place of -/// a `rmdirat` function. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [`REMOVEDIR`]: AtFlags::REMOVEDIR -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlinkat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/unlinkat.2.html -#[cfg(not(target_os = "espidf"))] -#[inline] -pub fn unlinkat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, flags: AtFlags) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::unlinkat(dirfd.as_fd(), path, flags)) -} - -/// `renameat(old_dirfd, old_path, new_dirfd, new_path)`—Renames a file or -/// directory. -/// -/// See [`renameat_with`] to pass additional flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/renameat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/renameat.2.html -#[inline] -pub fn renameat<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>( - old_dirfd: PFd, - old_path: P, - new_dirfd: QFd, - new_path: Q, -) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| { - backend::fs::syscalls::renameat( - old_dirfd.as_fd(), - old_path, - new_dirfd.as_fd(), - new_path, - ) - }) - }) -} - -/// `renameat2(old_dirfd, old_path, new_dirfd, new_path, flags)`—Renames a -/// file or directory. -/// -/// `renameat_with` is the same as [`renameat`] but adds an additional -/// flags operand. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/renameat2.2.html -#[cfg(any(apple, linux_kernel))] -#[inline] -#[doc(alias = "renameat2")] -#[doc(alias = "renameatx_np")] -pub fn renameat_with<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>( - old_dirfd: PFd, - old_path: P, - new_dirfd: QFd, - new_path: Q, - flags: RenameFlags, -) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| { - backend::fs::syscalls::renameat2( - old_dirfd.as_fd(), - old_path, - new_dirfd.as_fd(), - new_path, - flags, - ) - }) - }) -} - -/// `symlinkat(old_path, new_dirfd, new_path)`—Creates a symlink. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/symlinkat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/symlinkat.2.html -#[inline] -pub fn symlinkat<P: path::Arg, Q: path::Arg, Fd: AsFd>( - old_path: P, - new_dirfd: Fd, - new_path: Q, -) -> io::Result<()> { - old_path.into_with_c_str(|old_path| { - new_path.into_with_c_str(|new_path| { - backend::fs::syscalls::symlinkat(old_path, new_dirfd.as_fd(), new_path) - }) - }) -} - -/// `fstatat(dirfd, path, flags)`—Queries metadata for a file or directory. -/// -/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to -/// interpret the `st_mode` field. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstatat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fstatat.2.html -/// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode -/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode -#[cfg(not(target_os = "espidf"))] -#[inline] -#[doc(alias = "fstatat")] -pub fn statat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, flags: AtFlags) -> io::Result<Stat> { - path.into_with_c_str(|path| backend::fs::syscalls::statat(dirfd.as_fd(), path, flags)) -} - -/// `faccessat(dirfd, path, access, flags)`—Tests permissions for a file or -/// directory. -/// -/// On Linux before 5.8, this function uses the `faccessat` system call which -/// doesn't support any flags. This function emulates support for the -/// [`AtFlags::EACCESS`] flag by checking whether the uid and gid of the -/// process match the effective uid and gid, in which case the `EACCESS` flag -/// can be ignored. In Linux 5.8 and beyond `faccessat2` is used, which -/// supports flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/faccessat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/faccessat.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -#[inline] -#[doc(alias = "faccessat")] -pub fn accessat<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - access: Access, - flags: AtFlags, -) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::accessat(dirfd.as_fd(), path, access, flags)) -} - -/// `utimensat(dirfd, path, times, flags)`—Sets file or directory timestamps. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/utimensat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -#[inline] -pub fn utimensat<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::utimensat(dirfd.as_fd(), path, times, flags)) -} - -/// `fchmodat(dirfd, path, mode, flags)`—Sets file or directory permissions. -/// -/// Platform support for flags varies widely, for example on Linux -/// [`AtFlags::SYMLINK_NOFOLLOW`] is not implemented and therefore -/// [`io::Errno::OPNOTSUPP`] will be returned. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchmodat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fchmodat.2.html -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -#[doc(alias = "fchmodat")] -pub fn chmodat<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - mode: Mode, - flags: AtFlags, -) -> io::Result<()> { - path.into_with_c_str(|path| backend::fs::syscalls::chmodat(dirfd.as_fd(), path, mode, flags)) -} - -/// `fclonefileat(src, dst_dir, dst, flags)`—Efficiently copies between files. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/clonefile.2 -#[cfg(apple)] -#[inline] -pub fn fclonefileat<Fd: AsFd, DstFd: AsFd, P: path::Arg>( - src: Fd, - dst_dir: DstFd, - dst: P, - flags: CloneFlags, -) -> io::Result<()> { - dst.into_with_c_str(|dst| { - backend::fs::syscalls::fclonefileat(src.as_fd(), dst_dir.as_fd(), dst, flags) - }) -} - -/// `mknodat(dirfd, path, mode, dev)`—Creates special or normal files. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mknodat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mknodat.2.html -#[cfg(not(any( - apple, - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub fn mknodat<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - file_type: FileType, - mode: Mode, - dev: Dev, -) -> io::Result<()> { - path.into_with_c_str(|path| { - backend::fs::syscalls::mknodat(dirfd.as_fd(), path, file_type, mode, dev) - }) -} - -/// `fchownat(dirfd, path, owner, group, flags)`—Sets file or directory -/// ownership. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchownat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fchownat.2.html -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -#[doc(alias = "fchownat")] -pub fn chownat<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - owner: Option<Uid>, - group: Option<Gid>, - flags: AtFlags, -) -> io::Result<()> { - path.into_with_c_str(|path| { - backend::fs::syscalls::chownat(dirfd.as_fd(), path, owner, group, flags) - }) -} diff --git a/vendor/rustix/src/fs/constants.rs b/vendor/rustix/src/fs/constants.rs deleted file mode 100644 index 5f106342..00000000 --- a/vendor/rustix/src/fs/constants.rs +++ /dev/null @@ -1,355 +0,0 @@ -//! Filesystem API constants, translated into `bitflags` constants. - -use crate::backend; - -pub use crate::timespec::{Nsecs, Secs, Timespec}; -pub use backend::fs::types::*; - -impl FileType { - /// Returns `true` if this `FileType` is a regular file. - pub fn is_file(self) -> bool { - self == Self::RegularFile - } - - /// Returns `true` if this `FileType` is a directory. - pub fn is_dir(self) -> bool { - self == Self::Directory - } - - /// Returns `true` if this `FileType` is a symlink. - pub fn is_symlink(self) -> bool { - self == Self::Symlink - } - - /// Returns `true` if this `FileType` is a fifo. - #[cfg(not(target_os = "wasi"))] - pub fn is_fifo(self) -> bool { - self == Self::Fifo - } - - /// Returns `true` if this `FileType` is a socket. - #[cfg(not(target_os = "wasi"))] - pub fn is_socket(self) -> bool { - self == Self::Socket - } - - /// Returns `true` if this `FileType` is a character device. - pub fn is_char_device(self) -> bool { - self == Self::CharacterDevice - } - - /// Returns `true` if this `FileType` is a block device. - pub fn is_block_device(self) -> bool { - self == Self::BlockDevice - } -} - -#[cfg(test)] -#[allow(unused_imports)] -#[allow(unsafe_code)] -mod tests { - use super::*; - use crate::backend::c; - // Rust's libc crate lacks statx for Non-glibc targets. - #[cfg(all(target_os = "linux", target_env = "gnu"))] - use crate::fs::{Statx, StatxTimestamp}; - - #[test] - fn test_layouts() { - #[cfg(linux_kernel)] - assert_eq_size!(FsWord, linux_raw_sys::general::__fsword_t); - - // Don't test against `__kernel_mode_t` on platforms where it's a - // `u16`. - #[cfg(linux_kernel)] - #[cfg(not(any( - target_arch = "x86", - target_arch = "sparc", - target_arch = "avr", - target_arch = "arm", - )))] - assert_eq_size!(RawMode, linux_raw_sys::general::__kernel_mode_t); - - #[cfg(linux_kernel)] - #[cfg(any( - target_arch = "x86", - target_arch = "sparc", - target_arch = "avr", - target_arch = "arm", - ))] - assert_eq_size!(u16, linux_raw_sys::general::__kernel_mode_t); - - let some_stat: Stat = unsafe { core::mem::zeroed() }; - - // Ensure that seconds fields are 64-bit on non-y2038-bug platforms, and - // on Linux where we use statx. - #[cfg(any(linux_kernel, not(fix_y2038)))] - { - assert_eq!(some_stat.st_atime, 0_i64); - assert_eq!(some_stat.st_mtime, 0_i64); - assert_eq!(some_stat.st_ctime, 0_i64); - } - - // Ensure that file offsets are 64-bit. - assert_eq!(some_stat.st_size, 0_i64); - - // Check that various fields match expected types. - assert_eq!(some_stat.st_mode, 0 as RawMode); - assert_eq!(some_stat.st_dev, 0 as Dev); - assert_eq!(some_stat.st_rdev, 0 as Dev); - assert_eq!(some_stat.st_uid, 0 as crate::ugid::RawUid); - assert_eq!(some_stat.st_gid, 0 as crate::ugid::RawGid); - - // `Stat` should match `c::stat` or `c::stat64` unless we need y2038 - // fixes and are using a different layout. - #[cfg(not(any( - all(libc, linux_kernel, target_pointer_width = "32"), - all( - linux_raw, - any( - target_pointer_width = "32", - target_arch = "mips64", - target_arch = "mips64r6" - ) - ) - )))] - { - // Check that `Stat` matches `c::stat`. - #[cfg(not(all( - libc, - any( - all(linux_kernel, target_pointer_width = "64"), - target_os = "hurd", - target_os = "emscripten", - target_os = "l4re", - ) - )))] - { - check_renamed_type!(Stat, stat); - check_renamed_struct_field!(Stat, stat, st_dev); - check_renamed_struct_field!(Stat, stat, st_ino); - check_renamed_struct_field!(Stat, stat, st_nlink); - check_renamed_struct_field!(Stat, stat, st_mode); - check_renamed_struct_field!(Stat, stat, st_uid); - check_renamed_struct_field!(Stat, stat, st_gid); - #[cfg(all( - linux_raw, - not(any( - target_arch = "aarch64", - target_arch = "powerpc64", - target_arch = "riscv64", - target_arch = "s390x" - )) - ))] - check_renamed_struct_field!(Stat, stat, __pad0); - check_renamed_struct_field!(Stat, stat, st_rdev); - #[cfg(all(linux_raw, not(any(target_arch = "powerpc64", target_arch = "x86_64"))))] - check_renamed_struct_field!(Stat, stat, __pad1); - check_renamed_struct_field!(Stat, stat, st_size); - check_renamed_struct_field!(Stat, stat, st_blksize); - #[cfg(all( - linux_raw, - not(any( - target_arch = "powerpc64", - target_arch = "s390x", - target_arch = "x86_64" - )) - ))] - check_renamed_struct_field!(Stat, stat, __pad2); - check_renamed_struct_field!(Stat, stat, st_blocks); - check_renamed_struct_field!(Stat, stat, st_atime); - #[cfg(not(target_os = "netbsd"))] - check_renamed_struct_field!(Stat, stat, st_atime_nsec); - #[cfg(target_os = "netbsd")] - check_renamed_struct_renamed_field!(Stat, stat, st_atime_nsec, st_atimensec); - check_renamed_struct_field!(Stat, stat, st_mtime); - #[cfg(not(target_os = "netbsd"))] - check_renamed_struct_field!(Stat, stat, st_mtime_nsec); - #[cfg(target_os = "netbsd")] - check_renamed_struct_renamed_field!(Stat, stat, st_mtime_nsec, st_mtimensec); - check_renamed_struct_field!(Stat, stat, st_ctime); - #[cfg(not(target_os = "netbsd"))] - check_renamed_struct_field!(Stat, stat, st_ctime_nsec); - #[cfg(target_os = "netbsd")] - check_renamed_struct_renamed_field!(Stat, stat, st_ctime_nsec, st_ctimensec); - #[cfg(all( - linux_raw, - not(any( - target_arch = "aarch64", - target_arch = "powerpc64", - target_arch = "riscv64" - )) - ))] - check_renamed_struct_field!(Stat, stat, __unused); - #[cfg(all(linux_raw, not(any(target_arch = "s390x", target_arch = "x86_64"))))] - check_renamed_struct_field!(Stat, stat, __unused4); - #[cfg(all(linux_raw, not(any(target_arch = "s390x", target_arch = "x86_64"))))] - check_renamed_struct_field!(Stat, stat, __unused5); - #[cfg(all( - linux_raw, - not(any( - target_arch = "aarch64", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86_64" - )) - ))] - check_renamed_struct_field!(Stat, stat, __unused6); - } - - // Check that `Stat` matches `c::stat64`. - #[cfg(all( - libc, - any( - all(linux_kernel, target_pointer_width = "64"), - target_os = "hurd", - target_os = "emscripten", - target_os = "l4re", - ) - ))] - { - check_renamed_type!(Stat, stat64); - check_renamed_struct_field!(Stat, stat64, st_dev); - check_renamed_struct_field!(Stat, stat64, st_ino); - check_renamed_struct_field!(Stat, stat64, st_nlink); - check_renamed_struct_field!(Stat, stat64, st_mode); - check_renamed_struct_field!(Stat, stat64, st_uid); - check_renamed_struct_field!(Stat, stat64, st_gid); - #[cfg(all( - linux_raw, - not(any( - target_arch = "aarch64", - target_arch = "powerpc64", - target_arch = "riscv64", - target_arch = "s390x" - )) - ))] - check_renamed_struct_field!(Stat, stat64, __pad0); - check_renamed_struct_field!(Stat, stat64, st_rdev); - #[cfg(all(linux_raw, not(any(target_arch = "powerpc64", target_arch = "x86_64"))))] - check_renamed_struct_field!(Stat, stat64, __pad1); - check_renamed_struct_field!(Stat, stat64, st_size); - check_renamed_struct_field!(Stat, stat64, st_blksize); - #[cfg(all( - linux_raw, - not(any( - target_arch = "powerpc64", - target_arch = "s390x", - target_arch = "x86_64" - )) - ))] - check_renamed_struct_field!(Stat, stat64, __pad2); - check_renamed_struct_field!(Stat, stat64, st_blocks); - check_renamed_struct_field!(Stat, stat64, st_atime); - check_renamed_struct_field!(Stat, stat64, st_atime_nsec); - check_renamed_struct_field!(Stat, stat64, st_mtime); - check_renamed_struct_field!(Stat, stat64, st_mtime_nsec); - check_renamed_struct_field!(Stat, stat64, st_ctime); - check_renamed_struct_field!(Stat, stat64, st_ctime_nsec); - #[cfg(all( - linux_raw, - not(any( - target_arch = "aarch64", - target_arch = "powerpc64", - target_arch = "riscv64" - )) - ))] - check_renamed_struct_field!(Stat, stat64, __unused); - #[cfg(all(linux_raw, not(any(target_arch = "s390x", target_arch = "x86_64"))))] - check_renamed_struct_field!(Stat, stat64, __unused4); - #[cfg(all(linux_raw, not(any(target_arch = "s390x", target_arch = "x86_64"))))] - check_renamed_struct_field!(Stat, stat64, __unused5); - #[cfg(all( - linux_raw, - not(any( - target_arch = "aarch64", - target_arch = "riscv64", - target_arch = "s390x", - target_arch = "x86_64" - )) - ))] - check_renamed_struct_field!(Stat, stat64, __unused6); - } - } - - #[cfg(not(any( - solarish, - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - target_os = "redox", - target_os = "wasi", - )))] - { - check_renamed_type!(Fsid, fsid_t); - #[cfg(not(libc))] // libc hides the `val` field - check_renamed_struct_field!(Fsid, fsid_t, val); - } - - #[cfg(linux_like)] - { - check_renamed_type!(StatFs, statfs64); - check_renamed_struct_field!(StatFs, statfs64, f_type); - check_renamed_struct_field!(StatFs, statfs64, f_bsize); - check_renamed_struct_field!(StatFs, statfs64, f_blocks); - check_renamed_struct_field!(StatFs, statfs64, f_bfree); - check_renamed_struct_field!(StatFs, statfs64, f_bavail); - check_renamed_struct_field!(StatFs, statfs64, f_files); - check_renamed_struct_field!(StatFs, statfs64, f_ffree); - check_renamed_struct_field!(StatFs, statfs64, f_fsid); - check_renamed_struct_field!(StatFs, statfs64, f_namelen); - check_renamed_struct_field!(StatFs, statfs64, f_frsize); - check_renamed_struct_field!(StatFs, statfs64, f_flags); - #[cfg(linux_raw)] - check_renamed_struct_field!(StatFs, statfs64, f_spare); - } - - // Rust's libc crate lacks statx for Non-glibc targets. - #[cfg(all(target_os = "linux", target_env = "gnu"))] - { - check_renamed_type!(StatxTimestamp, statx_timestamp); - check_renamed_struct_field!(StatxTimestamp, statx_timestamp, tv_sec); - check_renamed_struct_field!(StatxTimestamp, statx_timestamp, tv_nsec); - #[cfg(linux_raw)] - check_renamed_struct_field!(StatxTimestamp, statx_timestamp, __reserved); - - check_renamed_type!(Statx, statx); - check_renamed_struct_field!(Statx, statx, stx_mask); - check_renamed_struct_field!(Statx, statx, stx_blksize); - check_renamed_struct_field!(Statx, statx, stx_attributes); - check_renamed_struct_field!(Statx, statx, stx_nlink); - check_renamed_struct_field!(Statx, statx, stx_uid); - check_renamed_struct_field!(Statx, statx, stx_gid); - check_renamed_struct_field!(Statx, statx, stx_mode); - #[cfg(linux_raw)] - check_renamed_struct_field!(Statx, statx, __spare0); - check_renamed_struct_field!(Statx, statx, stx_ino); - check_renamed_struct_field!(Statx, statx, stx_size); - check_renamed_struct_field!(Statx, statx, stx_blocks); - check_renamed_struct_field!(Statx, statx, stx_attributes_mask); - check_renamed_struct_field!(Statx, statx, stx_atime); - check_renamed_struct_field!(Statx, statx, stx_btime); - check_renamed_struct_field!(Statx, statx, stx_ctime); - check_renamed_struct_field!(Statx, statx, stx_mtime); - check_renamed_struct_field!(Statx, statx, stx_rdev_major); - check_renamed_struct_field!(Statx, statx, stx_rdev_minor); - check_renamed_struct_field!(Statx, statx, stx_dev_major); - check_renamed_struct_field!(Statx, statx, stx_dev_minor); - check_renamed_struct_field!(Statx, statx, stx_mnt_id); - check_renamed_struct_field!(Statx, statx, stx_dio_mem_align); - check_renamed_struct_field!(Statx, statx, stx_dio_offset_align); - #[cfg(not(libc))] // not in libc yet - check_renamed_struct_field!(Statx, statx, stx_subvol); - #[cfg(not(libc))] // not in libc yet - check_renamed_struct_field!(Statx, statx, stx_atomic_write_unit_min); - #[cfg(not(libc))] // not in libc yet - check_renamed_struct_field!(Statx, statx, stx_atomic_write_unit_max); - #[cfg(not(libc))] // not in libc yet - check_renamed_struct_field!(Statx, statx, stx_atomic_write_segments_max); - #[cfg(linux_raw)] - check_renamed_struct_field!(Statx, statx, __spare1); - #[cfg(linux_raw)] - check_renamed_struct_field!(Statx, statx, __spare3); - } - } -} diff --git a/vendor/rustix/src/fs/copy_file_range.rs b/vendor/rustix/src/fs/copy_file_range.rs deleted file mode 100644 index b927d572..00000000 --- a/vendor/rustix/src/fs/copy_file_range.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::{backend, io}; -use backend::fd::AsFd; - -/// `copy_file_range(fd_in, off_in, fd_out, off_out, len, 0)`—Copies data -/// from one file to another. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/copy_file_range.2.html -#[inline] -pub fn copy_file_range<InFd: AsFd, OutFd: AsFd>( - fd_in: InFd, - off_in: Option<&mut u64>, - fd_out: OutFd, - off_out: Option<&mut u64>, - len: usize, -) -> io::Result<usize> { - backend::fs::syscalls::copy_file_range(fd_in.as_fd(), off_in, fd_out.as_fd(), off_out, len) -} diff --git a/vendor/rustix/src/fs/dir.rs b/vendor/rustix/src/fs/dir.rs deleted file mode 100644 index b3e1e3b9..00000000 --- a/vendor/rustix/src/fs/dir.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! `Dir` and `DirEntry`. - -use crate::backend; - -pub use backend::fs::dir::{Dir, DirEntry}; diff --git a/vendor/rustix/src/fs/fadvise.rs b/vendor/rustix/src/fs/fadvise.rs deleted file mode 100644 index 93d8e081..00000000 --- a/vendor/rustix/src/fs/fadvise.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::{backend, io}; -use backend::fd::AsFd; -use backend::fs::types::Advice; -use core::num::NonZeroU64; - -/// `posix_fadvise(fd, offset, len, advice)`—Declares an expected access -/// pattern for a file. -/// -/// If `len` is `None`, the advice extends to the end of the file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_fadvise.html -/// [Linux]: https://man7.org/linux/man-pages/man2/posix_fadvise.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=posix_fadvise&sektion=2 -#[inline] -#[doc(alias = "posix_fadvise")] -pub fn fadvise<Fd: AsFd>( - fd: Fd, - offset: u64, - len: Option<NonZeroU64>, - advice: Advice, -) -> io::Result<()> { - backend::fs::syscalls::fadvise(fd.as_fd(), offset, len, advice) -} diff --git a/vendor/rustix/src/fs/fcntl.rs b/vendor/rustix/src/fs/fcntl.rs deleted file mode 100644 index ba5368c8..00000000 --- a/vendor/rustix/src/fs/fcntl.rs +++ /dev/null @@ -1,107 +0,0 @@ -//! The Unix `fcntl` function is effectively lots of different functions hidden -//! behind a single dynamic dispatch interface. In order to provide a type-safe -//! API, rustix makes them all separate functions so that they can have -//! dedicated static type signatures. - -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -use crate::fs::FlockOperation; -use crate::{backend, io}; -use backend::fd::AsFd; -use backend::fs::types::OFlags; - -/// `fcntl(fd, F_GETFL)`—Returns a file descriptor's access mode and status. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[inline] -#[doc(alias = "F_GETFL")] -pub fn fcntl_getfl<Fd: AsFd>(fd: Fd) -> io::Result<OFlags> { - backend::fs::syscalls::fcntl_getfl(fd.as_fd()) -} - -/// `fcntl(fd, F_SETFL, flags)`—Sets a file descriptor's status. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[inline] -#[doc(alias = "F_SETFL")] -pub fn fcntl_setfl<Fd: AsFd>(fd: Fd, flags: OFlags) -> io::Result<()> { - backend::fs::syscalls::fcntl_setfl(fd.as_fd(), flags) -} - -/// `fcntl(fd, F_GET_SEALS)`—Return the seals for `fd`'s inode. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -#[inline] -#[doc(alias = "F_GET_SEALS")] -pub fn fcntl_get_seals<Fd: AsFd>(fd: Fd) -> io::Result<SealFlags> { - backend::fs::syscalls::fcntl_get_seals(fd.as_fd()) -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -use backend::fs::types::SealFlags; - -/// `fcntl(fd, F_ADD_SEALS)`—Add seals to `fd`'s inode. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -#[inline] -#[doc(alias = "F_ADD_SEALS")] -pub fn fcntl_add_seals<Fd: AsFd>(fd: Fd, seals: SealFlags) -> io::Result<()> { - backend::fs::syscalls::fcntl_add_seals(fd.as_fd(), seals) -} - -/// `fcntl(fd, F_SETLK)`—Acquire or release an `fcntl`-style lock. -/// -/// This function doesn't currently have an offset or len; it currently always -/// sets the `l_len` field to 0, which is a special case that means the entire -/// file should be locked. -/// -/// Unlike `flock`-style locks, `fcntl`-style locks are process-associated, -/// meaning that they don't guard against being acquired by two threads in the -/// same process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -#[doc(alias = "F_SETLK")] -#[doc(alias = "F_SETLKW")] -pub fn fcntl_lock<Fd: AsFd>(fd: Fd, operation: FlockOperation) -> io::Result<()> { - backend::fs::syscalls::fcntl_lock(fd.as_fd(), operation) -} diff --git a/vendor/rustix/src/fs/fcntl_apple.rs b/vendor/rustix/src/fs/fcntl_apple.rs deleted file mode 100644 index a32e46d7..00000000 --- a/vendor/rustix/src/fs/fcntl_apple.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::{backend, io}; -use backend::fd::AsFd; - -/// `fcntl(fd, F_RDADVISE, radvisory { offset, len })` -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -#[doc(alias = "F_RDADVISE")] -#[inline] -pub fn fcntl_rdadvise<Fd: AsFd>(fd: Fd, offset: u64, len: u64) -> io::Result<()> { - backend::fs::syscalls::fcntl_rdadvise(fd.as_fd(), offset, len) -} - -/// `fcntl(fd, F_FULLFSYNC)` -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -#[doc(alias = "F_FULLSYNC")] -#[inline] -pub fn fcntl_fullfsync<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::fs::syscalls::fcntl_fullfsync(fd.as_fd()) -} - -/// `fcntl(fd, F_NOCACHE, value)`—Turn data caching off or on for a file -/// descriptor. -/// -/// See [this mailing list post] for additional information about the meanings -/// of `F_NOCACHE` and `F_GLOBAL_NOCACHE`. -/// -/// [this mailing list post]: https://lists.apple.com/archives/filesystem-dev/2007/Sep/msg00010.html -/// -/// See also [`fcntl_global_nocache`]. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -#[doc(alias = "F_NOCACHE")] -#[inline] -pub fn fcntl_nocache<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::fs::syscalls::fcntl_nocache(fd.as_fd(), value) -} - -/// `fcntl(fd, F_GLOBAL_NOCACHE, value)`—Turn data caching off or on for all -/// file descriptors. -/// -/// See [this mailing list post] for additional information about the meanings -/// of `F_NOCACHE` and `F_GLOBAL_NOCACHE`. -/// -/// [this mailing list post]: https://lists.apple.com/archives/filesystem-dev/2007/Sep/msg00010.html -/// -/// See also [`fcntl_nocache`]. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -#[doc(alias = "F_GLOBAL_NOCACHE")] -#[inline] -pub fn fcntl_global_nocache<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::fs::syscalls::fcntl_global_nocache(fd.as_fd(), value) -} diff --git a/vendor/rustix/src/fs/fcopyfile.rs b/vendor/rustix/src/fs/fcopyfile.rs deleted file mode 100644 index e8f26ffd..00000000 --- a/vendor/rustix/src/fs/fcopyfile.rs +++ /dev/null @@ -1,88 +0,0 @@ -use crate::fs::CopyfileFlags; -use crate::{backend, io}; -use backend::fd::AsFd; -use backend::fs::types::copyfile_state_t; - -/// `fcopyfile(from, to, state, flags)` -/// -/// # Safety -/// -/// The `state` operand must be allocated with `copyfile_state_alloc` and not -/// yet freed with `copyfile_state_free`. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html -#[inline] -pub unsafe fn fcopyfile<FromFd: AsFd, ToFd: AsFd>( - from: FromFd, - to: ToFd, - state: copyfile_state_t, - flags: CopyfileFlags, -) -> io::Result<()> { - backend::fs::syscalls::fcopyfile(from.as_fd(), to.as_fd(), state, flags) -} - -/// `copyfile_state_alloc()` -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html -#[inline] -pub fn copyfile_state_alloc() -> io::Result<copyfile_state_t> { - backend::fs::syscalls::copyfile_state_alloc() -} - -/// `copyfile_state_free(state)` -/// -/// # Safety -/// -/// The `state` operand must be allocated with `copyfile_state_alloc` and not -/// yet freed with `copyfile_state_free`. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html -#[inline] -pub unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { - backend::fs::syscalls::copyfile_state_free(state) -} - -/// `copyfile_state_get(state, COPYFILE_STATE_COPIED)` -/// -/// # Safety -/// -/// The `state` operand must be allocated with `copyfile_state_alloc` and not -/// yet freed with `copyfile_state_free`. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html -#[inline] -pub unsafe fn copyfile_state_get_copied(state: copyfile_state_t) -> io::Result<u64> { - backend::fs::syscalls::copyfile_state_get_copied(state) -} - -/// `copyfile_state_get(state, flags, dst)` -/// -/// # Safety -/// -/// The `state` operand must be allocated with `copyfile_state_alloc` and not -/// yet freed with `copyfile_state_free`. -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html -#[inline] -pub unsafe fn copyfile_state_get( - state: copyfile_state_t, - flag: u32, - dst: *mut core::ffi::c_void, -) -> io::Result<()> { - backend::fs::syscalls::copyfile_state_get(state, flag, dst) -} diff --git a/vendor/rustix/src/fs/fd.rs b/vendor/rustix/src/fs/fd.rs deleted file mode 100644 index 7ce1b3a4..00000000 --- a/vendor/rustix/src/fs/fd.rs +++ /dev/null @@ -1,331 +0,0 @@ -//! Functions which operate on file descriptors. - -#[cfg(not(target_os = "wasi"))] -use crate::fs::Mode; -#[cfg(not(target_os = "wasi"))] -use crate::fs::{Gid, Uid}; -use crate::fs::{SeekFrom, Timespec}; -use crate::{backend, io}; -use backend::fd::AsFd; -#[cfg(not(any( - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] -use backend::fs::types::FallocateFlags; -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "solaris", - target_os = "vita", - target_os = "wasi" -)))] -use backend::fs::types::FlockOperation; -#[cfg(linux_kernel)] -use backend::fs::types::FsWord; -use backend::fs::types::Stat; -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use backend::fs::types::StatFs; -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -use backend::fs::types::StatVfs; - -/// Timestamps used by [`utimensat`] and [`futimens`]. -/// -/// [`utimensat`]: crate::fs::utimensat -/// [`futimens`]: crate::fs::futimens -// This is `repr(C)` and specifically laid out to match the representation used -// by `utimensat` and `futimens`, which expect 2-element arrays of timestamps. -#[repr(C)] -#[derive(Debug, Clone)] -pub struct Timestamps { - /// The timestamp of the last access to a filesystem object. - pub last_access: Timespec, - - /// The timestamp of the last modification of a filesystem object. - pub last_modification: Timespec, -} - -/// The filesystem magic number for procfs. -/// -/// See [the `fstatfs` manual page] for more information. -/// -/// [the `fstatfs` manual page]: https://man7.org/linux/man-pages/man2/fstatfs.2.html#DESCRIPTION -#[cfg(linux_kernel)] -pub const PROC_SUPER_MAGIC: FsWord = backend::c::PROC_SUPER_MAGIC as FsWord; - -/// The filesystem magic number for NFS. -/// -/// See [the `fstatfs` manual page] for more information. -/// -/// [the `fstatfs` manual page]: https://man7.org/linux/man-pages/man2/fstatfs.2.html#DESCRIPTION -#[cfg(linux_kernel)] -pub const NFS_SUPER_MAGIC: FsWord = backend::c::NFS_SUPER_MAGIC as FsWord; - -/// `lseek(fd, offset, whence)`—Repositions a file descriptor within a file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/lseek.html -/// [Linux]: https://man7.org/linux/man-pages/man2/lseek.2.html -#[inline] -#[doc(alias = "lseek")] -pub fn seek<Fd: AsFd>(fd: Fd, pos: SeekFrom) -> io::Result<u64> { - backend::fs::syscalls::seek(fd.as_fd(), pos) -} - -/// `lseek(fd, 0, SEEK_CUR)`—Returns the current position within a file. -/// -/// Return the current position of the file descriptor. This is a subset of -/// the functionality of `seek`, but this interface makes it easier for users -/// to declare their intent not to mutate any state. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/lseek.html -/// [Linux]: https://man7.org/linux/man-pages/man2/lseek.2.html -#[inline] -#[doc(alias = "lseek")] -pub fn tell<Fd: AsFd>(fd: Fd) -> io::Result<u64> { - backend::fs::syscalls::tell(fd.as_fd()) -} - -/// `fchmod(fd, mode)`—Sets open file or directory permissions. -/// -/// This implementation does not support [`OFlags::PATH`] file descriptors, -/// even on platforms where the host libc emulates it. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchmod.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fchmod.2.html -/// [`OFlags::PATH`]: crate::fs::OFlags::PATH -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn fchmod<Fd: AsFd>(fd: Fd, mode: Mode) -> io::Result<()> { - backend::fs::syscalls::fchmod(fd.as_fd(), mode) -} - -/// `fchown(fd, owner, group)`—Sets open file or directory ownership. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchown.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fchown.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn fchown<Fd: AsFd>(fd: Fd, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { - backend::fs::syscalls::fchown(fd.as_fd(), owner, group) -} - -/// `fstat(fd)`—Queries metadata for an open file or directory. -/// -/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to -/// interpret the `st_mode` field. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstat.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fstat.2.html -/// [`Mode::from_raw_mode`]: Mode::from_raw_mode -/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode -#[inline] -pub fn fstat<Fd: AsFd>(fd: Fd) -> io::Result<Stat> { - backend::fs::syscalls::fstat(fd.as_fd()) -} - -/// `fstatfs(fd)`—Queries filesystem statistics for an open file or directory. -/// -/// Compared to [`fstatvfs`], this function often provides more information, -/// though it's less portable. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fstatfs.2.html -#[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub fn fstatfs<Fd: AsFd>(fd: Fd) -> io::Result<StatFs> { - backend::fs::syscalls::fstatfs(fd.as_fd()) -} - -/// `fstatvfs(fd)`—Queries filesystem statistics for an open file or -/// directory, POSIX version. -/// -/// Compared to [`fstatfs`], this function often provides less information, -/// but it is more portable. But even so, filesystems are very diverse and not -/// all the fields are meaningful for every filesystem. And `f_fsid` doesn't -/// seem to have a clear meaning anywhere. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstatvfs.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fstatvfs.2.html -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -#[inline] -pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> io::Result<StatVfs> { - backend::fs::syscalls::fstatvfs(fd.as_fd()) -} - -/// `futimens(fd, times)`—Sets timestamps for an open file or directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/futimens.html -/// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -#[inline] -pub fn futimens<Fd: AsFd>(fd: Fd, times: &Timestamps) -> io::Result<()> { - backend::fs::syscalls::futimens(fd.as_fd(), times) -} - -/// `fallocate(fd, mode, offset, len)`—Adjusts file allocation. -/// -/// This is a more general form of `posix_fallocate`, adding a `mode` argument -/// which modifies the behavior. On platforms which only support -/// `posix_fallocate` and not the more general form, no `FallocateFlags` values -/// are defined so it will always be empty. -/// -/// # References -/// - [POSIX] -/// - [Linux `fallocate`] -/// - [Linux `posix_fallocate`] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_fallocate.html -/// [Linux `fallocate`]: https://man7.org/linux/man-pages/man2/fallocate.2.html -/// [Linux `posix_fallocate`]: https://man7.org/linux/man-pages/man3/posix_fallocate.3.html -#[cfg(not(any( - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", -)))] // not implemented in libc for NetBSD yet -#[inline] -#[doc(alias = "posix_fallocate")] -pub fn fallocate<Fd: AsFd>(fd: Fd, mode: FallocateFlags, offset: u64, len: u64) -> io::Result<()> { - backend::fs::syscalls::fallocate(fd.as_fd(), mode, offset, len) -} - -/// `fsync(fd)`—Ensures that file data and metadata is written to the -/// underlying storage device. -/// -/// On iOS and macOS this isn't sufficient to ensure that data has reached -/// persistent storage; use [`fcntl_fullfsync`] to ensure that. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fsync.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fsync.2.html -/// [`fcntl_fullfsync`]: https://docs.rs/rustix/*/x86_64-apple-darwin/rustix/fs/fn.fcntl_fullfsync.html -#[inline] -pub fn fsync<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::fs::syscalls::fsync(fd.as_fd()) -} - -/// `fdatasync(fd)`—Ensures that file data is written to the underlying -/// storage device. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fdatasync.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fdatasync.2.html -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", -)))] -#[inline] -pub fn fdatasync<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::fs::syscalls::fdatasync(fd.as_fd()) -} - -/// `ftruncate(fd, length)`—Sets the length of a file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/ftruncate.html -/// [Linux]: https://man7.org/linux/man-pages/man2/ftruncate.2.html -#[inline] -pub fn ftruncate<Fd: AsFd>(fd: Fd, length: u64) -> io::Result<()> { - backend::fs::syscalls::ftruncate(fd.as_fd(), length) -} - -/// `flock(fd, operation)`—Acquire or release an advisory lock on an open file. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/flock.2.html -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "solaris", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub fn flock<Fd: AsFd>(fd: Fd, operation: FlockOperation) -> io::Result<()> { - backend::fs::syscalls::flock(fd.as_fd(), operation) -} - -/// `syncfs(fd)`—Flush cached filesystem data. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/syncfs.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn syncfs<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::fs::syscalls::syncfs(fd.as_fd()) -} diff --git a/vendor/rustix/src/fs/getpath.rs b/vendor/rustix/src/fs/getpath.rs deleted file mode 100644 index 8e14ff2f..00000000 --- a/vendor/rustix/src/fs/getpath.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::ffi::CString; -use crate::{backend, io}; -use backend::fd::AsFd; - -/// `fcntl(fd, F_GETPATH)` -/// -/// # References -/// - [Apple] -/// -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -#[inline] -pub fn getpath<Fd: AsFd>(fd: Fd) -> io::Result<CString> { - backend::fs::syscalls::getpath(fd.as_fd()) -} diff --git a/vendor/rustix/src/fs/id.rs b/vendor/rustix/src/fs/id.rs deleted file mode 100644 index 1fc2ef81..00000000 --- a/vendor/rustix/src/fs/id.rs +++ /dev/null @@ -1 +0,0 @@ -pub use crate::ugid::{Gid, Uid}; diff --git a/vendor/rustix/src/fs/inotify.rs b/vendor/rustix/src/fs/inotify.rs deleted file mode 100644 index ad03dfa6..00000000 --- a/vendor/rustix/src/fs/inotify.rs +++ /dev/null @@ -1,219 +0,0 @@ -//! inotify support for working with inotify objects. -//! -//! # Examples -//! -//! ``` -//! use rustix::fs::inotify; -//! use rustix::io; -//! use std::mem::MaybeUninit; -//! -//! # fn test() -> io::Result<()> { -//! // Create an inotify object. In this example, we use `NONBLOCK` so that the -//! // reader fails with `WOULDBLOCK` when no events are ready. Otherwise it -//! // will block until at least one event is ready. -//! let inotify = inotify::init(inotify::CreateFlags::NONBLOCK)?; -//! -//! // Add a directory to watch. -//! inotify::add_watch( -//! &inotify, -//! "/path/to/some/directory/to/watch", -//! inotify::WatchFlags::ALL_EVENTS, -//! )?; -//! -//! // Generate some events in the watched directory… -//! -//! // Loop over pending events. -//! let mut buf = [MaybeUninit::uninit(); 512]; -//! let mut iter = inotify::Reader::new(inotify, &mut buf); -//! loop { -//! let entry = match iter.next() { -//! // Stop iterating if there are no more events for now. -//! Err(io::Errno::WOULDBLOCK) => break, -//! Err(e) => return Err(e), -//! Ok(entry) => entry, -//! }; -//! -//! // Use `entry`… -//! } -//! -//! # Ok(()) -//! # } - -#![allow(unused_qualifications)] - -use super::inotify; -pub use crate::backend::fs::inotify::{CreateFlags, ReadFlags, WatchFlags}; -use crate::backend::fs::syscalls; -use crate::fd::{AsFd, OwnedFd}; -use crate::ffi::CStr; -use crate::io; -use crate::io::{read, Errno}; -use core::mem::{align_of, size_of, MaybeUninit}; -use linux_raw_sys::general::inotify_event; - -/// `inotify_init1(flags)`—Creates a new inotify object. -/// -/// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file -/// descriptor from being implicitly passed across `exec` boundaries. -#[doc(alias = "inotify_init1")] -#[inline] -pub fn init(flags: inotify::CreateFlags) -> io::Result<OwnedFd> { - syscalls::inotify_init1(flags) -} - -/// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify. -/// -/// This registers or updates a watch for the filesystem path `path` and -/// returns a watch descriptor corresponding to this watch. -/// -/// Note: Due to the existence of hardlinks, providing two different paths to -/// this method may result in it returning the same watch descriptor. An -/// application should keep track of this externally to avoid logic errors. -#[doc(alias = "inotify_add_watch")] -#[inline] -pub fn add_watch<P: crate::path::Arg, Fd: AsFd>( - inot: Fd, - path: P, - flags: inotify::WatchFlags, -) -> io::Result<i32> { - path.into_with_c_str(|path| syscalls::inotify_add_watch(inot.as_fd(), path, flags)) -} - -/// `inotify_rm_watch(self, wd)`—Removes a watch from this inotify. -/// -/// The watch descriptor provided should have previously been returned by -/// [`inotify::add_watch`] and not previously have been removed. -#[doc(alias = "inotify_rm_watch")] -#[inline] -pub fn remove_watch<Fd: AsFd>(inot: Fd, wd: i32) -> io::Result<()> { - syscalls::inotify_rm_watch(inot.as_fd(), wd) -} - -/// An inotify event iterator implemented with the read syscall. -/// -/// See the [`RawDir`] API for more details and usage examples as this API is -/// based on it. -/// -/// [`RawDir`]: crate::fs::raw_dir::RawDir -pub struct Reader<'buf, Fd: AsFd> { - fd: Fd, - buf: &'buf mut [MaybeUninit<u8>], - initialized: usize, - offset: usize, -} - -impl<'buf, Fd: AsFd> Reader<'buf, Fd> { - /// Create a new iterator from the given file descriptor and buffer. - pub fn new(fd: Fd, buf: &'buf mut [MaybeUninit<u8>]) -> Self { - Self { - fd, - buf: { - let offset = buf.as_ptr().align_offset(align_of::<inotify_event>()); - if offset < buf.len() { - &mut buf[offset..] - } else { - &mut [] - } - }, - initialized: 0, - offset: 0, - } - } -} - -/// An inotify event. -#[doc(alias = "inotify_event")] -#[derive(Debug)] -pub struct Event<'a> { - wd: i32, - events: ReadFlags, - cookie: u32, - file_name: Option<&'a CStr>, -} - -impl<'a> Event<'a> { - /// Returns the watch for which this event occurs. - #[inline] - pub fn wd(&self) -> i32 { - self.wd - } - - /// Returns a description of the events. - #[inline] - #[doc(alias = "mask")] - pub fn events(&self) -> ReadFlags { - self.events - } - - /// Returns the unique cookie associating related events. - #[inline] - pub fn cookie(&self) -> u32 { - self.cookie - } - - /// Returns the file name of this event, if any. - #[inline] - pub fn file_name(&self) -> Option<&CStr> { - self.file_name - } -} - -impl<'buf, Fd: AsFd> Reader<'buf, Fd> { - /// Read the next inotify event. - /// - /// This is similar to [`Iterator::next`] except that it doesn't return an - /// `Option`, because the stream doesn't have an ending. It always returns - /// events or errors. - /// - /// If there are no events in the buffer and none ready to be read: - /// - If the file descriptor was opened with - /// [`inotify::CreateFlags::NONBLOCK`], this will fail with - /// [`Errno::AGAIN`]. - /// - Otherwise this will block until at least one event is ready or an - /// error occurs. - #[allow(unsafe_code)] - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> io::Result<Event<'_>> { - if self.is_buffer_empty() { - match read(self.fd.as_fd(), &mut *self.buf).map(|(init, _)| init.len()) { - Ok(0) => return Err(Errno::INVAL), - Ok(bytes_read) => { - self.initialized = bytes_read; - self.offset = 0; - } - Err(e) => return Err(e), - } - } - - let ptr = self.buf[self.offset..].as_ptr(); - - // SAFETY: - // - This data is initialized by the check above. - // - Assumption: the kernel will not give us partial structs. - // - Assumption: the kernel uses proper alignment between structs. - // - The starting pointer is aligned (performed in `Reader::new`). - let event = unsafe { &*ptr.cast::<inotify_event>() }; - - self.offset += size_of::<inotify_event>() + usize::try_from(event.len).unwrap(); - - Ok(Event { - wd: event.wd, - events: ReadFlags::from_bits_retain(event.mask), - cookie: event.cookie, - file_name: if event.len > 0 { - // SAFETY: The kernel guarantees a NUL-terminated string. - Some(unsafe { CStr::from_ptr(event.name.as_ptr().cast()) }) - } else { - None - }, - }) - } - - /// Returns true if the internal buffer is empty and will be refilled when - /// calling [`next`]. This is useful to avoid further blocking reads. - /// - /// [`next`]: Self::next - pub fn is_buffer_empty(&self) -> bool { - self.offset >= self.initialized - } -} diff --git a/vendor/rustix/src/fs/ioctl.rs b/vendor/rustix/src/fs/ioctl.rs deleted file mode 100644 index c126fdd1..00000000 --- a/vendor/rustix/src/fs/ioctl.rs +++ /dev/null @@ -1,169 +0,0 @@ -//! Filesystem-oriented `ioctl` functions. - -#![allow(unsafe_code)] - -#[cfg(linux_kernel)] -use { - crate::backend::c, - crate::fd::AsFd, - crate::{backend, ffi, io, ioctl}, -}; - -use bitflags::bitflags; - -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] -use crate::fd::{AsRawFd as _, BorrowedFd}; - -/// `ioctl(fd, BLKSSZGET)`—Returns the logical block size of a block device. -/// -/// This is mentioned in the [Linux `openat` manual page]. -/// -/// [Linux `openat` manual page]: https://man7.org/linux/man-pages/man2/openat.2.html -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "BLKSSZGET")] -pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - // SAFETY: `BLZSSZGET` is a getter opcode that gets a `u32`. - unsafe { - let ctl = ioctl::Getter::<{ c::BLKSSZGET }, c::c_uint>::new(); - ioctl::ioctl(fd, ctl) - } -} - -/// `ioctl(fd, BLKPBSZGET)`—Returns the physical block size of a block device. -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "BLKPBSZGET")] -pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - // SAFETY: `BLKPBSZGET` is a getter opcode that gets a `u32`. - unsafe { - let ctl = ioctl::Getter::<{ c::BLKPBSZGET }, c::c_uint>::new(); - ioctl::ioctl(fd, ctl) - } -} - -/// `ioctl(fd, FICLONE, src_fd)`—Share data between open files. -/// -/// This ioctl is not available on SPARC platforms. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_ficlone.2.html -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] -#[inline] -#[doc(alias = "FICLONE")] -pub fn ioctl_ficlone<Fd: AsFd, SrcFd: AsFd>(fd: Fd, src_fd: SrcFd) -> io::Result<()> { - unsafe { ioctl::ioctl(fd, Ficlone(src_fd.as_fd())) } -} - -/// `ioctl(fd, EXT4_IOC_RESIZE_FS, blocks)`—Resize ext4 filesystem on fd. -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "EXT4_IOC_RESIZE_FS")] -pub fn ext4_ioc_resize_fs<Fd: AsFd>(fd: Fd, blocks: u64) -> io::Result<()> { - // SAFETY: `EXT4_IOC_RESIZE_FS` is a pointer setter opcode. - unsafe { - let ctl = ioctl::Setter::<{ backend::fs::EXT4_IOC_RESIZE_FS }, u64>::new(blocks); - ioctl::ioctl(fd, ctl) - } -} - -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] -struct Ficlone<'a>(BorrowedFd<'a>); - -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] -unsafe impl ioctl::Ioctl for Ficlone<'_> { - type Output = (); - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> ioctl::Opcode { - c::FICLONE as ioctl::Opcode - } - - fn as_ptr(&mut self) -> *mut c::c_void { - self.0.as_raw_fd() as *mut c::c_void - } - - unsafe fn output_from_ptr( - _: ioctl::IoctlOutput, - _: *mut c::c_void, - ) -> io::Result<Self::Output> { - Ok(()) - } -} - -#[cfg(linux_kernel)] -bitflags! { - /// `FS_*` constants for use with [`ioctl_getflags`]. - /// - /// [`ioctl_getflags`]: crate::fs::ioctl::ioctl_getflags - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IFlags: ffi::c_uint { - /// `FS_APPEND_FL` - const APPEND = linux_raw_sys::general::FS_APPEND_FL; - /// `FS_COMPR_FL` - const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL; - /// `FS_DIRSYNC_FL` - const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL; - /// `FS_IMMUTABLE_FL` - const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL; - /// `FS_JOURNAL_DATA_FL` - const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL; - /// `FS_NOATIME_FL` - const NOATIME = linux_raw_sys::general::FS_NOATIME_FL; - /// `FS_NOCOW_FL` - const NOCOW = linux_raw_sys::general::FS_NOCOW_FL; - /// `FS_NODUMP_FL` - const NODUMP = linux_raw_sys::general::FS_NODUMP_FL; - /// `FS_NOTAIL_FL` - const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL; - /// `FS_PROJINHERIT_FL` - const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL; - /// `FS_SECRM_FL` - const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL; - /// `FS_SYNC_FL` - const SYNC = linux_raw_sys::general::FS_SYNC_FL; - /// `FS_TOPDIR_FL` - const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL; - /// `FS_UNRM_FL` - const UNRM = linux_raw_sys::general::FS_UNRM_FL; - } -} - -/// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes -/// -/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "FS_IOC_GETFLAGS")] -pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> { - unsafe { - #[cfg(target_pointer_width = "32")] - let ctl = ioctl::Getter::<{ c::FS_IOC32_GETFLAGS }, u32>::new(); - #[cfg(target_pointer_width = "64")] - let ctl = ioctl::Getter::<{ c::FS_IOC_GETFLAGS }, u32>::new(); - - ioctl::ioctl(fd, ctl).map(IFlags::from_bits_retain) - } -} - -/// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes -/// -/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "FS_IOC_SETFLAGS")] -pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> { - unsafe { - #[cfg(target_pointer_width = "32")] - let ctl = ioctl::Setter::<{ c::FS_IOC32_SETFLAGS }, u32>::new(flags.bits()); - - #[cfg(target_pointer_width = "64")] - let ctl = ioctl::Setter::<{ c::FS_IOC_SETFLAGS }, u32>::new(flags.bits()); - - ioctl::ioctl(fd, ctl) - } -} diff --git a/vendor/rustix/src/fs/makedev.rs b/vendor/rustix/src/fs/makedev.rs deleted file mode 100644 index e6cf5c0e..00000000 --- a/vendor/rustix/src/fs/makedev.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::backend; -use crate::fs::Dev; - -/// `makedev(maj, min)`—Compute a device ID from a given major and minor ID. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/makedev.3.html -#[inline] -pub fn makedev(maj: u32, min: u32) -> Dev { - backend::fs::makedev::makedev(maj, min) -} - -/// `minor(dev)`—Compute the minor ID of a given device ID. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/minor.3.html -#[inline] -pub fn minor(dev: Dev) -> u32 { - backend::fs::makedev::minor(dev) -} - -/// `major(dev)`—Compute the major ID of a given device ID. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/major.3.html -#[inline] -pub fn major(dev: Dev) -> u32 { - backend::fs::makedev::major(dev) -} diff --git a/vendor/rustix/src/fs/memfd_create.rs b/vendor/rustix/src/fs/memfd_create.rs deleted file mode 100644 index 6e49771f..00000000 --- a/vendor/rustix/src/fs/memfd_create.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::fd::OwnedFd; -use crate::{backend, io, path}; -use backend::fs::types::MemfdFlags; - -/// `memfd_create(name, flags)`—Create an anonymous file. -/// -/// For a higher-level API to this functionality, see the [memfd] crate. -/// -/// [memfd]: https://crates.io/crates/memfd -/// -/// # References -/// - [Linux] -/// - [glibc] -/// - [FreeBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/memfd_create.2.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Memory_002dmapped-I_002fO.html#index-memfd_005fcreate -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?memfd_create -#[inline] -pub fn memfd_create<P: path::Arg>(name: P, flags: MemfdFlags) -> io::Result<OwnedFd> { - name.into_with_c_str(|name| backend::fs::syscalls::memfd_create(name, flags)) -} diff --git a/vendor/rustix/src/fs/mod.rs b/vendor/rustix/src/fs/mod.rs deleted file mode 100644 index 505925f7..00000000 --- a/vendor/rustix/src/fs/mod.rs +++ /dev/null @@ -1,141 +0,0 @@ -//! Filesystem operations. - -mod abs; -#[cfg(not(target_os = "redox"))] -mod at; -mod constants; -#[cfg(linux_kernel)] -mod copy_file_range; -#[cfg(all(feature = "alloc", not(any(target_os = "espidf", target_os = "redox"))))] -mod dir; -#[cfg(not(any( - apple, - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -mod fadvise; -pub(crate) mod fcntl; -#[cfg(apple)] -mod fcntl_apple; -#[cfg(apple)] -mod fcopyfile; -pub(crate) mod fd; -#[cfg(all(apple, feature = "alloc"))] -mod getpath; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. -mod id; -#[cfg(linux_kernel)] -pub mod inotify; -#[cfg(linux_kernel)] -mod ioctl; -#[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod makedev; -#[cfg(any(linux_kernel, target_os = "freebsd"))] -mod memfd_create; -#[cfg(linux_kernel)] -mod openat2; -#[cfg(linux_kernel)] -mod raw_dir; -mod seek_from; -#[cfg(target_os = "linux")] -mod sendfile; -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -mod special; -#[cfg(linux_kernel)] -mod statx; -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod sync; -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -mod xattr; - -pub use abs::*; -#[cfg(not(target_os = "redox"))] -pub use at::*; -pub use constants::*; -#[cfg(linux_kernel)] -pub use copy_file_range::copy_file_range; -#[cfg(all(feature = "alloc", not(any(target_os = "espidf", target_os = "redox"))))] -pub use dir::{Dir, DirEntry}; -#[cfg(not(any( - apple, - netbsdlike, - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -pub use fadvise::fadvise; -pub use fcntl::*; -#[cfg(apple)] -pub use fcntl_apple::*; -#[cfg(apple)] -pub use fcopyfile::*; -pub use fd::*; -#[cfg(all(apple, feature = "alloc"))] -pub use getpath::getpath; -#[cfg(not(target_os = "wasi"))] -pub use id::*; -#[cfg(linux_kernel)] -pub use ioctl::*; -#[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use makedev::*; -#[cfg(any(linux_kernel, target_os = "freebsd"))] -pub use memfd_create::memfd_create; -#[cfg(linux_kernel)] -pub use openat2::openat2; -#[cfg(linux_kernel)] -pub use raw_dir::{RawDir, RawDirEntry}; -pub use seek_from::SeekFrom; -#[cfg(target_os = "linux")] -pub use sendfile::sendfile; -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub use special::*; -#[cfg(linux_kernel)] -pub use statx::*; -#[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use sync::sync; -#[cfg(any(apple, linux_kernel, target_os = "hurd"))] -pub use xattr::*; - -/// Re-export types common to POSIX-ish platforms. -#[cfg(feature = "std")] -#[cfg(unix)] -pub use std::os::unix::fs::{DirEntryExt, FileExt, FileTypeExt, MetadataExt, OpenOptionsExt}; -#[cfg(feature = "std")] -#[cfg(all(wasi_ext, target_os = "wasi"))] -pub use std::os::wasi::fs::{DirEntryExt, FileExt, FileTypeExt, MetadataExt, OpenOptionsExt}; diff --git a/vendor/rustix/src/fs/openat2.rs b/vendor/rustix/src/fs/openat2.rs deleted file mode 100644 index 0a0e1d16..00000000 --- a/vendor/rustix/src/fs/openat2.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::fd::OwnedFd; -use crate::{backend, io, path}; -use backend::fd::AsFd; -use backend::fs::types::{Mode, OFlags, ResolveFlags}; - -/// `openat2(dirfd, path, OpenHow { oflags, mode, resolve }, sizeof(OpenHow))`— -/// Opens a file with more options. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/openat2.2.html -#[inline] -pub fn openat2<Fd: AsFd, P: path::Arg>( - dirfd: Fd, - path: P, - oflags: OFlags, - mode: Mode, - resolve: ResolveFlags, -) -> io::Result<OwnedFd> { - path.into_with_c_str(|path| { - backend::fs::syscalls::openat2(dirfd.as_fd(), path, oflags, mode, resolve) - }) -} diff --git a/vendor/rustix/src/fs/raw_dir.rs b/vendor/rustix/src/fs/raw_dir.rs deleted file mode 100644 index 7fec6fd7..00000000 --- a/vendor/rustix/src/fs/raw_dir.rs +++ /dev/null @@ -1,236 +0,0 @@ -//! `RawDir` and `RawDirEntry`. - -use crate::backend::fs::syscalls::getdents_uninit; -use crate::fd::AsFd; -use crate::ffi::CStr; -use crate::fs::FileType; -use crate::io; -use core::fmt; -use core::mem::{align_of, MaybeUninit}; -use linux_raw_sys::general::linux_dirent64; - -/// A directory iterator implemented with getdents. -/// -/// Note: This implementation does not handle growing the buffer. If this -/// functionality is necessary, you'll need to drop the current iterator, -/// resize the buffer, and then re-create the iterator. The iterator is -/// guaranteed to continue where it left off provided the file descriptor isn't -/// changed. See the example in [`RawDir::new`]. -pub struct RawDir<'buf, Fd: AsFd> { - fd: Fd, - buf: &'buf mut [MaybeUninit<u8>], - initialized: usize, - offset: usize, -} - -impl<'buf, Fd: AsFd> RawDir<'buf, Fd> { - /// Create a new iterator from the given file descriptor and buffer. - /// - /// Note: the buffer size may be trimmed to accommodate alignment - /// requirements. - /// - /// # Examples - /// - /// ## Simple but non-portable - /// - /// These examples are non-portable, because file systems may not have a - /// maximum file name length. If you can make assumptions that bound - /// this length, then these examples may suffice. - /// - /// Using the heap: - /// - /// ``` - /// # use std::mem::MaybeUninit; - /// # use rustix::fs::{CWD, Mode, OFlags, openat, RawDir}; - /// # use rustix::cstr; - /// - /// let fd = openat( - /// CWD, - /// cstr!("."), - /// OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, - /// Mode::empty(), - /// ) - /// .unwrap(); - /// - /// let mut buf = Vec::with_capacity(8192); - /// let mut iter = RawDir::new(fd, buf.spare_capacity_mut()); - /// while let Some(entry) = iter.next() { - /// let entry = entry.unwrap(); - /// dbg!(&entry); - /// } - /// ``` - /// - /// Using the stack: - /// - /// ``` - /// # use std::mem::MaybeUninit; - /// # use rustix::fs::{CWD, Mode, OFlags, openat, RawDir}; - /// # use rustix::cstr; - /// - /// let fd = openat( - /// CWD, - /// cstr!("."), - /// OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, - /// Mode::empty(), - /// ) - /// .unwrap(); - /// - /// let mut buf = [MaybeUninit::uninit(); 2048]; - /// let mut iter = RawDir::new(fd, &mut buf); - /// while let Some(entry) = iter.next() { - /// let entry = entry.unwrap(); - /// dbg!(&entry); - /// } - /// ``` - /// - /// ## Portable - /// - /// Heap allocated growing buffer for supporting directory entries with - /// arbitrarily large file names: - /// - /// ```ignore - /// # // The `ignore` above can be removed when we can depend on Rust 1.65. - /// # use std::mem::MaybeUninit; - /// # use rustix::fs::{CWD, Mode, OFlags, openat, RawDir}; - /// # use rustix::io::Errno; - /// # use rustix::cstr; - /// - /// let fd = openat( - /// CWD, - /// cstr!("."), - /// OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC, - /// Mode::empty(), - /// ) - /// .unwrap(); - /// - /// let mut buf = Vec::with_capacity(8192); - /// 'read: loop { - /// 'resize: { - /// let mut iter = RawDir::new(&fd, buf.spare_capacity_mut()); - /// while let Some(entry) = iter.next() { - /// let entry = match entry { - /// Err(Errno::INVAL) => break 'resize, - /// r => r.unwrap(), - /// }; - /// dbg!(&entry); - /// } - /// break 'read; - /// } - /// - /// let new_capacity = buf.capacity() * 2; - /// buf.reserve(new_capacity); - /// } - /// ``` - pub fn new(fd: Fd, buf: &'buf mut [MaybeUninit<u8>]) -> Self { - Self { - fd, - buf: { - let offset = buf.as_ptr().align_offset(align_of::<linux_dirent64>()); - if offset < buf.len() { - &mut buf[offset..] - } else { - &mut [] - } - }, - initialized: 0, - offset: 0, - } - } -} - -/// A raw directory entry, similar to [`std::fs::DirEntry`]. -/// -/// Unlike the std version, this may represent the `.` or `..` entries. -pub struct RawDirEntry<'a> { - file_name: &'a CStr, - file_type: u8, - inode_number: u64, - next_entry_cookie: i64, -} - -impl<'a> fmt::Debug for RawDirEntry<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut f = f.debug_struct("RawDirEntry"); - f.field("file_name", &self.file_name()); - f.field("file_type", &self.file_type()); - f.field("ino", &self.ino()); - f.field("next_entry_cookie", &self.next_entry_cookie()); - f.finish() - } -} - -impl<'a> RawDirEntry<'a> { - /// Returns the file name of this directory entry. - #[inline] - pub fn file_name(&self) -> &CStr { - self.file_name - } - - /// Returns the type of this directory entry. - #[inline] - pub fn file_type(&self) -> FileType { - FileType::from_dirent_d_type(self.file_type) - } - - /// Returns the inode number of this directory entry. - #[inline] - #[doc(alias = "inode_number")] - pub fn ino(&self) -> u64 { - self.inode_number - } - - /// Returns the seek cookie to the next directory entry. - #[inline] - #[doc(alias = "off")] - pub fn next_entry_cookie(&self) -> u64 { - self.next_entry_cookie as u64 - } -} - -impl<'buf, Fd: AsFd> RawDir<'buf, Fd> { - /// Identical to [`Iterator::next`] except that [`Iterator::Item`] borrows - /// from self. - /// - /// Note: this interface will be broken to implement a stdlib iterator API - /// with GAT support once one becomes available. - #[allow(unsafe_code)] - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Option<io::Result<RawDirEntry<'_>>> { - if self.is_buffer_empty() { - match getdents_uninit(self.fd.as_fd(), self.buf) { - Ok(0) => return None, - Ok(bytes_read) => { - self.initialized = bytes_read; - self.offset = 0; - } - Err(e) => return Some(Err(e)), - } - } - - let dirent_ptr = self.buf[self.offset..].as_ptr(); - // SAFETY: - // - This data is initialized by the check above. - // - Assumption: the kernel will not give us partial structs. - // - Assumption: the kernel uses proper alignment between structs. - // - The starting pointer is aligned (performed in `RawDir::new`). - let dirent = unsafe { &*dirent_ptr.cast::<linux_dirent64>() }; - - self.offset += usize::from(dirent.d_reclen); - - Some(Ok(RawDirEntry { - file_type: dirent.d_type, - inode_number: dirent.d_ino.into(), - next_entry_cookie: dirent.d_off.into(), - // SAFETY: The kernel guarantees a NUL-terminated string. - file_name: unsafe { CStr::from_ptr(dirent.d_name.as_ptr().cast()) }, - })) - } - - /// Returns true if the internal buffer is empty and will be refilled when - /// calling [`next`]. - /// - /// [`next`]: Self::next - pub fn is_buffer_empty(&self) -> bool { - self.offset >= self.initialized - } -} diff --git a/vendor/rustix/src/fs/seek_from.rs b/vendor/rustix/src/fs/seek_from.rs deleted file mode 100644 index bc0907ca..00000000 --- a/vendor/rustix/src/fs/seek_from.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/io/mod.rs at revision -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. - -/// Enumeration of possible methods to seek within an I/O object. -/// -/// It is used by the [`seek`] function. -/// -/// This is similar to [`std::io::SeekFrom`], however it adds platform-specific -/// seek options. -/// -/// [`seek`]: crate::fs::seek -#[derive(Copy, PartialEq, Eq, Clone, Debug)] -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub enum SeekFrom { - /// Sets the offset to the provided number of bytes. - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - Start(#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] u64), - - /// Sets the offset to the size of this object plus the specified number of - /// bytes. - /// - /// It is possible to seek beyond the end of an object, but it's an error - /// to seek before byte 0. - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - End(#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] i64), - - /// Sets the offset to the current position plus the specified number of - /// bytes. - /// - /// It is possible to seek beyond the end of an object, but it's an error - /// to seek before byte 0. - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - Current(#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] i64), - - /// Sets the offset to the current position plus the specified number of - /// bytes, plus the distance to the next byte which is not in a hole. - /// - /// If the offset is in a hole at the end of the file, the seek will fail - /// with [`Errno::NXIO`]. - /// - /// [`Errno::NXIO`]: crate::io::Errno::NXIO - #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - Data(u64), - - /// Sets the offset to the current position plus the specified number of - /// bytes, plus the distance to the next byte which is in a hole. - /// - /// If there is no hole past the offset, it will be set to the end of the - /// file i.e. there is an implicit hole at the end of any file. - #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - Hole(u64), -} diff --git a/vendor/rustix/src/fs/sendfile.rs b/vendor/rustix/src/fs/sendfile.rs deleted file mode 100644 index db3d6022..00000000 --- a/vendor/rustix/src/fs/sendfile.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::{backend, io}; -use backend::fd::AsFd; - -/// `sendfile(out_fd, in_fd, offset, count)`—Transfer data between file -/// descriptors. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sendfile.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn sendfile<OutFd: AsFd, InFd: AsFd>( - out_fd: OutFd, - in_fd: InFd, - offset: Option<&mut u64>, - count: usize, -) -> io::Result<usize> { - backend::fs::syscalls::sendfile(out_fd.as_fd(), in_fd.as_fd(), offset, count) -} diff --git a/vendor/rustix/src/fs/special.rs b/vendor/rustix/src/fs/special.rs deleted file mode 100644 index 276a775f..00000000 --- a/vendor/rustix/src/fs/special.rs +++ /dev/null @@ -1,80 +0,0 @@ -//! The `CWD` and `ABS` constants, representing the current working directory -//! and absolute-only paths, respectively. -//! -//! # Safety -//! -//! This file uses `AT_FDCWD`, which is a raw file descriptor, but which is -//! always valid, and `-EBADF`, which is an undocumented by commonly used -//! convention of passing a value which will always fail if the accompanying -//! path isn't absolute. - -#![allow(unsafe_code)] - -use crate::backend; -use backend::c; -use backend::fd::{BorrowedFd, RawFd}; - -/// `AT_FDCWD`—A handle representing the current working directory. -/// -/// This is a file descriptor which refers to the process current directory -/// which can be used as the directory argument in `*at` functions such as -/// [`openat`]. -/// -/// # References -/// - [POSIX] -/// -/// [`openat`]: crate::fs::openat -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/fcntl.h.html -// SAFETY: `AT_FDCWD` is a reserved value that is never dynamically -// allocated, so it'll remain valid for the duration of `'static`. -#[cfg(not(target_os = "horizon"))] -#[doc(alias = "AT_FDCWD")] -pub const CWD: BorrowedFd<'static> = - unsafe { BorrowedFd::<'static>::borrow_raw(c::AT_FDCWD as RawFd) }; - -/// `-EBADF`—A handle that requires paths to be absolute. -/// -/// This is a file descriptor which refers to no directory, which can be used -/// as the directory argument in `*at` functions such as [`openat`], which -/// causes them to fail with [`BADF`] if the accompanying path is not absolute. -/// -/// This corresponds to the undocumented by commonly used convention of -/// passing `-EBADF` as the `dirfd` argument, which is ignored if the path is -/// absolute, and evokes an `EBADF` error otherwise. -/// -/// [`openat`]: crate::fs::openat -/// [`BADF`]: crate::io::Errno::BADF -// SAFETY: This `-EBADF` convention is commonly used, such as in lxc, so OS's -// aren't going to break it. -pub const ABS: BorrowedFd<'static> = - unsafe { BorrowedFd::<'static>::borrow_raw(c::EBADF.wrapping_neg() as RawFd) }; - -#[cfg(test)] -mod tests { - use super::*; - use crate::fd::AsRawFd as _; - - #[test] - fn test_cwd() { - assert!(CWD.as_raw_fd() != -1); - assert!(CWD.as_raw_fd() != c::STDIN_FILENO); - assert!(CWD.as_raw_fd() != c::STDOUT_FILENO); - assert!(CWD.as_raw_fd() != c::STDERR_FILENO); - #[cfg(linux_kernel)] - #[cfg(feature = "io_uring")] - assert!(CWD.as_raw_fd() != crate::io_uring::IORING_REGISTER_FILES_SKIP.as_raw_fd()); - } - - #[test] - fn test_abs() { - assert!(ABS.as_raw_fd() < 0); - assert!(ABS.as_raw_fd() != -1); - assert!(ABS.as_raw_fd() != c::AT_FDCWD); - assert!(ABS.as_raw_fd() != c::STDIN_FILENO); - assert!(ABS.as_raw_fd() != c::STDOUT_FILENO); - assert!(ABS.as_raw_fd() != c::STDERR_FILENO); - #[cfg(linux_kernel)] - #[cfg(feature = "io_uring")] - assert!(ABS.as_raw_fd() != crate::io_uring::IORING_REGISTER_FILES_SKIP.as_raw_fd()); - } -} diff --git a/vendor/rustix/src/fs/statx.rs b/vendor/rustix/src/fs/statx.rs deleted file mode 100644 index f1d995ec..00000000 --- a/vendor/rustix/src/fs/statx.rs +++ /dev/null @@ -1,275 +0,0 @@ -//! Linux `statx`. - -use crate::fd::AsFd; -use crate::fs::AtFlags; -use crate::{backend, io, path}; -use backend::c; -use bitflags::bitflags; - -#[cfg(feature = "linux_4_11")] -use backend::fs::syscalls::statx as _statx; -#[cfg(not(feature = "linux_4_11"))] -use compat::statx as _statx; - -/// `struct statx` for use with [`statx`]. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -#[non_exhaustive] -pub struct Statx { - pub stx_mask: u32, - pub stx_blksize: u32, - pub stx_attributes: StatxAttributes, - pub stx_nlink: u32, - pub stx_uid: u32, - pub stx_gid: u32, - pub stx_mode: u16, - pub(crate) __spare0: [u16; 1], - pub stx_ino: u64, - pub stx_size: u64, - pub stx_blocks: u64, - pub stx_attributes_mask: StatxAttributes, - pub stx_atime: StatxTimestamp, - pub stx_btime: StatxTimestamp, - pub stx_ctime: StatxTimestamp, - pub stx_mtime: StatxTimestamp, - pub stx_rdev_major: u32, - pub stx_rdev_minor: u32, - pub stx_dev_major: u32, - pub stx_dev_minor: u32, - pub stx_mnt_id: u64, - pub stx_dio_mem_align: u32, - pub stx_dio_offset_align: u32, - pub stx_subvol: u64, - pub stx_atomic_write_unit_min: u32, - pub stx_atomic_write_unit_max: u32, - pub stx_atomic_write_segments_max: u32, - pub(crate) __spare1: [u32; 1], - pub(crate) __spare3: [u64; 9], -} - -/// `struct statx_timestamp` for use with [`Statx`]. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[non_exhaustive] -pub struct StatxTimestamp { - /// Seconds. - pub tv_sec: i64, - - /// Nanoseconds. Must be less than 1_000_000_000. - pub tv_nsec: u32, - - pub(crate) __reserved: i32, -} - -bitflags! { - /// `STATX_*` constants for use with [`statx`]. - /// - /// [`statx`]: crate::fs::statx - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct StatxFlags: u32 { - /// `STATX_TYPE` - const TYPE = c::STATX_TYPE; - - /// `STATX_MODE` - const MODE = c::STATX_MODE; - - /// `STATX_NLINK` - const NLINK = c::STATX_NLINK; - - /// `STATX_UID` - const UID = c::STATX_UID; - - /// `STATX_GID` - const GID = c::STATX_GID; - - /// `STATX_ATIME` - const ATIME = c::STATX_ATIME; - - /// `STATX_MTIME` - const MTIME = c::STATX_MTIME; - - /// `STATX_CTIME` - const CTIME = c::STATX_CTIME; - - /// `STATX_INO` - const INO = c::STATX_INO; - - /// `STATX_SIZE` - const SIZE = c::STATX_SIZE; - - /// `STATX_BLOCKS` - const BLOCKS = c::STATX_BLOCKS; - - /// `STATX_BASIC_STATS` - const BASIC_STATS = c::STATX_BASIC_STATS; - - /// `STATX_BTIME` - const BTIME = c::STATX_BTIME; - - /// `STATX_MNT_ID` (since Linux 5.8) - const MNT_ID = c::STATX_MNT_ID; - - /// `STATX_DIOALIGN` (since Linux 6.1) - const DIOALIGN = c::STATX_DIOALIGN; - - /// `STATX_ALL` - const ALL = c::STATX_ALL; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// `STATX_ATTR_*` flags for use with [`Statx`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct StatxAttributes: u64 { - /// `STATX_ATTR_COMPRESSED` - const COMPRESSED = c::STATX_ATTR_COMPRESSED as u64; - - /// `STATX_ATTR_IMMUTABLE` - const IMMUTABLE = c::STATX_ATTR_IMMUTABLE as u64; - - /// `STATX_ATTR_APPEND` - const APPEND = c::STATX_ATTR_APPEND as u64; - - /// `STATX_ATTR_NODUMP` - const NODUMP = c::STATX_ATTR_NODUMP as u64; - - /// `STATX_ATTR_ENCRYPTED` - const ENCRYPTED = c::STATX_ATTR_ENCRYPTED as u64; - - /// `STATX_ATTR_AUTOMOUNT` - const AUTOMOUNT = c::STATX_ATTR_AUTOMOUNT as u64; - - /// `STATX_ATTR_MOUNT_ROOT` - const MOUNT_ROOT = c::STATX_ATTR_MOUNT_ROOT as u64; - - /// `STATX_ATTR_VERITY` - const VERITY = c::STATX_ATTR_VERITY as u64; - - /// `STATX_ATTR_DAX` - const DAX = c::STATX_ATTR_DAX as u64; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `statx(dirfd, path, flags, mask, statxbuf)`—Extended `stat`. -/// -/// This function returns [`io::Errno::NOSYS`] if `statx` is not available on -/// the platform, such as Linux before 4.11. This also includes older Docker -/// versions where the actual syscall fails with different error codes; rustix -/// handles this and translates them into `NOSYS`. -/// -/// # References -/// - [Linux] -/// -/// # Examples -/// -/// ``` -/// # use std::path::Path; -/// # use std::io; -/// # use rustix::fs::{AtFlags, StatxFlags}; -/// # use rustix::fd::BorrowedFd; -/// /// Try to determine if the provided path is a mount root. Will return -/// /// `Ok(None)` if the kernel is not new enough to support `statx` or -/// /// [`StatxAttributes::MOUNT_ROOT`]. -/// fn is_mountpoint(root: BorrowedFd<'_>, path: &Path) -> io::Result<Option<bool>> { -/// use rustix::fs::{AtFlags, StatxAttributes, StatxFlags}; -/// -/// match rustix::fs::statx( -/// root, -/// path, -/// AtFlags::NO_AUTOMOUNT | AtFlags::SYMLINK_NOFOLLOW, -/// StatxFlags::empty(), -/// ) { -/// Ok(r) => { -/// let present = r.stx_attributes_mask.contains(StatxAttributes::MOUNT_ROOT); -/// Ok(present.then(|| r.stx_attributes.contains(StatxAttributes::MOUNT_ROOT))) -/// } -/// Err(rustix::io::Errno::NOSYS) => Ok(None), -/// Err(e) => Err(e.into()), -/// } -/// } -/// ``` -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/statx.2.html -#[inline] -pub fn statx<P: path::Arg, Fd: AsFd>( - dirfd: Fd, - path: P, - flags: AtFlags, - mask: StatxFlags, -) -> io::Result<Statx> { - path.into_with_c_str(|path| _statx(dirfd.as_fd(), path, flags, mask)) -} - -#[cfg(not(feature = "linux_4_11"))] -mod compat { - use crate::fd::BorrowedFd; - use crate::ffi::CStr; - use crate::fs::{AtFlags, Statx, StatxFlags}; - use crate::{backend, io}; - use core::sync::atomic::{AtomicU8, Ordering}; - - // Linux kernel prior to 4.11 and old versions of Docker don't support - // `statx`. We store the availability in a global to avoid unnecessary - // syscalls. - // - // 0: Unknown - // 1: Not available - // 2: Available - static STATX_STATE: AtomicU8 = AtomicU8::new(0); - - #[inline] - pub fn statx( - dirfd: BorrowedFd<'_>, - path: &CStr, - flags: AtFlags, - mask: StatxFlags, - ) -> io::Result<Statx> { - match STATX_STATE.load(Ordering::Relaxed) { - 0 => statx_init(dirfd, path, flags, mask), - 1 => Err(io::Errno::NOSYS), - _ => backend::fs::syscalls::statx(dirfd, path, flags, mask), - } - } - - /// The first `statx` call. We don't know if `statx` is available yet. - fn statx_init( - dirfd: BorrowedFd<'_>, - path: &CStr, - flags: AtFlags, - mask: StatxFlags, - ) -> io::Result<Statx> { - match backend::fs::syscalls::statx(dirfd, path, flags, mask) { - Err(err) => statx_error(err), - result => { - STATX_STATE.store(2, Ordering::Relaxed); - result - } - } - } - - /// The first `statx` call failed. We can get a variety of error codes - /// from seccomp configs or faulty FUSE drivers, so we don't trust - /// `ENOSYS` or `EPERM` to tell us whether statx is available. - #[cold] - fn statx_error(err: io::Errno) -> io::Result<Statx> { - if backend::fs::syscalls::is_statx_available() { - // Statx is available. Record this, and fail with the error - // code of the initial `statx` call. - STATX_STATE.store(2, Ordering::Relaxed); - Err(err) - } else { - // Statx is not available. Record this, and fail with `NOSYS`. - STATX_STATE.store(1, Ordering::Relaxed); - Err(io::Errno::NOSYS) - } - } -} diff --git a/vendor/rustix/src/fs/sync.rs b/vendor/rustix/src/fs/sync.rs deleted file mode 100644 index cb5f0704..00000000 --- a/vendor/rustix/src/fs/sync.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::backend; - -/// `sync`—Flush cached filesystem data for all filesystems. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sync.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sync.2.html -#[inline] -pub fn sync() { - backend::fs::syscalls::sync(); -} diff --git a/vendor/rustix/src/fs/xattr.rs b/vendor/rustix/src/fs/xattr.rs deleted file mode 100644 index ea0eaea1..00000000 --- a/vendor/rustix/src/fs/xattr.rs +++ /dev/null @@ -1,256 +0,0 @@ -//! Extended attribute functions. - -#![allow(unsafe_code)] - -use crate::buffer::Buffer; -use crate::{backend, ffi, io, path}; -use backend::c; -use backend::fd::AsFd; -use bitflags::bitflags; - -bitflags! { - /// `XATTR_*` constants for use with [`setxattr`], and other `*setxattr` - /// functions. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XattrFlags: ffi::c_uint { - /// `XATTR_CREATE` - const CREATE = c::XATTR_CREATE as c::c_uint; - - /// `XATTR_REPLACE` - const REPLACE = c::XATTR_REPLACE as c::c_uint; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `getxattr(path, name, value)`—Get extended filesystem attributes. -/// -/// For a higher-level API to xattr functionality, see the [xattr] crate. -/// -/// [xattr]: https://crates.io/crates/xattr -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/getxattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getxattr.2.html -#[inline] -pub fn getxattr<P: path::Arg, Name: path::Arg, Buf: Buffer<u8>>( - path: P, - name: Name, - mut value: Buf, -) -> io::Result<Buf::Output> { - path.into_with_c_str(|path| { - name.into_with_c_str(|name| { - // SAFETY: `getxattr` behaves. - let len = unsafe { backend::fs::syscalls::getxattr(path, name, value.parts_mut())? }; - // SAFETY: `getxattr` behaves. - unsafe { Ok(value.assume_init(len)) } - }) - }) -} - -/// `lgetxattr(path, name, value.as_ptr(), value.len())`—Get extended -/// filesystem attributes, without following symlinks in the last path -/// component. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/lgetxattr.2.html -#[inline] -pub fn lgetxattr<P: path::Arg, Name: path::Arg, Buf: Buffer<u8>>( - path: P, - name: Name, - mut value: Buf, -) -> io::Result<Buf::Output> { - path.into_with_c_str(|path| { - name.into_with_c_str(|name| { - // SAFETY: `lgetxattr` behaves. - let len = unsafe { backend::fs::syscalls::lgetxattr(path, name, value.parts_mut())? }; - // SAFETY: `lgetxattr` behaves. - unsafe { Ok(value.assume_init(len)) } - }) - }) -} - -/// `fgetxattr(fd, name, value.as_ptr(), value.len())`—Get extended -/// filesystem attributes on an open file descriptor. -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fgetxattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fgetxattr.2.html -#[inline] -pub fn fgetxattr<Fd: AsFd, Name: path::Arg, Buf: Buffer<u8>>( - fd: Fd, - name: Name, - mut value: Buf, -) -> io::Result<Buf::Output> { - name.into_with_c_str(|name| { - // SAFETY: `fgetxattr` behaves. - let len = unsafe { backend::fs::syscalls::fgetxattr(fd.as_fd(), name, value.parts_mut())? }; - // SAFETY: `fgetxattr` behaves. - unsafe { Ok(value.assume_init(len)) } - }) -} - -/// `setxattr(path, name, value.as_ptr(), value.len(), flags)`—Set extended -/// filesystem attributes. -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setxattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setxattr.2.html -#[inline] -pub fn setxattr<P: path::Arg, Name: path::Arg>( - path: P, - name: Name, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - path.into_with_c_str(|path| { - name.into_with_c_str(|name| backend::fs::syscalls::setxattr(path, name, value, flags)) - }) -} - -/// `setxattr(path, name, value.as_ptr(), value.len(), flags)`—Set extended -/// filesystem attributes, without following symlinks in the last path -/// component. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/lsetxattr.2.html -#[inline] -pub fn lsetxattr<P: path::Arg, Name: path::Arg>( - path: P, - name: Name, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - path.into_with_c_str(|path| { - name.into_with_c_str(|name| backend::fs::syscalls::lsetxattr(path, name, value, flags)) - }) -} - -/// `fsetxattr(fd, name, value.as_ptr(), value.len(), flags)`—Set extended -/// filesystem attributes on an open file descriptor. -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fsetxattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fsetxattr.2.html -#[inline] -pub fn fsetxattr<Fd: AsFd, Name: path::Arg>( - fd: Fd, - name: Name, - value: &[u8], - flags: XattrFlags, -) -> io::Result<()> { - name.into_with_c_str(|name| backend::fs::syscalls::fsetxattr(fd.as_fd(), name, value, flags)) -} - -/// `listxattr(path, list.as_ptr(), list.len())`—List extended filesystem -/// attributes. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/listxattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/listxattr.2.html -#[inline] -pub fn listxattr<P: path::Arg, Buf: Buffer<u8>>(path: P, mut list: Buf) -> io::Result<Buf::Output> { - path.into_with_c_str(|path| { - // SAFETY: `listxattr` behaves. - let len = unsafe { backend::fs::syscalls::listxattr(path, list.parts_mut())? }; - // SAFETY: `listxattr` behaves. - unsafe { Ok(list.assume_init(len)) } - }) -} - -/// `llistxattr(path, list.as_ptr(), list.len())`—List extended filesystem -/// attributes, without following symlinks in the last path component. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/llistxattr.2.html -#[inline] -pub fn llistxattr<P: path::Arg, Buf: Buffer<u8>>( - path: P, - mut list: Buf, -) -> io::Result<Buf::Output> { - path.into_with_c_str(|path| { - // SAFETY: `flistxattr` behaves. - let len = unsafe { backend::fs::syscalls::llistxattr(path, list.parts_mut())? }; - // SAFETY: `flistxattr` behaves. - unsafe { Ok(list.assume_init(len)) } - }) -} - -/// `flistxattr(fd, list.as_ptr(), list.len())`—List extended filesystem -/// attributes on an open file descriptor. -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/flistxattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/flistxattr.2.html -#[inline] -pub fn flistxattr<Fd: AsFd, Buf: Buffer<u8>>(fd: Fd, mut list: Buf) -> io::Result<Buf::Output> { - // SAFETY: `flistxattr` behaves. - let len = unsafe { backend::fs::syscalls::flistxattr(fd.as_fd(), list.parts_mut())? }; - // SAFETY: `flistxattr` behaves. - unsafe { Ok(list.assume_init(len)) } -} - -/// `removexattr(path, name)`—Remove an extended filesystem attribute. -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/removexattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/removexattr.2.html -pub fn removexattr<P: path::Arg, Name: path::Arg>(path: P, name: Name) -> io::Result<()> { - path.into_with_c_str(|path| { - name.into_with_c_str(|name| backend::fs::syscalls::removexattr(path, name)) - }) -} - -/// `lremovexattr(path, name)`—Remove an extended filesystem attribute, -/// without following symlinks in the last path component. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/lremovexattr.2.html -pub fn lremovexattr<P: path::Arg, Name: path::Arg>(path: P, name: Name) -> io::Result<()> { - path.into_with_c_str(|path| { - name.into_with_c_str(|name| backend::fs::syscalls::lremovexattr(path, name)) - }) -} - -/// `fremovexattr(fd, name)`—Remove an extended filesystem attribute on an -/// open file descriptor. -/// -/// # References -/// - [Linux] -/// - [Apple] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fremovexattr.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fremovexattr.2.html -pub fn fremovexattr<Fd: AsFd, Name: path::Arg>(fd: Fd, name: Name) -> io::Result<()> { - name.into_with_c_str(|name| backend::fs::syscalls::fremovexattr(fd.as_fd(), name)) -} diff --git a/vendor/rustix/src/io/close.rs b/vendor/rustix/src/io/close.rs deleted file mode 100644 index 9317edfe..00000000 --- a/vendor/rustix/src/io/close.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! The unsafe `close` for raw file descriptors. -//! -//! # Safety -//! -//! Operating on raw file descriptors is unsafe. -#![allow(unsafe_code)] - -use crate::backend; -use backend::fd::RawFd; - -/// `close(raw_fd)`—Closes a `RawFd` directly. -/// -/// Most users won't need to use this, as [`OwnedFd`] automatically closes its -/// file descriptor on `Drop`. -/// -/// This function does not return a `Result`, as it is the [responsibility] of -/// filesystem designers to not return errors from `close`. Users who chose to -/// use NFS or similar filesystems should take care to monitor for problems -/// externally. -/// -/// [responsibility]: https://lwn.net/Articles/576518/ -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [`OwnedFd`]: crate::fd::OwnedFd -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#close-and-shutdownget-outta-my-face -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/close.html -/// [Linux]: https://man7.org/linux/man-pages/man2/close.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/close.2.html#//apple_ref/doc/man/2/close -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-closesocket -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=close&sektion=2 -/// [NetBSD]: https://man.netbsd.org/close.2 -/// [OpenBSD]: https://man.openbsd.org/close.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=close§ion=2 -/// [illumos]: https://illumos.org/man/2/close -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Opening-and-Closing-Files.html#index-close -/// -/// # Safety -/// -/// This function takes a `RawFd`, which must be valid before the call, and is -/// not valid after the call. -#[inline] -pub unsafe fn close(raw_fd: RawFd) { - backend::io::syscalls::close(raw_fd) -} - -/// `close(raw_fd)`—Closes a `RawFd` directly, and report any errors returned -/// by the OS. -/// -/// The rustix developers do not intend the existence of this feature to imply -/// that anyone should use it. -/// -/// # Safety -/// -/// This function takes a `RawFd`, which must be valid before the call, and is -/// not valid after the call, even if it fails. -#[cfg(feature = "try_close")] -pub unsafe fn try_close(raw_fd: RawFd) -> crate::io::Result<()> { - backend::io::syscalls::try_close(raw_fd) -} diff --git a/vendor/rustix/src/io/dup.rs b/vendor/rustix/src/io/dup.rs deleted file mode 100644 index 1d1a4852..00000000 --- a/vendor/rustix/src/io/dup.rs +++ /dev/null @@ -1,125 +0,0 @@ -//! Functions which duplicate file descriptors. - -use crate::fd::OwnedFd; -use crate::{backend, io}; -use backend::fd::AsFd; - -#[cfg(not(target_os = "wasi"))] -pub use backend::io::types::DupFlags; - -/// `dup(fd)`—Creates a new `OwnedFd` instance that shares the same -/// underlying [file description] as `fd`. -/// -/// This function does not set the `O_CLOEXEC` flag. To do a `dup` that does -/// set `O_CLOEXEC`, use [`fcntl_dupfd_cloexec`]. -/// -/// POSIX guarantees that `dup` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [file description]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_258 -/// [`fcntl_dupfd_cloexec`]: crate::io::fcntl_dupfd_cloexec -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/dup.html -/// [Linux]: https://man7.org/linux/man-pages/man2/dup.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/dup.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=dup&sektion=2 -/// [NetBSD]: https://man.netbsd.org/dup.2 -/// [OpenBSD]: https://man.openbsd.org/dup.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=dup§ion=2 -/// [illumos]: https://illumos.org/man/2/dup -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Duplicating-Descriptors.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn dup<Fd: AsFd>(fd: Fd) -> io::Result<OwnedFd> { - backend::io::syscalls::dup(fd.as_fd()) -} - -/// `dup2(fd, new)`—Changes the [file description] of a file descriptor. -/// -/// `dup2` conceptually closes `new` and then sets the file description for -/// `new` to be the same as the one for `fd`. This is a very unusual operation, -/// and should only be used on file descriptors where you know how `new` will -/// be subsequently used. -/// -/// This function does not set the `O_CLOEXEC` flag. To do a `dup2` that does -/// set `O_CLOEXEC`, use [`dup3`] with [`DupFlags::CLOEXEC`] on platforms which -/// support it, or [`fcntl_dupfd_cloexec`]. -/// -/// For `dup2` to stdin, stdout, and stderr, see [`stdio::dup2_stdin`], -/// [`stdio::dup2_stdout`], and [`stdio::dup2_stderr`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [file description]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_258 -/// [`fcntl_dupfd_cloexec`]: crate::io::fcntl_dupfd_cloexec -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/dup2.html -/// [Linux]: https://man7.org/linux/man-pages/man2/dup2.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/dup2.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=dup2&sektion=2 -/// [NetBSD]: https://man.netbsd.org/dup2.2 -/// [OpenBSD]: https://man.openbsd.org/dup2.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=dup2§ion=2 -/// [illumos]: https://illumos.org/man/2/dup -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Duplicating-Descriptors.html -/// [`stdio::dup2_stdin`]: crate::stdio::dup2_stdin -/// [`stdio::dup2_stdout`]: crate::stdio::dup2_stdout -/// [`stdio::dup2_stderr`]: crate::stdio::dup2_stderr -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn dup2<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> io::Result<()> { - backend::io::syscalls::dup2(fd.as_fd(), new) -} - -/// `dup3(fd, new, flags)`—Changes the [file description] of a file -/// descriptor, with flags. -/// -/// `dup3` is the same as [`dup2`] but adds an additional flags operand, and it -/// fails in the case that `fd` and `new` have the same file descriptor value. -/// This additional difference is the reason this function isn't named -/// `dup2_with`. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// -/// [file description]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_258 -/// [Linux]: https://man7.org/linux/man-pages/man2/dup3.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=dup3&sektion=3 -/// [NetBSD]: https://man.netbsd.org/dup3.2 -/// [OpenBSD]: https://man.openbsd.org/dup3.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=dup3§ion=3 -#[cfg(not(any( - target_os = "aix", - target_os = "espidf", - target_os = "horizon", - target_os = "nto", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub fn dup3<Fd: AsFd>(fd: Fd, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { - backend::io::syscalls::dup3(fd.as_fd(), new, flags) -} diff --git a/vendor/rustix/src/io/errno.rs b/vendor/rustix/src/io/errno.rs deleted file mode 100644 index 7d3eadf7..00000000 --- a/vendor/rustix/src/io/errno.rs +++ /dev/null @@ -1,74 +0,0 @@ -//! The `Errno` type, which is a minimal wrapper around an error code. -//! -//! We define the error constants as individual `const`s instead of an enum -//! because we may not know about all of the host's error values and we don't -//! want unrecognized values to create undefined behavior. - -use crate::backend; -#[cfg(all(not(feature = "std"), error_in_core))] -use core::error; -use core::{fmt, result}; -#[cfg(feature = "std")] -use std::error; - -/// A specialized [`Result`] type for `rustix` APIs. -pub type Result<T> = result::Result<T, Errno>; - -pub use backend::io::errno::Errno; - -impl Errno { - /// Shorthand for `std::io::Error::from(self).kind()`. - #[cfg(feature = "std")] - #[inline] - pub fn kind(self) -> std::io::ErrorKind { - std::io::Error::from(self).kind() - } -} - -impl fmt::Display for Errno { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "std")] - { - std::io::Error::from(*self).fmt(f) - } - #[cfg(not(feature = "std"))] - { - write!(f, "os error {}", self.raw_os_error()) - } - } -} - -impl fmt::Debug for Errno { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(feature = "std")] - { - std::io::Error::from(*self).fmt(f) - } - #[cfg(not(feature = "std"))] - { - write!(f, "os error {}", self.raw_os_error()) - } - } -} - -#[cfg(any(feature = "std", error_in_core))] -impl error::Error for Errno {} - -#[cfg(feature = "std")] -impl From<Errno> for std::io::Error { - #[inline] - fn from(err: Errno) -> Self { - Self::from_raw_os_error(err.raw_os_error() as _) - } -} - -/// Call `f` until it either succeeds or fails other than [`Errno::INTR`]. -#[inline] -pub fn retry_on_intr<T, F: FnMut() -> Result<T>>(mut f: F) -> Result<T> { - loop { - match f() { - Err(Errno::INTR) => (), - result => return result, - } - } -} diff --git a/vendor/rustix/src/io/fcntl.rs b/vendor/rustix/src/io/fcntl.rs deleted file mode 100644 index fcb63a3b..00000000 --- a/vendor/rustix/src/io/fcntl.rs +++ /dev/null @@ -1,143 +0,0 @@ -//! The Unix `fcntl` function is effectively lots of different functions hidden -//! behind a single dynamic dispatch interface. In order to provide a type-safe -//! API, rustix makes them all separate functions so that they can have -//! dedicated static type signatures. -//! -//! `fcntl` functions which are not specific to files or directories live in -//! the [`io`] module instead. -//! -//! [`io`]: crate::io - -use crate::{backend, io}; -use backend::fd::{AsFd, OwnedFd, RawFd}; - -pub use backend::io::types::FdFlags; - -/// `fcntl(fd, F_GETFD)`—Returns a file descriptor's flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=fcntl&sektion=2 -/// [NetBSD]: https://man.netbsd.org/fcntl.2 -/// [OpenBSD]: https://man.openbsd.org/fcntl.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=fcntl§ion=2 -/// [illumos]: https://illumos.org/man/2/fcntl -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Control-Operations.html#index-fcntl-function -#[inline] -#[doc(alias = "F_GETFD")] -pub fn fcntl_getfd<Fd: AsFd>(fd: Fd) -> io::Result<FdFlags> { - backend::io::syscalls::fcntl_getfd(fd.as_fd()) -} - -/// `fcntl(fd, F_SETFD, flags)`—Sets a file descriptor's flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=fcntl&sektion=2 -/// [NetBSD]: https://man.netbsd.org/fcntl.2 -/// [OpenBSD]: https://man.openbsd.org/fcntl.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=fcntl§ion=2 -/// [illumos]: https://illumos.org/man/2/fcntl -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Control-Operations.html#index-fcntl-function -#[inline] -#[doc(alias = "F_SETFD")] -pub fn fcntl_setfd<Fd: AsFd>(fd: Fd, flags: FdFlags) -> io::Result<()> { - backend::io::syscalls::fcntl_setfd(fd.as_fd(), flags) -} - -/// `fcntl(fd, F_DUPFD_CLOEXEC)`—Creates a new `OwnedFd` instance, with value -/// at least `min`, that has `O_CLOEXEC` set and that shares the same -/// underlying [file description] as `fd`. -/// -/// POSIX guarantees that `F_DUPFD_CLOEXEC` will use the lowest unused file -/// descriptor which is at least `min`, however it is not safe in general to -/// rely on this, as file descriptors may be unexpectedly allocated on other -/// threads or in libraries. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=fcntl&sektion=2 -/// [NetBSD]: https://man.netbsd.org/fcntl.2 -/// [OpenBSD]: https://man.openbsd.org/fcntl.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=fcntl§ion=2 -/// [illumos]: https://illumos.org/man/2/fcntl -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Control-Operations.html#index-fcntl-function -/// [file description]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_258 -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -#[inline] -#[doc(alias = "F_DUPFD_CLOEXEC")] -pub fn fcntl_dupfd_cloexec<Fd: AsFd>(fd: Fd, min: RawFd) -> io::Result<OwnedFd> { - backend::io::syscalls::fcntl_dupfd_cloexec(fd.as_fd(), min) -} - -/// `fcntl(fd, F_DUPFD)`—Creates a new `OwnedFd` instance, with value at -/// least `min`, that shares the same underlying [file description] as `fd`. -/// -/// POSIX guarantees that `F_DUPFD` will use the lowest unused file descriptor -/// which is at least `min`, however it is not safe in general to rely on this, -/// as file descriptors may be unexpectedly allocated on other threads or in -/// libraries. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=fcntl&sektion=2 -/// [NetBSD]: https://man.netbsd.org/fcntl.2 -/// [OpenBSD]: https://man.openbsd.org/fcntl.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=fcntl§ion=2 -/// [illumos]: https://illumos.org/man/2/fcntl -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Control-Operations.html#index-fcntl-function -/// [file description]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_258 -#[cfg(target_os = "espidf")] -#[inline] -#[doc(alias = "F_DUPFD")] -pub fn fcntl_dupfd<Fd: AsFd>(fd: Fd, min: RawFd) -> io::Result<OwnedFd> { - backend::io::syscalls::fcntl_dupfd(fd.as_fd(), min) -} diff --git a/vendor/rustix/src/io/ioctl.rs b/vendor/rustix/src/io/ioctl.rs deleted file mode 100644 index b47269f1..00000000 --- a/vendor/rustix/src/io/ioctl.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! The Unix `ioctl` function is effectively lots of different functions hidden -//! behind a single dynamic dispatch interface. In order to provide a type-safe -//! API, rustix makes them all separate functions so that they can have -//! dedicated static type signatures. -//! -//! Some ioctls, such as those related to filesystems, terminals, and -//! processes, live in other top-level API modules. - -#![allow(unsafe_code)] - -use crate::{backend, io, ioctl}; -use backend::c; -use backend::fd::AsFd; - -/// `ioctl(fd, FIOCLEX, NULL)`—Set the close-on-exec flag. -/// -/// This is similar to `fcntl(fd, F_SETFD, FD_CLOEXEC)`, except that it avoids -/// clearing any other flags that might be set. -#[cfg(apple)] -#[inline] -#[doc(alias = "FIOCLEX")] -#[doc(alias = "FD_CLOEXEC")] -pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> { - // SAFETY: `FIOCLEX` is a no-argument setter opcode. - unsafe { - let ctl = ioctl::NoArg::<{ c::FIOCLEX }>::new(); - ioctl::ioctl(fd, ctl) - } -} - -/// `ioctl(fd, FIONBIO, &value)`—Enables or disables non-blocking mode. -/// -/// # References -/// - [Winsock] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes -/// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS -/// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS -#[inline] -#[doc(alias = "FIONBIO")] -pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - // SAFETY: `FIONBIO` is a pointer setter opcode. - unsafe { - let ctl = ioctl::Setter::<{ c::FIONBIO }, c::c_int>::new(value.into()); - ioctl::ioctl(fd, ctl) - } -} - -/// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read. -/// -/// The result of this function gets silently coerced into a C `int` by the OS, -/// so it may contain a wrapped value. -/// -/// # References -/// - [Linux] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_tty.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#unix-ioctl-codes -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2#GENERIC%09IOCTLS -/// [NetBSD]: https://man.netbsd.org/ioctl.2#GENERIC%20IOCTLS -/// [OpenBSD]: https://man.openbsd.org/ioctl.2#GENERIC_IOCTLS -#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] -#[inline] -#[doc(alias = "FIONREAD")] -pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> { - // SAFETY: `FIONREAD` is a getter opcode that gets a `c_int`. - unsafe { - let ctl = ioctl::Getter::<{ c::FIONREAD }, c::c_int>::new(); - ioctl::ioctl(fd, ctl).map(|n| n as u64) - } -} diff --git a/vendor/rustix/src/io/mod.rs b/vendor/rustix/src/io/mod.rs deleted file mode 100644 index a2994d74..00000000 --- a/vendor/rustix/src/io/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! I/O operations. -//! -//! If you're looking for [`SeekFrom`], it's in the [`fs`] module. -//! -//! [`SeekFrom`]: crate::fs::SeekFrom -//! [`fs`]: crate::fs - -mod close; -#[cfg(not(windows))] -mod dup; -mod errno; -#[cfg(not(windows))] -mod fcntl; -mod ioctl; -mod read_write; - -pub use close::*; -#[cfg(not(windows))] -pub use dup::*; -pub use errno::{retry_on_intr, Errno, Result}; -#[cfg(not(windows))] -pub use fcntl::*; -pub use ioctl::*; -pub use read_write::*; diff --git a/vendor/rustix/src/io/read_write.rs b/vendor/rustix/src/io/read_write.rs deleted file mode 100644 index 572c7b65..00000000 --- a/vendor/rustix/src/io/read_write.rs +++ /dev/null @@ -1,310 +0,0 @@ -//! `read` and `write`, optionally positioned, optionally vectored. - -#![allow(unsafe_code)] - -use crate::buffer::Buffer; -use crate::{backend, io}; -use backend::fd::AsFd; - -// Declare `IoSlice` and `IoSliceMut`. -#[cfg(not(windows))] -pub use crate::maybe_polyfill::io::{IoSlice, IoSliceMut}; - -#[cfg(linux_kernel)] -pub use backend::io::types::ReadWriteFlags; - -/// `read(fd, buf)`—Reads from a stream. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/read.html -/// [Linux]: https://man7.org/linux/man-pages/man2/read.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/read.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=read&sektion=2 -/// [NetBSD]: https://man.netbsd.org/read.2 -/// [OpenBSD]: https://man.openbsd.org/read.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=read§ion=2 -/// [illumos]: https://illumos.org/man/2/read -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/I_002fO-Primitives.html#index-reading-from-a-file-descriptor -#[inline] -pub fn read<Fd: AsFd, Buf: Buffer<u8>>(fd: Fd, mut buf: Buf) -> io::Result<Buf::Output> { - // SAFETY: `read` behaves. - let len = unsafe { backend::io::syscalls::read(fd.as_fd(), buf.parts_mut())? }; - // SAFETY: `read` behaves. - unsafe { Ok(buf.assume_init(len)) } -} - -/// `write(fd, buf)`—Writes to a stream. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/write.html -/// [Linux]: https://man7.org/linux/man-pages/man2/write.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/write.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=write&sektion=2 -/// [NetBSD]: https://man.netbsd.org/write.2 -/// [OpenBSD]: https://man.openbsd.org/write.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=write§ion=2 -/// [illumos]: https://illumos.org/man/2/write -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/I_002fO-Primitives.html#index-writing-to-a-file-descriptor -#[inline] -pub fn write<Fd: AsFd>(fd: Fd, buf: &[u8]) -> io::Result<usize> { - backend::io::syscalls::write(fd.as_fd(), buf) -} - -/// `pread(fd, buf, offset)`—Reads from a file at a given position. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pread.html -/// [Linux]: https://man7.org/linux/man-pages/man2/pread.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pread.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pread&sektion=2 -/// [NetBSD]: https://man.netbsd.org/pread.2 -/// [OpenBSD]: https://man.openbsd.org/pread.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pread§ion=2 -/// [illumos]: https://illumos.org/man/2/pread -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/I_002fO-Primitives.html#index-pread64 -#[cfg(not(windows))] -#[inline] -pub fn pread<Fd: AsFd, Buf: Buffer<u8>>( - fd: Fd, - mut buf: Buf, - offset: u64, -) -> io::Result<Buf::Output> { - // SAFETY: `pread` behaves. - let len = unsafe { backend::io::syscalls::pread(fd.as_fd(), buf.parts_mut(), offset)? }; - // SAFETY: `pread` behaves. - unsafe { Ok(buf.assume_init(len)) } -} - -/// `pwrite(fd, bufs)`—Writes to a file at a given position. -/// -/// Contrary to POSIX, on many popular platforms including Linux and FreeBSD, -/// if the file is opened in append mode, this ignores the offset appends the -/// data to the end of the file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pwrite.html -/// [Linux]: https://man7.org/linux/man-pages/man2/pwrite.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pwrite.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pwrite&sektion=2 -/// [NetBSD]: https://man.netbsd.org/pwrite.2 -/// [OpenBSD]: https://man.openbsd.org/pwrite.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pwrite§ion=2 -/// [illumos]: https://illumos.org/man/2/pwrite -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/I_002fO-Primitives.html#index-pwrite64 -#[cfg(not(windows))] -#[inline] -pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: u64) -> io::Result<usize> { - backend::io::syscalls::pwrite(fd.as_fd(), buf, offset) -} - -/// `readv(fd, bufs)`—Reads from a stream into multiple buffers. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readv.html -/// [Linux]: https://man7.org/linux/man-pages/man2/readv.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/readv.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=readv&sektion=2 -/// [NetBSD]: https://man.netbsd.org/readv.2 -/// [OpenBSD]: https://man.openbsd.org/readv.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=readv§ion=2 -/// [illumos]: https://illumos.org/man/2/readv -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Scatter_002dGather.html#index-readv -#[cfg(not(any(windows, target_os = "espidf", target_os = "horizon")))] -#[inline] -pub fn readv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - backend::io::syscalls::readv(fd.as_fd(), bufs) -} - -/// `writev(fd, bufs)`—Writes to a stream from multiple buffers. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/writev.html -/// [Linux]: https://man7.org/linux/man-pages/man2/writev.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/writev.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=writev&sektion=2 -/// [NetBSD]: https://man.netbsd.org/writev.2 -/// [OpenBSD]: https://man.openbsd.org/writev.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=writev§ion=2 -/// [illumos]: https://illumos.org/man/2/writev -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Scatter_002dGather.html#index-writev -#[cfg(not(any(windows, target_os = "espidf", target_os = "horizon")))] -#[inline] -pub fn writev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - backend::io::syscalls::writev(fd.as_fd(), bufs) -} - -/// `preadv(fd, bufs, offset)`—Reads from a file at a given position into -/// multiple buffers. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/preadv.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=preadv&sektion=2 -/// [NetBSD]: https://man.netbsd.org/preadv.2 -/// [OpenBSD]: https://man.openbsd.org/preadv.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=preadv§ion=2 -/// [illumos]: https://illumos.org/man/2/preadv -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Scatter_002dGather.html#index-preadv64 -#[cfg(not(any( - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -#[inline] -pub fn preadv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { - backend::io::syscalls::preadv(fd.as_fd(), bufs, offset) -} - -/// `pwritev(fd, bufs, offset)`—Writes to a file at a given position from -/// multiple buffers. -/// -/// Contrary to POSIX, on many popular platforms including Linux and FreeBSD, -/// if the file is opened in append mode, this ignores the offset appends the -/// data to the end of the file. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pwritev.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pwritev&sektion=2 -/// [NetBSD]: https://man.netbsd.org/pwritev.2 -/// [OpenBSD]: https://man.openbsd.org/pwritev.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pwritev§ion=2 -/// [illumos]: https://illumos.org/man/2/pwritev -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/I_002fO-Primitives.html#index-pwrite64 -#[cfg(not(any( - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "solaris", - target_os = "vita", -)))] -#[inline] -pub fn pwritev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { - backend::io::syscalls::pwritev(fd.as_fd(), bufs, offset) -} - -/// `preadv2(fd, bufs, offset, flags)`—Reads data, with several options. -/// -/// An `offset` of `u64::MAX` means to use and update the current file offset. -/// -/// # References -/// - [Linux] -/// - [glibc] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/preadv2.2.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Scatter_002dGather.html#index-preadv64v2 -#[cfg(linux_kernel)] -#[inline] -pub fn preadv2<Fd: AsFd>( - fd: Fd, - bufs: &mut [IoSliceMut<'_>], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result<usize> { - backend::io::syscalls::preadv2(fd.as_fd(), bufs, offset, flags) -} - -/// `pwritev2(fd, bufs, offset, flags)`—Writes data, with several options. -/// -/// An `offset` of `u64::MAX` means to use and update the current file offset. -/// -/// # References -/// - [Linux] -/// - [glibc] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pwritev2.2.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Scatter_002dGather.html#index-pwritev64v2 -#[cfg(linux_kernel)] -#[inline] -pub fn pwritev2<Fd: AsFd>( - fd: Fd, - bufs: &[IoSlice<'_>], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result<usize> { - backend::io::syscalls::pwritev2(fd.as_fd(), bufs, offset, flags) -} diff --git a/vendor/rustix/src/io_uring/bindgen_types.rs b/vendor/rustix/src/io_uring/bindgen_types.rs deleted file mode 100644 index c45aefb6..00000000 --- a/vendor/rustix/src/io_uring/bindgen_types.rs +++ /dev/null @@ -1,101 +0,0 @@ -//! Local versions of types that bindgen would use. - -use crate::utils::{as_mut_ptr, as_ptr}; - -/// This represents an incomplete array field at the end of a struct. -/// -/// This is called `__IncompleteArrayField` in bindgen bindings. -#[repr(C)] -#[derive(Default)] -pub struct IncompleteArrayField<T>(::core::marker::PhantomData<T>, [T; 0]); - -#[allow(missing_docs)] -impl<T> IncompleteArrayField<T> { - #[inline] - pub const fn new() -> Self { - Self(::core::marker::PhantomData, []) - } - - #[inline] - pub fn as_ptr(&self) -> *const T { - as_ptr(self).cast::<T>() - } - - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { - as_mut_ptr(self).cast::<T>() - } - - #[inline] - pub unsafe fn as_slice(&self, len: usize) -> &[T] { - ::core::slice::from_raw_parts(self.as_ptr(), len) - } - - #[inline] - pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { - ::core::slice::from_raw_parts_mut(self.as_mut_ptr(), len) - } -} - -impl<T> ::core::fmt::Debug for IncompleteArrayField<T> { - fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - fmt.write_str("IncompleteArrayField") - } -} - -/// This represents a toplevel union field. -/// -/// This is called `__BindgenUnionField` in bindgen bindings. -pub struct UnionField<T>(::core::marker::PhantomData<T>); - -#[allow(missing_docs)] -impl<T> UnionField<T> { - #[inline] - pub const fn new() -> Self { - Self(::core::marker::PhantomData) - } - - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::core::mem::transmute(self) - } - - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::core::mem::transmute(self) - } -} - -impl<T> ::core::default::Default for UnionField<T> { - #[inline] - fn default() -> Self { - Self::new() - } -} - -impl<T> ::core::clone::Clone for UnionField<T> { - #[inline] - fn clone(&self) -> Self { - *self - } -} - -impl<T> ::core::marker::Copy for UnionField<T> {} - -impl<T> ::core::fmt::Debug for UnionField<T> { - fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - fmt.write_str("UnionField") - } -} - -impl<T> ::core::hash::Hash for UnionField<T> { - fn hash<H: ::core::hash::Hasher>(&self, _state: &mut H) {} -} - -impl<T> ::core::cmp::PartialEq for UnionField<T> { - fn eq(&self, _other: &Self) -> bool { - true - } -} - -impl<T> ::core::cmp::Eq for UnionField<T> {} diff --git a/vendor/rustix/src/io_uring/mod.rs b/vendor/rustix/src/io_uring/mod.rs deleted file mode 100644 index 5e375681..00000000 --- a/vendor/rustix/src/io_uring/mod.rs +++ /dev/null @@ -1,2207 +0,0 @@ -//! Linux [io_uring]. -//! -//! This API is very low-level. The main adaptations it makes from the raw -//! Linux io_uring API are the use of appropriately-sized `bitflags`, `enum`, -//! `Result`, `OwnedFd`, `AsFd`, `RawFd`, and `*mut c_void` in place of plain -//! integers. -//! -//! For a higher-level API built on top of this, see the [rustix-uring] crate. -//! -//! # Safety -//! -//! io_uring operates on raw pointers and raw file descriptors. Rustix does not -//! attempt to provide a safe API for these, because the abstraction level is -//! too low for this to be practical. Safety should be introduced in -//! higher-level abstraction layers. -//! -//! # References -//! - [Linux] -//! - [io_uring header] -//! -//! [Linux]: https://www.man7.org/linux/man-pages/man7/io_uring.7.html -//! [io_uring]: https://en.wikipedia.org/wiki/Io_uring -//! [io_uring header]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/io_uring.h?h=v6.13 -//! [rustix-uring]: https://crates.io/crates/rustix-uring -#![allow(unsafe_code)] - -mod bindgen_types; - -use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; -use crate::utils::option_as_ptr; -use crate::{backend, io}; -use bindgen_types::*; -use core::cmp::Ordering; -use core::ffi::c_void; -use core::hash::{Hash, Hasher}; -use core::mem::size_of; -use core::ptr::null_mut; -use linux_raw_sys::net; - -// Export types used in io_uring APIs. -pub use crate::clockid::ClockId; -pub use crate::event::epoll::{ - Event as EpollEvent, EventData as EpollEventData, EventFlags as EpollEventFlags, -}; -pub use crate::ffi::c_char; -pub use crate::fs::{ - Advice, AtFlags, Mode, OFlags, RenameFlags, ResolveFlags, Statx, StatxFlags, XattrFlags, -}; -pub use crate::io::ReadWriteFlags; -pub use crate::kernel_sigset::KernelSigSet; -pub use crate::net::addr::{SocketAddrLen, SocketAddrOpaque, SocketAddrStorage}; -pub use crate::net::{RecvFlags, SendFlags, SocketFlags}; -pub use crate::signal::Signal; -pub use crate::thread::futex::{ - Wait as FutexWait, WaitFlags as FutexWaitFlags, WaitPtr as FutexWaitPtr, - WaitvFlags as FutexWaitvFlags, -}; -pub use crate::timespec::{Nsecs, Secs, Timespec}; - -mod sys { - pub(super) use linux_raw_sys::io_uring::*; - #[cfg(test)] - pub(super) use { - crate::backend::c::iovec, linux_raw_sys::general::open_how, linux_raw_sys::net::msghdr, - }; -} - -/// `msghdr` -#[allow(missing_docs)] -#[repr(C)] -pub struct MsgHdr { - pub msg_name: *mut c_void, - pub msg_namelen: SocketAddrLen, - pub msg_iov: *mut iovec, - pub msg_iovlen: usize, - pub msg_control: *mut c_void, - pub msg_controllen: usize, - pub msg_flags: RecvFlags, -} - -/// `io_uring_setup(entries, params)`—Setup a context for performing -/// asynchronous I/O. -/// -/// # Safety -/// -/// If [`IoringSetupFlags::ATTACH_WQ`] is set, the `wq_fd` field of -/// `io_uring_params` must be an open file descriptor. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_setup.2.html -#[inline] -pub unsafe fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> { - backend::io_uring::syscalls::io_uring_setup(entries, params) -} - -/// `io_uring_register(fd, opcode, arg, nr_args)`—Register files or user -/// buffers for asynchronous I/O. -/// -/// To pass flags, use [`io_uring_register_with`]. -/// -/// # Safety -/// -/// io_uring operates on raw pointers and raw file descriptors. Users are -/// responsible for ensuring that memory and resources are only accessed in -/// valid ways. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_register.2.html -#[inline] -pub unsafe fn io_uring_register<Fd: AsFd>( - fd: Fd, - opcode: IoringRegisterOp, - arg: *const c_void, - nr_args: u32, -) -> io::Result<u32> { - backend::io_uring::syscalls::io_uring_register(fd.as_fd(), opcode, arg, nr_args) -} - -/// `io_uring_register_with(fd, opcode, flags, arg, nr_args)`—Register files or -/// user buffers for asynchronous I/O. -/// -/// # Safety -/// -/// io_uring operates on raw pointers and raw file descriptors. Users are -/// responsible for ensuring that memory and resources are only accessed in -/// valid ways. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_register.2.html -#[inline] -pub unsafe fn io_uring_register_with<Fd: AsFd>( - fd: Fd, - opcode: IoringRegisterOp, - flags: IoringRegisterFlags, - arg: *const c_void, - nr_args: u32, -) -> io::Result<u32> { - backend::io_uring::syscalls::io_uring_register_with(fd.as_fd(), opcode, flags, arg, nr_args) -} - -/// `io_uring_enter(fd, to_submit, min_complete, flags, 0, 0)`—Initiate -/// and/or complete asynchronous I/O. -/// -/// This version has no `arg` argument. To pass: -/// - a signal mask, use [`io_uring_enter_sigmask`]. -/// - an [`io_uring_getevents_arg`], use [`io_uring_enter_arg`] (aka -/// `io_uring_enter2`). -/// -/// # Safety -/// -/// io_uring operates on raw pointers and raw file descriptors. Users are -/// responsible for ensuring that memory and resources are only accessed in -/// valid ways. -/// -/// And, `flags` must not have [`IoringEnterFlags::EXT_ARG`] or -/// [`IoringEnterFlags::EXT_ARG_REG`] set. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html -#[doc(alias = "io_uring_enter2")] -#[inline] -pub unsafe fn io_uring_enter<Fd: AsFd>( - fd: Fd, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, -) -> io::Result<u32> { - debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG)); - debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG_REG)); - - backend::io_uring::syscalls::io_uring_enter( - fd.as_fd(), - to_submit, - min_complete, - flags, - null_mut(), - 0, - ) -} - -/// `io_uring_enter(fd, to_submit, min_complete, flags, sigmask, -/// sizeof(*sigmask))`— Initiate and/or complete asynchronous I/O, with a -/// signal mask. -/// -/// # Safety -/// -/// io_uring operates on raw pointers and raw file descriptors. Users are -/// responsible for ensuring that memory and resources are only accessed in -/// valid ways. -/// -/// And, `flags` must not have [`IoringEnterFlags::EXT_ARG`] or -/// [`IoringEnterFlags::EXT_ARG_REG`] set. -/// -/// And, the `KernelSigSet` referred to by `arg` must not contain any signal -/// numbers reserved by libc. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html -#[doc(alias = "io_uring_enter")] -#[inline] -pub unsafe fn io_uring_enter_sigmask<Fd: AsFd>( - fd: Fd, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - sigmask: Option<&KernelSigSet>, -) -> io::Result<u32> { - debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG)); - debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG_REG)); - - backend::io_uring::syscalls::io_uring_enter( - fd.as_fd(), - to_submit, - min_complete, - flags, - option_as_ptr(sigmask).cast::<c_void>(), - size_of::<KernelSigSet>(), - ) -} - -/// `io_uring_enter2(fd, to_submit, min_complete, flags, arg, sizeof(*arg))`— -/// Initiate and/or complete asynchronous I/O, with a signal mask and a -/// timeout. -/// -/// # Safety -/// -/// io_uring operates on raw pointers and raw file descriptors. Users are -/// responsible for ensuring that memory and resources are only accessed in -/// valid ways. -/// -/// And, `flags` must have [`IoringEnterFlags::EXT_ARG`] set, and must not have -/// [`IoringEnterFlags::EXT_ARG_REG`] set. -/// -/// And, the `KernelSigSet` pointed to by the `io_uring_getenvets_arg` referred -/// to by `arg` must not contain any signal numbers reserved by libc. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html -#[doc(alias = "io_uring_enter")] -#[doc(alias = "io_uring_enter2")] -#[inline] -pub unsafe fn io_uring_enter_arg<Fd: AsFd>( - fd: Fd, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - arg: Option<&io_uring_getevents_arg>, -) -> io::Result<u32> { - debug_assert!(flags.contains(IoringEnterFlags::EXT_ARG)); - debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG_REG)); - - backend::io_uring::syscalls::io_uring_enter( - fd.as_fd(), - to_submit, - min_complete, - flags, - option_as_ptr(arg).cast::<c_void>(), - size_of::<io_uring_getevents_arg>(), - ) -} - -// TODO: Uncomment this when we support `IoringRegisterOp::CQWAIT_REG`. -/* -/// `io_uring_enter2(fd, to_submit, min_complete, flags, offset, -/// sizeof(io_uring_reg_wait))`— Initiate and/or complete asynchronous I/O, -/// using a previously registered `io_uring_reg_wait`. -/// -/// `offset` is an offset into an area of wait regions previously registered -/// with [`io_uring_register`] using the [`IoringRegisterOp::CQWAIT_REG`] -/// operation. -/// -/// # Safety -/// -/// io_uring operates on raw pointers and raw file descriptors. Users are -/// responsible for ensuring that memory and resources are only accessed in -/// valid ways. -/// -/// And, `flags` must have [`IoringEnterFlags::EXT_ARG_REG`] set, and must not -/// have [`IoringEnterFlags::EXT_ARG`] set. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.man7.org/linux/man-pages/man2/io_uring_enter.2.html -#[doc(alias = "io_uring_enter")] -#[doc(alias = "io_uring_enter2")] -#[inline] -pub unsafe fn io_uring_enter_reg_wait<Fd: AsFd>( - fd: Fd, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - reg_wait: usize, -) -> io::Result<u32> { - debug_assert!(!flags.contains(IoringEnterFlags::EXT_ARG)); - debug_assert!(flags.contains(IoringEnterFlags::EXT_ARG_REG)); - - backend::io_uring::syscalls::io_uring_enter( - fd.as_fd(), - to_submit, - min_complete, - flags, - reg_wait as *mut c_void, - size_of::<io_uring_reg_wait>(), - ) -} -*/ - -bitflags::bitflags! { - /// `IORING_ENTER_*` flags for use with [`io_uring_enter`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringEnterFlags: u32 { - /// `IORING_ENTER_GETEVENTS` - const GETEVENTS = sys::IORING_ENTER_GETEVENTS; - - /// `IORING_ENTER_SQ_WAKEUP` - const SQ_WAKEUP = sys::IORING_ENTER_SQ_WAKEUP; - - /// `IORING_ENTER_SQ_WAIT` - const SQ_WAIT = sys::IORING_ENTER_SQ_WAIT; - - /// `IORING_ENTER_EXT_ARG` (since Linux 5.11) - const EXT_ARG = sys::IORING_ENTER_EXT_ARG; - - /// `IORING_ENTER_REGISTERED_RING` - const REGISTERED_RING = sys::IORING_ENTER_REGISTERED_RING; - - /// `IORING_ENTER_ABS_TIMER` (since Linux 6.12) - const ABS_TIMER = sys::IORING_ENTER_ABS_TIMER; - - /// `IORING_ENTER_EXT_ARG_REG` (since Linux 6.12) - const EXT_ARG_REG = sys::IORING_ENTER_EXT_ARG_REG; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `IORING_REGISTER_*` and `IORING_UNREGISTER_*` constants for use with -/// [`io_uring_register`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u8)] -#[non_exhaustive] -pub enum IoringRegisterOp { - /// `IORING_REGISTER_BUFFERS` - RegisterBuffers = sys::io_uring_register_op::IORING_REGISTER_BUFFERS as _, - - /// `IORING_UNREGISTER_BUFFERS` - UnregisterBuffers = sys::io_uring_register_op::IORING_UNREGISTER_BUFFERS as _, - - /// `IORING_REGISTER_FILES` - RegisterFiles = sys::io_uring_register_op::IORING_REGISTER_FILES as _, - - /// `IORING_UNREGISTER_FILES` - UnregisterFiles = sys::io_uring_register_op::IORING_UNREGISTER_FILES as _, - - /// `IORING_REGISTER_EVENTFD` - RegisterEventfd = sys::io_uring_register_op::IORING_REGISTER_EVENTFD as _, - - /// `IORING_UNREGISTER_EVENTFD` - UnregisterEventfd = sys::io_uring_register_op::IORING_UNREGISTER_EVENTFD as _, - - /// `IORING_REGISTER_FILES_UPDATE` - RegisterFilesUpdate = sys::io_uring_register_op::IORING_REGISTER_FILES_UPDATE as _, - - /// `IORING_REGISTER_EVENTFD_ASYNC` - RegisterEventfdAsync = sys::io_uring_register_op::IORING_REGISTER_EVENTFD_ASYNC as _, - - /// `IORING_REGISTER_PROBE` - RegisterProbe = sys::io_uring_register_op::IORING_REGISTER_PROBE as _, - - /// `IORING_REGISTER_PERSONALITY` - RegisterPersonality = sys::io_uring_register_op::IORING_REGISTER_PERSONALITY as _, - - /// `IORING_UNREGISTER_PERSONALITY` - UnregisterPersonality = sys::io_uring_register_op::IORING_UNREGISTER_PERSONALITY as _, - - /// `IORING_REGISTER_RESTRICTIONS` - RegisterRestrictions = sys::io_uring_register_op::IORING_REGISTER_RESTRICTIONS as _, - - /// `IORING_REGISTER_ENABLE_RINGS` - RegisterEnableRings = sys::io_uring_register_op::IORING_REGISTER_ENABLE_RINGS as _, - - /// `IORING_REGISTER_BUFFERS2` - RegisterBuffers2 = sys::io_uring_register_op::IORING_REGISTER_BUFFERS2 as _, - - /// `IORING_REGISTER_BUFFERS_UPDATE` - RegisterBuffersUpdate = sys::io_uring_register_op::IORING_REGISTER_BUFFERS_UPDATE as _, - - /// `IORING_REGISTER_FILES2` - RegisterFiles2 = sys::io_uring_register_op::IORING_REGISTER_FILES2 as _, - - /// `IORING_REGISTER_FILES_UPDATE2` - RegisterFilesUpdate2 = sys::io_uring_register_op::IORING_REGISTER_FILES_UPDATE2 as _, - - /// `IORING_REGISTER_IOWQ_AFF` - RegisterIowqAff = sys::io_uring_register_op::IORING_REGISTER_IOWQ_AFF as _, - - /// `IORING_UNREGISTER_IOWQ_AFF` - UnregisterIowqAff = sys::io_uring_register_op::IORING_UNREGISTER_IOWQ_AFF as _, - - /// `IORING_REGISTER_IOWQ_MAX_WORKERS` - RegisterIowqMaxWorkers = sys::io_uring_register_op::IORING_REGISTER_IOWQ_MAX_WORKERS as _, - - /// `IORING_REGISTER_RING_FDS` - RegisterRingFds = sys::io_uring_register_op::IORING_REGISTER_RING_FDS as _, - - /// `IORING_UNREGISTER_RING_FDS` - UnregisterRingFds = sys::io_uring_register_op::IORING_UNREGISTER_RING_FDS as _, - - /// `IORING_REGISTER_PBUF_RING` - RegisterPbufRing = sys::io_uring_register_op::IORING_REGISTER_PBUF_RING as _, - - /// `IORING_UNREGISTER_PBUF_RING` - UnregisterPbufRing = sys::io_uring_register_op::IORING_UNREGISTER_PBUF_RING as _, - - /// `IORING_REGISTER_SYNC_CANCEL` - RegisterSyncCancel = sys::io_uring_register_op::IORING_REGISTER_SYNC_CANCEL as _, - - /// `IORING_REGISTER_FILE_ALLOC_RANGE` - RegisterFileAllocRange = sys::io_uring_register_op::IORING_REGISTER_FILE_ALLOC_RANGE as _, - - /// `IORING_REGISTER_PBUF_STATUS` (since Linux 6.8) - RegisterPbufStatus = sys::io_uring_register_op::IORING_REGISTER_PBUF_STATUS as _, - - /// `IORING_REGISTER_NAPI` (since Linux 6.9) - RegisterNapi = sys::io_uring_register_op::IORING_REGISTER_NAPI as _, - - /// `IORING_UNREGISTER_NAPI` (since Linux 6.9) - UnregisterNapi = sys::io_uring_register_op::IORING_UNREGISTER_NAPI as _, - - /// `IORING_REGISTER_CLOCK` (since Linux 6.12) - RegisterClock = sys::io_uring_register_op::IORING_REGISTER_CLOCK as _, - - /// `IORING_REGISTER_CLONE_BUFFERS ` (since Linux 6.12) - RegisterCloneBuffers = sys::io_uring_register_op::IORING_REGISTER_CLONE_BUFFERS as _, - - /// `IORING_REGISTER_SEND_MSG_RING` (since Linux 6.12) - RegisterSendMsgRing = sys::io_uring_register_op::IORING_REGISTER_SEND_MSG_RING as _, - - /// `IORING_REGISTER_RESIZE_RINGS`(since Linux 6.13) - RegisterResizeRings = sys::io_uring_register_op::IORING_REGISTER_RESIZE_RINGS as _, -} - -bitflags::bitflags! { - /// `IORING_REGISTER_*` flags for use with [`io_uring_register_with`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringRegisterFlags: u32 { - /// `IORING_REGISTER_USE_REGISTERED_RING` - const USE_REGISTERED_RING = sys::io_uring_register_op::IORING_REGISTER_USE_REGISTERED_RING as u32; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `IORING_OP_*` constants for use with [`io_uring_sqe`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u8)] -#[non_exhaustive] -pub enum IoringOp { - /// `IORING_OP_NOP` - Nop = sys::io_uring_op::IORING_OP_NOP as _, - - /// `IORING_OP_ACCEPT` - Accept = sys::io_uring_op::IORING_OP_ACCEPT as _, - - /// `IORING_OP_ASYNC_CANCEL` - AsyncCancel = sys::io_uring_op::IORING_OP_ASYNC_CANCEL as _, - - /// `IORING_OP_CLOSE` - Close = sys::io_uring_op::IORING_OP_CLOSE as _, - - /// `IORING_OP_CONNECT` - Connect = sys::io_uring_op::IORING_OP_CONNECT as _, - - /// `IORING_OP_EPOLL_CTL` - EpollCtl = sys::io_uring_op::IORING_OP_EPOLL_CTL as _, - - /// `IORING_OP_FADVISE` - Fadvise = sys::io_uring_op::IORING_OP_FADVISE as _, - - /// `IORING_OP_FALLOCATE` - Fallocate = sys::io_uring_op::IORING_OP_FALLOCATE as _, - - /// `IORING_OP_FILES_UPDATE` - FilesUpdate = sys::io_uring_op::IORING_OP_FILES_UPDATE as _, - - /// `IORING_OP_FSYNC` - Fsync = sys::io_uring_op::IORING_OP_FSYNC as _, - - /// `IORING_OP_LINKAT` - Linkat = sys::io_uring_op::IORING_OP_LINKAT as _, - - /// `IORING_OP_LINK_TIMEOUT` - LinkTimeout = sys::io_uring_op::IORING_OP_LINK_TIMEOUT as _, - - /// `IORING_OP_MADVISE` - Madvise = sys::io_uring_op::IORING_OP_MADVISE as _, - - /// `IORING_OP_MKDIRAT` - Mkdirat = sys::io_uring_op::IORING_OP_MKDIRAT as _, - - /// `IORING_OP_OPENAT` - Openat = sys::io_uring_op::IORING_OP_OPENAT as _, - - /// `IORING_OP_OPENAT2` - Openat2 = sys::io_uring_op::IORING_OP_OPENAT2 as _, - - /// `IORING_OP_POLL_ADD` - PollAdd = sys::io_uring_op::IORING_OP_POLL_ADD as _, - - /// `IORING_OP_POLL_REMOVE` - PollRemove = sys::io_uring_op::IORING_OP_POLL_REMOVE as _, - - /// `IORING_OP_PROVIDE_BUFFERS` - ProvideBuffers = sys::io_uring_op::IORING_OP_PROVIDE_BUFFERS as _, - - /// `IORING_OP_READ` - Read = sys::io_uring_op::IORING_OP_READ as _, - - /// `IORING_OP_READV` - Readv = sys::io_uring_op::IORING_OP_READV as _, - - /// `IORING_OP_READ_FIXED` - ReadFixed = sys::io_uring_op::IORING_OP_READ_FIXED as _, - - /// `IORING_OP_RECV` - Recv = sys::io_uring_op::IORING_OP_RECV as _, - - /// `IORING_OP_RECVMSG` - Recvmsg = sys::io_uring_op::IORING_OP_RECVMSG as _, - - /// `IORING_OP_REMOVE_BUFFERS` - RemoveBuffers = sys::io_uring_op::IORING_OP_REMOVE_BUFFERS as _, - - /// `IORING_OP_RENAMEAT` - Renameat = sys::io_uring_op::IORING_OP_RENAMEAT as _, - - /// `IORING_OP_SEND` - Send = sys::io_uring_op::IORING_OP_SEND as _, - - /// `IORING_OP_SENDMSG` - Sendmsg = sys::io_uring_op::IORING_OP_SENDMSG as _, - - /// `IORING_OP_SHUTDOWN` - Shutdown = sys::io_uring_op::IORING_OP_SHUTDOWN as _, - - /// `IORING_OP_SPLICE` - Splice = sys::io_uring_op::IORING_OP_SPLICE as _, - - /// `IORING_OP_STATX` - Statx = sys::io_uring_op::IORING_OP_STATX as _, - - /// `IORING_OP_SYMLINKAT` - Symlinkat = sys::io_uring_op::IORING_OP_SYMLINKAT as _, - - /// `IORING_OP_SYNC_FILE_RANGE` - SyncFileRange = sys::io_uring_op::IORING_OP_SYNC_FILE_RANGE as _, - - /// `IORING_OP_TEE` - Tee = sys::io_uring_op::IORING_OP_TEE as _, - - /// `IORING_OP_TIMEOUT` - Timeout = sys::io_uring_op::IORING_OP_TIMEOUT as _, - - /// `IORING_OP_TIMEOUT_REMOVE` - TimeoutRemove = sys::io_uring_op::IORING_OP_TIMEOUT_REMOVE as _, - - /// `IORING_OP_UNLINKAT` - Unlinkat = sys::io_uring_op::IORING_OP_UNLINKAT as _, - - /// `IORING_OP_WRITE` - Write = sys::io_uring_op::IORING_OP_WRITE as _, - - /// `IORING_OP_WRITEV` - Writev = sys::io_uring_op::IORING_OP_WRITEV as _, - - /// `IORING_OP_WRITE_FIXED` - WriteFixed = sys::io_uring_op::IORING_OP_WRITE_FIXED as _, - - /// `IORING_OP_MSG_RING` - MsgRing = sys::io_uring_op::IORING_OP_MSG_RING as _, - - /// `IORING_OP_FSETXATTR` - Fsetxattr = sys::io_uring_op::IORING_OP_FSETXATTR as _, - - /// `IORING_OP_SETXATTR` - Setxattr = sys::io_uring_op::IORING_OP_SETXATTR as _, - - /// `IORING_OP_FGETXATTR` - Fgetxattr = sys::io_uring_op::IORING_OP_FGETXATTR as _, - - /// `IORING_OP_GETXATTR` - Getxattr = sys::io_uring_op::IORING_OP_GETXATTR as _, - - /// `IORING_OP_SOCKET` - Socket = sys::io_uring_op::IORING_OP_SOCKET as _, - - /// `IORING_OP_URING_CMD` - UringCmd = sys::io_uring_op::IORING_OP_URING_CMD as _, - - /// `IORING_OP_SEND_ZC` - SendZc = sys::io_uring_op::IORING_OP_SEND_ZC as _, - - /// `IORING_OP_SENDMSG_ZC` - SendmsgZc = sys::io_uring_op::IORING_OP_SENDMSG_ZC as _, - - /// `IORING_OP_READ_MULTISHOT` (since Linux 6.7) - ReadMultishot = sys::io_uring_op::IORING_OP_READ_MULTISHOT as _, - - /// `IORING_OP_WAITID` (since Linux 6.5) - Waitid = sys::io_uring_op::IORING_OP_WAITID as _, - - /// `IORING_OP_FUTEX_WAIT` (since Linux 6.7) - FutexWait = sys::io_uring_op::IORING_OP_FUTEX_WAIT as _, - - /// `IORING_OP_FUTEX_WAKE` (since Linux 6.7) - FutexWake = sys::io_uring_op::IORING_OP_FUTEX_WAKE as _, - - /// `IORING_OP_FUTEX_WAITV` (since Linux 6.7) - FutexWaitv = sys::io_uring_op::IORING_OP_FUTEX_WAITV as _, - - /// `IORING_OP_FIXED_FD_INSTALL` (since Linux 6.8) - FixedFdInstall = sys::io_uring_op::IORING_OP_FIXED_FD_INSTALL as _, - - /// `IORING_OP_FTRUNCATE` (since Linux 6.9) - Ftruncate = sys::io_uring_op::IORING_OP_FTRUNCATE as _, - - /// `IORING_OP_BIND` (since Linux 6.11) - Bind = sys::io_uring_op::IORING_OP_BIND as _, - - /// `IORING_OP_LISTEN` (since Linux 6.11) - Listen = sys::io_uring_op::IORING_OP_LISTEN as _, -} - -impl Default for IoringOp { - #[inline] - fn default() -> Self { - Self::Nop - } -} - -/// `IORING_RESTRICTION_*` constants for use with [`io_uring_restriction`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u16)] -#[non_exhaustive] -pub enum IoringRestrictionOp { - /// `IORING_RESTRICTION_REGISTER_OP` - RegisterOp = sys::io_uring_register_restriction_op::IORING_RESTRICTION_REGISTER_OP as _, - - /// `IORING_RESTRICTION_SQE_FLAGS_ALLOWED` - SqeFlagsAllowed = - sys::io_uring_register_restriction_op::IORING_RESTRICTION_SQE_FLAGS_ALLOWED as _, - - /// `IORING_RESTRICTION_SQE_FLAGS_REQUIRED` - SqeFlagsRequired = - sys::io_uring_register_restriction_op::IORING_RESTRICTION_SQE_FLAGS_REQUIRED as _, - - /// `IORING_RESTRICTION_SQE_OP` - SqeOp = sys::io_uring_register_restriction_op::IORING_RESTRICTION_SQE_OP as _, -} - -impl Default for IoringRestrictionOp { - #[inline] - fn default() -> Self { - Self::RegisterOp - } -} - -/// `IORING_MSG_*` constants which represent commands for use with -/// [`IoringOp::MsgRing`], (`seq.addr`) -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u64)] -#[non_exhaustive] -pub enum IoringMsgringCmds { - /// `IORING_MSG_DATA` - Data = sys::io_uring_msg_ring_flags::IORING_MSG_DATA as _, - - /// `IORING_MSG_SEND_FD` - SendFd = sys::io_uring_msg_ring_flags::IORING_MSG_SEND_FD as _, -} - -bitflags::bitflags! { - /// `IORING_SETUP_*` flags for use with [`io_uring_params`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringSetupFlags: u32 { - /// `IORING_SETUP_ATTACH_WQ` - const ATTACH_WQ = sys::IORING_SETUP_ATTACH_WQ; - - /// `IORING_SETUP_CLAMP` - const CLAMP = sys::IORING_SETUP_CLAMP; - - /// `IORING_SETUP_CQSIZE` - const CQSIZE = sys::IORING_SETUP_CQSIZE; - - /// `IORING_SETUP_IOPOLL` - const IOPOLL = sys::IORING_SETUP_IOPOLL; - - /// `IORING_SETUP_R_DISABLED` - const R_DISABLED = sys::IORING_SETUP_R_DISABLED; - - /// `IORING_SETUP_SQPOLL` - const SQPOLL = sys::IORING_SETUP_SQPOLL; - - /// `IORING_SETUP_SQ_AFF` - const SQ_AFF = sys::IORING_SETUP_SQ_AFF; - - /// `IORING_SETUP_SQE128` - const SQE128 = sys::IORING_SETUP_SQE128; - - /// `IORING_SETUP_CQE32` - const CQE32 = sys::IORING_SETUP_CQE32; - - /// `IORING_SETUP_SUBMIT_ALL` - const SUBMIT_ALL = sys::IORING_SETUP_SUBMIT_ALL; - - /// `IORING_SETUP_COOP_TRASKRUN` - const COOP_TASKRUN = sys::IORING_SETUP_COOP_TASKRUN; - - /// `IORING_SETUP_TASKRUN_FLAG` - const TASKRUN_FLAG = sys::IORING_SETUP_TASKRUN_FLAG; - - /// `IORING_SETUP_SINGLE_ISSUER` - const SINGLE_ISSUER = sys::IORING_SETUP_SINGLE_ISSUER; - - /// `IORING_SETUP_DEFER_TASKRUN` - const DEFER_TASKRUN = sys::IORING_SETUP_DEFER_TASKRUN; - - /// `IORING_SETUP_NO_MMAP` - const NO_MMAP = sys::IORING_SETUP_NO_MMAP; - - /// `IORING_SETUP_REGISTERED_FD_ONLY` - const REGISTERED_FD_ONLY = sys::IORING_SETUP_REGISTERED_FD_ONLY; - - /// `IORING_SETUP_NO_SQARRAY` - const NO_SQARRAY = sys::IORING_SETUP_NO_SQARRAY; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IOSQE_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringSqeFlags: u8 { - /// `1 << IOSQE_ASYNC_BIT` - const ASYNC = 1 << sys::io_uring_sqe_flags_bit::IOSQE_ASYNC_BIT as u8; - - /// `1 << IOSQE_BUFFER_SELECT_BIT` - const BUFFER_SELECT = 1 << sys::io_uring_sqe_flags_bit::IOSQE_BUFFER_SELECT_BIT as u8; - - /// `1 << IOSQE_FIXED_FILE_BIT` - const FIXED_FILE = 1 << sys::io_uring_sqe_flags_bit::IOSQE_FIXED_FILE_BIT as u8; - - /// 1 << `IOSQE_IO_DRAIN_BIT` - const IO_DRAIN = 1 << sys::io_uring_sqe_flags_bit::IOSQE_IO_DRAIN_BIT as u8; - - /// `1 << IOSQE_IO_HARDLINK_BIT` - const IO_HARDLINK = 1 << sys::io_uring_sqe_flags_bit::IOSQE_IO_HARDLINK_BIT as u8; - - /// `1 << IOSQE_IO_LINK_BIT` - const IO_LINK = 1 << sys::io_uring_sqe_flags_bit::IOSQE_IO_LINK_BIT as u8; - - /// `1 << IOSQE_CQE_SKIP_SUCCESS_BIT` - const CQE_SKIP_SUCCESS = 1 << sys::io_uring_sqe_flags_bit::IOSQE_CQE_SKIP_SUCCESS_BIT as u8; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_CQE_F_*` flags for use with [`io_uring_cqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringCqeFlags: u32 { - /// `IORING_CQE_F_BUFFER` - const BUFFER = bitcast!(sys::IORING_CQE_F_BUFFER); - - /// `IORING_CQE_F_MORE` - const MORE = bitcast!(sys::IORING_CQE_F_MORE); - - /// `IORING_CQE_F_SOCK_NONEMPTY` - const SOCK_NONEMPTY = bitcast!(sys::IORING_CQE_F_SOCK_NONEMPTY); - - /// `IORING_CQE_F_NOTIF` - const NOTIF = bitcast!(sys::IORING_CQE_F_NOTIF); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_FSYNC_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringFsyncFlags: u32 { - /// `IORING_FSYNC_DATASYNC` - const DATASYNC = sys::IORING_FSYNC_DATASYNC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_TIMEOUT_*` and `IORING_LINK_TIMEOUT_UPDATE` flags for use with - /// [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringTimeoutFlags: u32 { - /// `IORING_TIMEOUT_ABS` - const ABS = sys::IORING_TIMEOUT_ABS; - - /// `IORING_TIMEOUT_UPDATE` - const UPDATE = sys::IORING_TIMEOUT_UPDATE; - - /// `IORING_TIMEOUT_BOOTTIME` - const BOOTTIME = sys::IORING_TIMEOUT_BOOTTIME; - - /// `IORING_TIMEOUT_ETIME_SUCCESS` - const ETIME_SUCCESS = sys::IORING_TIMEOUT_ETIME_SUCCESS; - - /// `IORING_TIMEOUT_REALTIME` - const REALTIME = sys::IORING_TIMEOUT_REALTIME; - - /// `IORING_TIMEOUT_CLOCK_MASK` - const CLOCK_MASK = sys::IORING_TIMEOUT_CLOCK_MASK; - - /// `IORING_TIMEOUT_UPDATE_MASK` - const UPDATE_MASK = sys::IORING_TIMEOUT_UPDATE_MASK; - - /// `IORING_LINK_TIMEOUT_UPDATE` - const LINK_TIMEOUT_UPDATE = sys::IORING_LINK_TIMEOUT_UPDATE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `SPLICE_F_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpliceFlags: u32 { - /// `SPLICE_F_FD_IN_FIXED` - const FD_IN_FIXED = sys::SPLICE_F_FD_IN_FIXED; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_MSG_RING_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringMsgringFlags: u32 { - /// `IORING_MSG_RING_CQE_SKIP` - const CQE_SKIP = sys::IORING_MSG_RING_CQE_SKIP; - - /// `IORING_MSG_RING_FLAGS_PASS` - const FLAGS_PASS = sys::IORING_MSG_RING_FLAGS_PASS; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_URING_CMD_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringUringCmdFlags: u32 { - /// `IORING_URING_CMD_FIXED` - const FIXED = sys::IORING_URING_CMD_FIXED; - - /// `IORING_URING_CMD_MASK` - const MASK = sys::IORING_URING_CMD_MASK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_ASYNC_CANCEL_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringAsyncCancelFlags: u32 { - /// `IORING_ASYNC_CANCEL_ALL` - const ALL = sys::IORING_ASYNC_CANCEL_ALL; - - /// `IORING_ASYNC_CANCEL_FD` - const FD = sys::IORING_ASYNC_CANCEL_FD; - - /// `IORING_ASYNC_CANCEL_FD` - const ANY = sys::IORING_ASYNC_CANCEL_ANY; - - /// `IORING_ASYNC_CANCEL_FD` - const FD_FIXED = sys::IORING_ASYNC_CANCEL_FD_FIXED; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_FIXED_FD_*` flags for use with [`io_uring_sqe`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringFixedFdFlags: u32 { - /// `IORING_FIXED_FD_NO_CLOEXEC` - const NO_CLOEXEC = sys::IORING_FIXED_FD_NO_CLOEXEC; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_FEAT_*` flags for use with [`io_uring_params`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringFeatureFlags: u32 { - /// `IORING_FEAT_CQE_SKIP` - const CQE_SKIP = sys::IORING_FEAT_CQE_SKIP; - - /// `IORING_FEAT_CUR_PERSONALITY` - const CUR_PERSONALITY = sys::IORING_FEAT_CUR_PERSONALITY; - - /// `IORING_FEAT_EXT_ARG` - const EXT_ARG = sys::IORING_FEAT_EXT_ARG; - - /// `IORING_FEAT_FAST_POLL` - const FAST_POLL = sys::IORING_FEAT_FAST_POLL; - - /// `IORING_FEAT_NATIVE_WORKERS` - const NATIVE_WORKERS = sys::IORING_FEAT_NATIVE_WORKERS; - - /// `IORING_FEAT_NODROP` - const NODROP = sys::IORING_FEAT_NODROP; - - /// `IORING_FEAT_POLL_32BITS` - const POLL_32BITS = sys::IORING_FEAT_POLL_32BITS; - - /// `IORING_FEAT_RSRC_TAGS` - const RSRC_TAGS = sys::IORING_FEAT_RSRC_TAGS; - - /// `IORING_FEAT_RW_CUR_POS` - const RW_CUR_POS = sys::IORING_FEAT_RW_CUR_POS; - - /// `IORING_FEAT_SINGLE_MMAP` - const SINGLE_MMAP = sys::IORING_FEAT_SINGLE_MMAP; - - /// `IORING_FEAT_SQPOLL_NONFIXED` - const SQPOLL_NONFIXED = sys::IORING_FEAT_SQPOLL_NONFIXED; - - /// `IORING_FEAT_SUBMIT_STABLE` - const SUBMIT_STABLE = sys::IORING_FEAT_SUBMIT_STABLE; - - /// `IORING_FEAT_LINKED_FILE` - const LINKED_FILE = sys::IORING_FEAT_LINKED_FILE; - - /// `IORING_FEAT_REG_REG_RING` - const REG_REG_RING = sys::IORING_FEAT_REG_REG_RING; - - /// `IORING_FEAT_RECVSEND_BUNDLE` - const RECVSEND_BUNDLE = sys::IORING_FEAT_RECVSEND_BUNDLE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IO_URING_OP_*` flags for use with [`io_uring_probe_op`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringOpFlags: u16 { - /// `IO_URING_OP_SUPPORTED` - const SUPPORTED = sys::IO_URING_OP_SUPPORTED as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_RSRC_*` flags for use with [`io_uring_rsrc_register`]. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringRsrcFlags: u32 { - /// `IORING_RSRC_REGISTER_SPARSE` - const REGISTER_SPARSE = sys::IORING_RSRC_REGISTER_SPARSE as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_SQ_*` flags. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringSqFlags: u32 { - /// `IORING_SQ_NEED_WAKEUP` - const NEED_WAKEUP = sys::IORING_SQ_NEED_WAKEUP; - - /// `IORING_SQ_CQ_OVERFLOW` - const CQ_OVERFLOW = sys::IORING_SQ_CQ_OVERFLOW; - - /// `IORING_SQ_TASKRUN` - const TASKRUN = sys::IORING_SQ_TASKRUN; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_CQ_*` flags. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringCqFlags: u32 { - /// `IORING_CQ_EVENTFD_DISABLED` - const EVENTFD_DISABLED = sys::IORING_CQ_EVENTFD_DISABLED; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// `IORING_POLL_*` flags. - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringPollFlags: u32 { - /// `IORING_POLL_ADD_MULTI` - const ADD_MULTI = sys::IORING_POLL_ADD_MULTI; - - /// `IORING_POLL_UPDATE_EVENTS` - const UPDATE_EVENTS = sys::IORING_POLL_UPDATE_EVENTS; - - /// `IORING_POLL_UPDATE_USER_DATA` - const UPDATE_USER_DATA = sys::IORING_POLL_UPDATE_USER_DATA; - - /// `IORING_POLL_ADD_LEVEL` - const ADD_LEVEL = sys::IORING_POLL_ADD_LEVEL; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// send/sendmsg flags (`sqe.ioprio`) - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringSendFlags: u16 { - /// `IORING_RECVSEND_POLL_FIRST`. - /// - /// See also [`IoringRecvFlags::POLL_FIRST`]. - const POLL_FIRST = sys::IORING_RECVSEND_POLL_FIRST as _; - - /// `IORING_RECVSEND_FIXED_BUF` - /// - /// See also [`IoringRecvFlags::FIXED_BUF`]. - const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _; - - /// `IORING_SEND_ZC_REPORT_USAGE` (since Linux 6.2) - const ZC_REPORT_USAGE = sys::IORING_SEND_ZC_REPORT_USAGE as _; - - /// `IORING_RECVSEND_BUNDLE` - /// - /// See also [`IoringRecvFlags::BUNDLE`]. - const BUNDLE = sys::IORING_RECVSEND_BUNDLE as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// recv/recvmsg flags (`sqe.ioprio`) - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringRecvFlags: u16 { - /// `IORING_RECVSEND_POLL_FIRST` - /// - /// See also [`IoringSendFlags::POLL_FIRST`]. - const POLL_FIRST = sys::IORING_RECVSEND_POLL_FIRST as _; - - /// `IORING_RECV_MULTISHOT` - const MULTISHOT = sys::IORING_RECV_MULTISHOT as _; - - /// `IORING_RECVSEND_FIXED_BUF` - /// - /// See also [`IoringSendFlags::FIXED_BUF`]. - const FIXED_BUF = sys::IORING_RECVSEND_FIXED_BUF as _; - - /// `IORING_RECVSEND_BUNDLE` - /// - /// See also [`IoringSendFlags::BUNDLE`]. - const BUNDLE = sys::IORING_RECVSEND_BUNDLE as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// accept flags (`sqe.ioprio`) - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct IoringAcceptFlags: u16 { - /// `IORING_ACCEPT_MULTISHOT` - const MULTISHOT = sys::IORING_ACCEPT_MULTISHOT as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags::bitflags! { - /// recvmsg out flags - #[repr(transparent)] - #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct RecvmsgOutFlags: u32 { - /// `MSG_EOR` - const EOR = net::MSG_EOR; - - /// `MSG_TRUNC` - const TRUNC = net::MSG_TRUNC; - - /// `MSG_CTRUNC` - const CTRUNC = net::MSG_CTRUNC; - - /// `MSG_OOB` - const OOB = net::MSG_OOB; - - /// `MSG_ERRQUEUE` - const ERRQUEUE = net::MSG_ERRQUEUE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[allow(missing_docs)] -pub const IORING_CQE_BUFFER_SHIFT: u32 = sys::IORING_CQE_BUFFER_SHIFT as _; -#[allow(missing_docs)] -pub const IORING_FILE_INDEX_ALLOC: i32 = sys::IORING_FILE_INDEX_ALLOC as _; - -// Re-export these as `u64`, which is the `offset` type in `rustix::io::mmap`. -#[allow(missing_docs)] -pub const IORING_OFF_SQ_RING: u64 = sys::IORING_OFF_SQ_RING as _; -#[allow(missing_docs)] -pub const IORING_OFF_CQ_RING: u64 = sys::IORING_OFF_CQ_RING as _; -#[allow(missing_docs)] -pub const IORING_OFF_SQES: u64 = sys::IORING_OFF_SQES as _; - -/// `IORING_REGISTER_FILES_SKIP` -// SAFETY: `IORING_REGISTER_FILES_SKIP` is a reserved value that is never -// dynamically allocated, so it'll remain valid for the duration of -// `'static`. -pub const IORING_REGISTER_FILES_SKIP: BorrowedFd<'static> = - unsafe { BorrowedFd::<'static>::borrow_raw(sys::IORING_REGISTER_FILES_SKIP as RawFd) }; - -/// `IORING_NOTIF_USAGE_ZC_COPIED` (since Linux 6.2) -pub const IORING_NOTIF_USAGE_ZC_COPIED: i32 = sys::IORING_NOTIF_USAGE_ZC_COPIED as _; - -/// A pointer in the io_uring API. -/// -/// `io_uring`'s native API represents pointers as `u64` values. In order to -/// preserve strict-provenance, use a `*mut c_void`. On platforms where -/// pointers are narrower than 64 bits, this requires additional padding. -#[repr(C)] -#[cfg_attr(any(target_arch = "arm", target_arch = "powerpc"), repr(align(8)))] -#[derive(Copy, Clone)] -#[non_exhaustive] -pub struct io_uring_ptr { - #[cfg(all(target_pointer_width = "32", target_endian = "big"))] - #[doc(hidden)] - pub __pad32: u32, - #[cfg(all(target_pointer_width = "16", target_endian = "big"))] - #[doc(hidden)] - pub __pad16: u16, - - /// The pointer value. - pub ptr: *mut c_void, - - #[cfg(all(target_pointer_width = "16", target_endian = "little"))] - #[doc(hidden)] - pub __pad16: u16, - #[cfg(all(target_pointer_width = "32", target_endian = "little"))] - #[doc(hidden)] - pub __pad32: u32, -} - -impl io_uring_ptr { - /// Construct a null `io_uring_ptr`. - #[inline] - pub const fn null() -> Self { - Self::new(null_mut()) - } - - /// Construct a new `io_uring_ptr`. - #[inline] - pub const fn new(ptr: *mut c_void) -> Self { - Self { - ptr, - - #[cfg(target_pointer_width = "16")] - __pad16: 0, - #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] - __pad32: 0, - } - } -} - -impl From<*mut c_void> for io_uring_ptr { - #[inline] - fn from(ptr: *mut c_void) -> Self { - Self::new(ptr) - } -} - -impl PartialEq for io_uring_ptr { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.ptr.eq(&other.ptr) - } -} - -impl Eq for io_uring_ptr {} - -#[allow(clippy::non_canonical_partial_ord_impl)] -impl PartialOrd for io_uring_ptr { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - self.ptr.partial_cmp(&other.ptr) - } -} - -impl Ord for io_uring_ptr { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - self.ptr.cmp(&other.ptr) - } -} - -impl Hash for io_uring_ptr { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - self.ptr.hash(state) - } -} - -impl Default for io_uring_ptr { - #[inline] - fn default() -> Self { - Self::null() - } -} - -impl core::fmt::Pointer for io_uring_ptr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.ptr.fmt(f) - } -} - -impl core::fmt::Debug for io_uring_ptr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.ptr.fmt(f) - } -} - -/// User data in the io_uring API. -/// -/// `io_uring`'s native API represents `user_data` fields as `u64` values. In -/// order to preserve strict-provenance, use a union which allows users to -/// optionally store pointers. -#[repr(C)] -#[derive(Copy, Clone)] -pub union io_uring_user_data { - /// An arbitrary `u64`. - pub u64_: u64, - - /// A pointer. - pub ptr: io_uring_ptr, -} - -impl io_uring_user_data { - /// Create a zero-initialized `Self`. - pub const fn zeroed() -> Self { - // Initialize the `u64_` field, which is the size of the full union. - // This can use `core::mem::zeroed` in Rust 1.75. - Self { u64_: 0 } - } - - /// Return the `u64` value. - #[inline] - pub const fn u64_(self) -> u64 { - // SAFETY: All the fields have the same underlying representation. - unsafe { self.u64_ } - } - - /// Create a `Self` from a `u64` value. - #[inline] - pub const fn from_u64(u64_: u64) -> Self { - Self { u64_ } - } - - /// Return the `ptr` pointer value. - #[inline] - pub const fn ptr(self) -> *mut c_void { - // SAFETY: All the fields have the same underlying representation. - unsafe { self.ptr }.ptr - } - - /// Create a `Self` from a pointer value. - #[inline] - pub const fn from_ptr(ptr: *mut c_void) -> Self { - Self { - ptr: io_uring_ptr::new(ptr), - } - } -} - -impl From<u64> for io_uring_user_data { - #[inline] - fn from(u64_: u64) -> Self { - Self::from_u64(u64_) - } -} - -impl From<*mut c_void> for io_uring_user_data { - #[inline] - fn from(ptr: *mut c_void) -> Self { - Self::from_ptr(ptr) - } -} - -impl PartialEq for io_uring_user_data { - #[inline] - fn eq(&self, other: &Self) -> bool { - // SAFETY: `io_uring_ptr` and `u64` have the same layout. - unsafe { self.u64_.eq(&other.u64_) } - } -} - -impl Eq for io_uring_user_data {} - -#[allow(clippy::non_canonical_partial_ord_impl)] -impl PartialOrd for io_uring_user_data { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - // SAFETY: `io_uring_ptr` and `u64` have the same layout. - unsafe { self.u64_.partial_cmp(&other.u64_) } - } -} - -impl Ord for io_uring_user_data { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - // SAFETY: `io_uring_ptr` and `u64` have the same layout. - unsafe { self.u64_.cmp(&other.u64_) } - } -} - -impl Hash for io_uring_user_data { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - // SAFETY: `io_uring_ptr` and `u64` have the same layout. - unsafe { self.u64_.hash(state) } - } -} - -impl Default for io_uring_user_data { - #[inline] - fn default() -> Self { - Self::zeroed() - } -} - -impl core::fmt::Debug for io_uring_user_data { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - // SAFETY: Just format as a `u64`, since formatting doesn't preserve - // provenance, and we don't have a discriminant. - unsafe { self.u64_.fmt(f) } - } -} - -/// An io_uring Submission Queue Entry. -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone, Default)] -pub struct io_uring_sqe { - pub opcode: IoringOp, - pub flags: IoringSqeFlags, - pub ioprio: ioprio_union, - pub fd: RawFd, - pub off_or_addr2: off_or_addr2_union, - pub addr_or_splice_off_in: addr_or_splice_off_in_union, - pub len: len_union, - pub op_flags: op_flags_union, - pub user_data: io_uring_user_data, - pub buf: buf_union, - pub personality: u16, - pub splice_fd_in_or_file_index_or_addr_len: splice_fd_in_or_file_index_or_addr_len_union, - pub addr3_or_cmd: addr3_or_cmd_union, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union ioprio_union { - pub recv_flags: IoringRecvFlags, - pub send_flags: IoringSendFlags, - pub accept_flags: IoringAcceptFlags, - pub ioprio: u16, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union len_union { - pub poll_flags: IoringPollFlags, - pub len: u32, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union addr3_or_cmd_union { - pub addr3: addr3_struct, - pub cmd: [u8; 0], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone, Default)] -#[non_exhaustive] -pub struct addr3_struct { - pub addr3: u64, - #[doc(hidden)] - pub __pad2: [u64; 1], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union off_or_addr2_union { - pub off: u64, - pub addr2: io_uring_ptr, - pub cmd_op: cmd_op_struct, - pub user_data: io_uring_user_data, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -#[non_exhaustive] -pub struct cmd_op_struct { - pub cmd_op: u32, - #[doc(hidden)] - pub __pad1: u32, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union addr_or_splice_off_in_union { - pub addr: io_uring_ptr, - pub splice_off_in: u64, - pub msgring_cmd: IoringMsgringCmds, - pub user_data: io_uring_user_data, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union op_flags_union { - pub rw_flags: crate::io::ReadWriteFlags, - pub fsync_flags: IoringFsyncFlags, - pub poll_events: u16, - pub poll32_events: u32, - pub sync_range_flags: u32, - /// `msg_flags` is split into `send_flags` and `recv_flags`. - #[doc(alias = "msg_flags")] - pub send_flags: SendFlags, - /// `msg_flags` is split into `send_flags` and `recv_flags`. - #[doc(alias = "msg_flags")] - pub recv_flags: RecvFlags, - pub timeout_flags: IoringTimeoutFlags, - pub accept_flags: SocketFlags, - pub cancel_flags: IoringAsyncCancelFlags, - pub open_flags: OFlags, - pub statx_flags: AtFlags, - pub fadvise_advice: Advice, - pub splice_flags: SpliceFlags, - pub rename_flags: RenameFlags, - pub unlink_flags: AtFlags, - pub hardlink_flags: AtFlags, - pub xattr_flags: XattrFlags, - pub msg_ring_flags: IoringMsgringFlags, - pub uring_cmd_flags: IoringUringCmdFlags, - pub futex_flags: FutexWaitvFlags, - pub install_fd_flags: IoringFixedFdFlags, -} - -#[allow(missing_docs)] -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub union buf_union { - pub buf_index: u16, - pub buf_group: u16, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union splice_fd_in_or_file_index_or_addr_len_union { - pub splice_fd_in: i32, - pub file_index: u32, - pub addr_len: addr_len_struct, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -#[non_exhaustive] -pub struct addr_len_struct { - pub addr_len: u16, - #[doc(hidden)] - pub __pad3: [u16; 1], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -#[non_exhaustive] -pub struct io_uring_sync_cancel_reg { - pub addr: io_uring_user_data, - pub fd: i32, - pub flags: IoringAsyncCancelFlags, - pub timeout: Timespec, - pub opcode: u8, - #[doc(hidden)] - pub pad: [u8; 7], - #[doc(hidden)] - pub pad2: [u64; 3], -} - -impl Default for io_uring_sync_cancel_reg { - #[inline] - fn default() -> Self { - Self { - addr: Default::default(), - fd: Default::default(), - flags: Default::default(), - timeout: Timespec { - tv_sec: 0, - tv_nsec: 0, - }, - opcode: Default::default(), - pad: Default::default(), - pad2: Default::default(), - } - } -} - -/// An io_uring Completion Queue Entry. -/// -/// This does not derive `Copy` or `Clone` because the `big_cqe` field is not -/// automatically copyable. -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -pub struct io_uring_cqe { - pub user_data: io_uring_user_data, - pub res: i32, - pub flags: IoringCqeFlags, - pub big_cqe: IncompleteArrayField<u64>, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_restriction { - pub opcode: IoringRestrictionOp, - pub register_or_sqe_op_or_sqe_flags: register_or_sqe_op_or_sqe_flags_union, - #[doc(hidden)] - pub resv: u8, - #[doc(hidden)] - pub resv2: [u32; 3], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Copy, Clone)] -pub union register_or_sqe_op_or_sqe_flags_union { - pub register_op: IoringRegisterOp, - pub sqe_op: IoringOp, - pub sqe_flags: IoringSqeFlags, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_params { - pub sq_entries: u32, - pub cq_entries: u32, - pub flags: IoringSetupFlags, - pub sq_thread_cpu: u32, - pub sq_thread_idle: u32, - pub features: IoringFeatureFlags, - pub wq_fd: RawFd, - #[doc(hidden)] - pub resv: [u32; 3], - pub sq_off: io_sqring_offsets, - pub cq_off: io_cqring_offsets, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_sqring_offsets { - pub head: u32, - pub tail: u32, - pub ring_mask: u32, - pub ring_entries: u32, - pub flags: u32, - pub dropped: u32, - pub array: u32, - #[doc(hidden)] - pub resv1: u32, - pub user_addr: io_uring_ptr, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_cqring_offsets { - pub head: u32, - pub tail: u32, - pub ring_mask: u32, - pub ring_entries: u32, - pub overflow: u32, - pub cqes: u32, - pub flags: u32, - #[doc(hidden)] - pub resv1: u32, - pub user_addr: io_uring_ptr, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -#[non_exhaustive] -pub struct io_uring_probe { - pub last_op: IoringOp, - pub ops_len: u8, - #[doc(hidden)] - pub resv: u16, - #[doc(hidden)] - pub resv2: [u32; 3], - pub ops: IncompleteArrayField<io_uring_probe_op>, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_probe_op { - pub op: IoringOp, - #[doc(hidden)] - pub resv: u8, - pub flags: IoringOpFlags, - #[doc(hidden)] - pub resv2: u32, -} - -#[allow(missing_docs)] -#[repr(C, align(8))] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_files_update { - pub offset: u32, - #[doc(hidden)] - pub resv: u32, - pub fds: io_uring_ptr, -} - -#[allow(missing_docs)] -#[repr(C, align(8))] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_rsrc_register { - pub nr: u32, - pub flags: IoringRsrcFlags, - #[doc(hidden)] - pub resv2: u64, - pub data: io_uring_ptr, - pub tags: io_uring_ptr, -} - -#[allow(missing_docs)] -#[repr(C, align(8))] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_rsrc_update { - pub offset: u32, - #[doc(hidden)] - pub resv: u32, - pub data: io_uring_ptr, -} - -#[allow(missing_docs)] -#[repr(C, align(8))] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_rsrc_update2 { - pub offset: u32, - #[doc(hidden)] - pub resv: u32, - pub data: io_uring_ptr, - pub tags: io_uring_ptr, - pub nr: u32, - #[doc(hidden)] - pub resv2: u32, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -pub struct io_uring_getevents_arg { - pub sigmask: io_uring_ptr, - pub sigmask_sz: u32, - pub min_wait_usec: u32, - pub ts: io_uring_ptr, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct io_uring_recvmsg_out { - pub namelen: SocketAddrLen, - pub controllen: u32, - pub payloadlen: u32, - pub flags: RecvmsgOutFlags, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct iovec { - pub iov_base: *mut c_void, - pub iov_len: usize, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct open_how { - /// An [`OFlags`] value represented as a `u64`. - pub flags: u64, - - /// A [`Mode`] value represented as a `u64`. - pub mode: u64, - - pub resolve: ResolveFlags, -} - -impl open_how { - /// Create a zero-initialized `Self`. - pub const fn zeroed() -> Self { - Self { - flags: 0, - mode: 0, - resolve: ResolveFlags::empty(), - } - } -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_buf_reg { - pub ring_addr: io_uring_ptr, - pub ring_entries: u32, - pub bgid: u16, - pub flags: u16, - #[doc(hidden)] - pub resv: [u64; 3_usize], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct io_uring_buf { - pub addr: io_uring_ptr, - pub len: u32, - pub bid: u16, - #[doc(hidden)] - pub resv: u16, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Copy, Clone, Default)] -#[non_exhaustive] -pub struct buf_ring_tail_struct { - #[doc(hidden)] - pub resv1: u64, - #[doc(hidden)] - pub resv2: u32, - #[doc(hidden)] - pub resv3: u16, - pub tail: u16, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -pub struct buf_ring_bufs_struct { - pub bufs: IncompleteArrayField<io_uring_buf>, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -pub struct tail_or_bufs_struct { - pub tail: UnionField<buf_ring_tail_struct>, - pub bufs: UnionField<buf_ring_bufs_struct>, - pub union_field: [u64; 2], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -pub struct io_uring_buf_ring { - pub tail_or_bufs: tail_or_bufs_struct, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -#[non_exhaustive] -pub struct io_uring_napi { - pub busy_poll_to: u32, - pub prefer_busy_poll: u8, - pub opcode: u8, - #[doc(hidden)] - pub pad: [u8; 2], - pub op_param: u32, - #[doc(hidden)] - pub resv: u32, -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -#[non_exhaustive] -pub struct io_uring_clone_buffers { - pub src_fd: u32, - pub flags: u32, - pub src_off: u32, - pub dst_off: u32, - pub nr: u32, - #[doc(hidden)] - pub pad: [u32; 3], -} - -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Default)] -#[non_exhaustive] -pub struct io_uring_reg_wait { - pub ts: Timespec, - pub min_wait_usec: u32, - pub flags: u32, - pub sigmask: io_uring_ptr, - pub sigmask_sz: u32, - #[doc(hidden)] - pub pad: [u32; 3], - #[doc(hidden)] - pub pad2: [u64; 2], -} - -impl Default for ioprio_union { - #[inline] - fn default() -> Self { - default_union!(ioprio_union, ioprio) - } -} - -impl Default for len_union { - #[inline] - fn default() -> Self { - default_union!(len_union, len) - } -} - -impl Default for off_or_addr2_union { - #[inline] - fn default() -> Self { - default_union!(off_or_addr2_union, off) - } -} - -impl Default for addr_or_splice_off_in_union { - #[inline] - fn default() -> Self { - default_union!(addr_or_splice_off_in_union, splice_off_in) - } -} - -impl Default for addr3_or_cmd_union { - #[inline] - fn default() -> Self { - default_union!(addr3_or_cmd_union, addr3) - } -} - -impl Default for op_flags_union { - #[inline] - fn default() -> Self { - default_union!(op_flags_union, sync_range_flags) - } -} - -impl Default for buf_union { - #[inline] - fn default() -> Self { - default_union!(buf_union, buf_index) - } -} - -impl Default for splice_fd_in_or_file_index_or_addr_len_union { - #[inline] - fn default() -> Self { - default_union!(splice_fd_in_or_file_index_or_addr_len_union, splice_fd_in) - } -} - -impl Default for register_or_sqe_op_or_sqe_flags_union { - #[inline] - fn default() -> Self { - default_union!(register_or_sqe_op_or_sqe_flags_union, sqe_flags) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::fd::AsRawFd as _; - - /// Check that our custom structs and unions have the same layout as the - /// kernel's versions. - #[test] - fn io_uring_layouts() { - use sys as c; - - // `io_uring_ptr` is a replacement for `u64`. - assert_eq_size!(io_uring_ptr, u64); - assert_eq_align!(io_uring_ptr, u64); - - // Test that pointers are stored in `io_uring_ptr` in the way that - // io_uring stores them in a `u64`. - unsafe { - const MAGIC: u64 = !0x0123_4567_89ab_cdef; - let ptr = io_uring_ptr::new(MAGIC as usize as *mut c_void); - assert_eq!(ptr.ptr, MAGIC as usize as *mut c_void); - #[cfg(target_pointer_width = "16")] - assert_eq!(ptr.__pad16, 0); - #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] - assert_eq!(ptr.__pad32, 0); - let int = core::mem::transmute::<io_uring_ptr, u64>(ptr); - assert_eq!(int, MAGIC as usize as u64); - } - - // `io_uring_user_data` is a replacement for `u64`. - assert_eq_size!(io_uring_user_data, u64); - assert_eq_align!(io_uring_user_data, u64); - - // Test that `u64`s and pointers are properly stored in - // `io_uring_user_data`. - unsafe { - const MAGIC: u64 = !0x0123_4567_89ab_cdef; - let user_data = io_uring_user_data::from_u64(MAGIC); - assert_eq!(user_data.u64_(), MAGIC); - assert_eq!( - core::mem::transmute::<io_uring_user_data, u64>(user_data), - MAGIC - ); - let user_data = io_uring_user_data::from_ptr(MAGIC as usize as *mut c_void); - assert_eq!(user_data.ptr(), MAGIC as usize as *mut c_void); - assert_eq!( - core::mem::transmute::<io_uring_user_data, u64>(user_data), - MAGIC as usize as u64 - ); - } - - check_renamed_type!(off_or_addr2_union, io_uring_sqe__bindgen_ty_1); - check_renamed_type!(addr_or_splice_off_in_union, io_uring_sqe__bindgen_ty_2); - check_renamed_type!(addr3_or_cmd_union, io_uring_sqe__bindgen_ty_6); - check_renamed_type!(op_flags_union, io_uring_sqe__bindgen_ty_3); - check_renamed_type!(buf_union, io_uring_sqe__bindgen_ty_4); - check_renamed_type!( - splice_fd_in_or_file_index_or_addr_len_union, - io_uring_sqe__bindgen_ty_5 - ); - check_renamed_type!(addr_len_struct, io_uring_sqe__bindgen_ty_5__bindgen_ty_1); - check_renamed_type!( - register_or_sqe_op_or_sqe_flags_union, - io_uring_restriction__bindgen_ty_1 - ); - - check_renamed_type!(addr3_struct, io_uring_sqe__bindgen_ty_6__bindgen_ty_1); - check_renamed_type!(cmd_op_struct, io_uring_sqe__bindgen_ty_1__bindgen_ty_1); - - check_type!(io_uring_sqe); - check_struct_field!(io_uring_sqe, opcode); - check_struct_field!(io_uring_sqe, flags); - check_struct_field!(io_uring_sqe, ioprio); - check_struct_field!(io_uring_sqe, fd); - check_struct_renamed_field!(io_uring_sqe, off_or_addr2, __bindgen_anon_1); - check_struct_renamed_field!(io_uring_sqe, addr_or_splice_off_in, __bindgen_anon_2); - check_struct_field!(io_uring_sqe, len); - check_struct_renamed_field!(io_uring_sqe, op_flags, __bindgen_anon_3); - check_struct_field!(io_uring_sqe, user_data); - check_struct_renamed_field!(io_uring_sqe, buf, __bindgen_anon_4); - check_struct_field!(io_uring_sqe, personality); - check_struct_renamed_field!( - io_uring_sqe, - splice_fd_in_or_file_index_or_addr_len, - __bindgen_anon_5 - ); - check_struct_renamed_field!(io_uring_sqe, addr3_or_cmd, __bindgen_anon_6); - - check_type!(io_uring_restriction); - check_struct_field!(io_uring_restriction, opcode); - check_struct_renamed_field!( - io_uring_restriction, - register_or_sqe_op_or_sqe_flags, - __bindgen_anon_1 - ); - check_struct_field!(io_uring_restriction, resv); - check_struct_field!(io_uring_restriction, resv2); - - check_struct!(io_uring_cqe, user_data, res, flags, big_cqe); - check_struct!( - io_uring_params, - sq_entries, - cq_entries, - flags, - sq_thread_cpu, - sq_thread_idle, - features, - wq_fd, - resv, - sq_off, - cq_off - ); - check_struct!( - io_sqring_offsets, - head, - tail, - ring_mask, - ring_entries, - flags, - dropped, - array, - resv1, - user_addr - ); - check_struct!( - io_cqring_offsets, - head, - tail, - ring_mask, - ring_entries, - overflow, - cqes, - flags, - resv1, - user_addr - ); - check_struct!(io_uring_recvmsg_out, namelen, controllen, payloadlen, flags); - check_struct!(io_uring_probe, last_op, ops_len, resv, resv2, ops); - check_struct!(io_uring_probe_op, op, resv, flags, resv2); - check_struct!(io_uring_files_update, offset, resv, fds); - check_struct!(io_uring_rsrc_register, nr, flags, resv2, data, tags); - check_struct!(io_uring_rsrc_update, offset, resv, data); - check_struct!(io_uring_rsrc_update2, offset, resv, data, tags, nr, resv2); - check_struct!( - io_uring_getevents_arg, - sigmask, - sigmask_sz, - min_wait_usec, - ts - ); - check_struct!(iovec, iov_base, iov_len); - check_struct!(open_how, flags, mode, resolve); - check_struct!(io_uring_buf_reg, ring_addr, ring_entries, bgid, flags, resv); - check_struct!(io_uring_buf, addr, len, bid, resv); - check_struct!( - io_uring_sync_cancel_reg, - addr, - fd, - flags, - timeout, - opcode, - pad, - pad2 - ); - - check_renamed_type!(tail_or_bufs_struct, io_uring_buf_ring__bindgen_ty_1); - check_renamed_type!( - buf_ring_tail_struct, - io_uring_buf_ring__bindgen_ty_1__bindgen_ty_1 - ); - check_renamed_type!( - buf_ring_bufs_struct, - io_uring_buf_ring__bindgen_ty_1__bindgen_ty_2 - ); - check_struct_renamed_field!(io_uring_buf_ring, tail_or_bufs, __bindgen_anon_1); - - check_struct!( - io_uring_napi, - busy_poll_to, - prefer_busy_poll, - opcode, - pad, - op_param, - resv - ); - check_struct!( - io_uring_clone_buffers, - src_fd, - flags, - src_off, - dst_off, - nr, - pad - ); - check_struct!( - io_uring_reg_wait, - ts, - min_wait_usec, - flags, - sigmask, - sigmask_sz, - pad, - pad2 - ); - - check_renamed_struct!( - MsgHdr, - msghdr, - msg_name, - msg_namelen, - msg_iov, - msg_iovlen, - msg_control, - msg_controllen, - msg_flags - ); - } - - #[test] - fn test_io_uring_register_files_skip() { - use crate::backend::c; - assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != -1); - assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != c::STDIN_FILENO); - assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != c::STDOUT_FILENO); - assert!(IORING_REGISTER_FILES_SKIP.as_raw_fd() != c::STDERR_FILENO); - } -} diff --git a/vendor/rustix/src/ioctl/bsd.rs b/vendor/rustix/src/ioctl/bsd.rs deleted file mode 100644 index 965b31d1..00000000 --- a/vendor/rustix/src/ioctl/bsd.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! `ioctl` opcode behavior for BSD platforms. - -use super::{Direction, Opcode}; - -pub(super) const fn compose_opcode( - dir: Direction, - group: Opcode, - num: Opcode, - size: Opcode, -) -> Opcode { - let dir = match dir { - Direction::None => NONE, - Direction::Read => READ, - Direction::Write => WRITE, - Direction::ReadWrite => READ | WRITE, - }; - - dir | num | (group << 8) | ((size & IOCPARAM_MASK) << 16) -} - -// `IOC_VOID` -pub const NONE: Opcode = 0x2000_0000; -// `IOC_OUT` (“out” is from the perspective of the kernel) -pub const READ: Opcode = 0x4000_0000; -// `IOC_IN` (“in” is from the perspective of the kernel) -pub const WRITE: Opcode = 0x8000_0000; -pub const IOCPARAM_MASK: Opcode = 0x1FFF; diff --git a/vendor/rustix/src/ioctl/linux.rs b/vendor/rustix/src/ioctl/linux.rs deleted file mode 100644 index 7215228a..00000000 --- a/vendor/rustix/src/ioctl/linux.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! `ioctl` opcode behavior for Linux platforms. - -use super::{Direction, Opcode}; -use consts::*; - -/// Compose an opcode from its component parts. -pub(super) const fn compose_opcode( - dir: Direction, - group: Opcode, - num: Opcode, - size: Opcode, -) -> Opcode { - macro_rules! mask_and_shift { - ($val:expr, $shift:expr, $mask:expr) => {{ - ($val & $mask) << $shift - }}; - } - - let dir = match dir { - Direction::None => NONE, - Direction::Read => READ, - Direction::Write => WRITE, - Direction::ReadWrite => READ | WRITE, - }; - - mask_and_shift!(group, GROUP_SHIFT, GROUP_MASK) - | mask_and_shift!(num, NUM_SHIFT, NUM_MASK) - | mask_and_shift!(size, SIZE_SHIFT, SIZE_MASK) - | mask_and_shift!(dir, DIR_SHIFT, DIR_MASK) -} - -const NUM_BITS: Opcode = 8; -const GROUP_BITS: Opcode = 8; - -const NUM_SHIFT: Opcode = 0; -const GROUP_SHIFT: Opcode = NUM_SHIFT + NUM_BITS; -const SIZE_SHIFT: Opcode = GROUP_SHIFT + GROUP_BITS; -const DIR_SHIFT: Opcode = SIZE_SHIFT + SIZE_BITS; - -const NUM_MASK: Opcode = (1 << NUM_BITS) - 1; -const GROUP_MASK: Opcode = (1 << GROUP_BITS) - 1; -const SIZE_MASK: Opcode = (1 << SIZE_BITS) - 1; -const DIR_MASK: Opcode = (1 << DIR_BITS) - 1; - -#[cfg(any( - target_arch = "x86", - target_arch = "arm", - target_arch = "s390x", - target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "riscv32", - target_arch = "riscv64", - target_arch = "loongarch64", - target_arch = "csky" -))] -mod consts { - use super::Opcode; - - pub(super) const NONE: Opcode = 0; - pub(super) const READ: Opcode = 2; - pub(super) const WRITE: Opcode = 1; - pub(super) const SIZE_BITS: Opcode = 14; - pub(super) const DIR_BITS: Opcode = 2; -} - -#[cfg(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "sparc", - target_arch = "sparc64" -))] -mod consts { - use super::Opcode; - - pub(super) const NONE: Opcode = 1; - pub(super) const READ: Opcode = 2; - pub(super) const WRITE: Opcode = 4; - pub(super) const SIZE_BITS: Opcode = 13; - pub(super) const DIR_BITS: Opcode = 3; -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - - #[cfg(not(any( - // These have no ioctl opcodes defined in linux_raw_sys so we can't use - // that as a known-good value for this test. - target_arch = "sparc", - target_arch = "sparc64" -)))] - #[test] - fn check_known_opcodes() { - use crate::backend::c::{c_long, c_uint}; - use core::mem::size_of; - - // _IOR('U', 15, unsigned int) - assert_eq!( - compose_opcode( - Direction::Read, - b'U' as Opcode, - 15, - size_of::<c_uint>() as Opcode - ), - linux_raw_sys::ioctl::USBDEVFS_CLAIMINTERFACE as Opcode - ); - - // _IOW('v', 2, long) - assert_eq!( - compose_opcode( - Direction::Write, - b'v' as Opcode, - 2, - size_of::<c_long>() as Opcode - ), - linux_raw_sys::ioctl::FS_IOC_SETVERSION as Opcode - ); - } -} diff --git a/vendor/rustix/src/ioctl/mod.rs b/vendor/rustix/src/ioctl/mod.rs deleted file mode 100644 index e3e8f8e1..00000000 --- a/vendor/rustix/src/ioctl/mod.rs +++ /dev/null @@ -1,376 +0,0 @@ -//! Unsafe `ioctl` API. -//! -//! Unix systems expose a number of `ioctl`'s. `ioctl`s have been adopted as a -//! general purpose system call for making calls into the kernel. In addition -//! to the wide variety of system calls that are included by default in the -//! kernel, many drivers expose their own `ioctl`'s for controlling their -//! behavior, some of which are proprietary. Therefore it is impossible to make -//! a safe interface for every `ioctl` call, as they all have wildly varying -//! semantics. -//! -//! This module provides an unsafe interface to write your own `ioctl` API. To -//! start, create a type that implements [`Ioctl`]. Then, pass it to [`ioctl`] -//! to make the `ioctl` call. - -#![allow(unsafe_code)] - -use crate::fd::{AsFd, BorrowedFd}; -use crate::ffi as c; -use crate::io::Result; - -#[cfg(any(linux_kernel, bsd))] -use core::mem; - -pub use patterns::*; - -mod patterns; - -#[cfg(linux_kernel)] -mod linux; - -#[cfg(bsd)] -mod bsd; - -#[cfg(linux_kernel)] -use linux as platform; - -#[cfg(bsd)] -use bsd as platform; - -/// Perform an `ioctl` call. -/// -/// `ioctl` was originally intended to act as a way of modifying the behavior -/// of files, but has since been adopted as a general purpose system call for -/// making calls into the kernel. In addition to the default calls exposed by -/// generic file descriptors, many drivers expose their own `ioctl` calls for -/// controlling their behavior, some of which are proprietary. -/// -/// This crate exposes many other `ioctl` interfaces with safe and idiomatic -/// wrappers, like [`ioctl_fionbio`] and [`ioctl_fionread`]. It is recommended -/// to use those instead of this function, as they are safer and more -/// idiomatic. For other cases, implement the [`Ioctl`] API and pass it to this -/// function. -/// -/// See documentation for [`Ioctl`] for more information. -/// -/// [`ioctl_fionbio`]: crate::io::ioctl_fionbio -/// [`ioctl_fionread`]: crate::io::ioctl_fionread -/// -/// # Safety -/// -/// While [`Ioctl`] takes much of the unsafety out of `ioctl` calls, callers -/// must still ensure that the opcode value, operand type, and data access -/// correctly reflect what's in the device driver servicing the call. `ioctl` -/// calls form a protocol between the userspace `ioctl` callers and the device -/// drivers in the kernel, and safety depends on both sides agreeing and -/// upholding the expectations of the other. -/// -/// And, `ioctl` calls can read and write arbitrary memory and have arbitrary -/// side effects. Callers must ensure that any memory accesses and side effects -/// are compatible with Rust language invariants. -/// -/// # References -/// - [Linux] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [Apple] -/// - [Solaris] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl.2.html -/// [Winsock]: https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-ioctlsocket -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2 -/// [NetBSD]: https://man.netbsd.org/ioctl.2 -/// [OpenBSD]: https://man.openbsd.org/ioctl.2 -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/ioctl.2.html -/// [Solaris]: https://docs.oracle.com/cd/E23824_01/html/821-1463/ioctl-2.html -/// [illumos]: https://illumos.org/man/2/ioctl -#[inline] -pub unsafe fn ioctl<F: AsFd, I: Ioctl>(fd: F, mut ioctl: I) -> Result<I::Output> { - let fd = fd.as_fd(); - let request = ioctl.opcode(); - let arg = ioctl.as_ptr(); - - // SAFETY: The variant of `Ioctl` asserts that this is a valid IOCTL call - // to make. - let output = if I::IS_MUTATING { - _ioctl(fd, request, arg)? - } else { - _ioctl_readonly(fd, request, arg)? - }; - - // SAFETY: The variant of `Ioctl` asserts that this is a valid pointer to - // the output data. - I::output_from_ptr(output, arg) -} - -unsafe fn _ioctl(fd: BorrowedFd<'_>, request: Opcode, arg: *mut c::c_void) -> Result<IoctlOutput> { - crate::backend::io::syscalls::ioctl(fd, request, arg) -} - -unsafe fn _ioctl_readonly( - fd: BorrowedFd<'_>, - request: Opcode, - arg: *mut c::c_void, -) -> Result<IoctlOutput> { - crate::backend::io::syscalls::ioctl_readonly(fd, request, arg) -} - -/// A trait defining the properties of an `ioctl` command. -/// -/// Objects implementing this trait can be passed to [`ioctl`] to make an -/// `ioctl` call. The contents of the object represent the inputs to the -/// `ioctl` call. The inputs must be convertible to a pointer through the -/// `as_ptr` method. In most cases, this involves either casting a number to a -/// pointer, or creating a pointer to the actual data. The latter case is -/// necessary for `ioctl` calls that modify userspace data. -/// -/// # Safety -/// -/// This trait is unsafe to implement because it is impossible to guarantee -/// that the `ioctl` call is safe. The `ioctl` call may be proprietary, or it -/// may be unsafe to call in certain circumstances. -/// -/// By implementing this trait, you guarantee that: -/// -/// - The `ioctl` call expects the input provided by `as_ptr` and produces the -/// output as indicated by `output`. -/// - That `output_from_ptr` can safely take the pointer from `as_ptr` and -/// cast it to the correct type, *only* after the `ioctl` call. -/// - That the return value of `opcode` uniquely identifies the `ioctl` call. -/// - That, for whatever platforms you are targeting, the `ioctl` call is safe -/// to make. -/// - If `IS_MUTATING` is false, that no userspace data will be modified by -/// the `ioctl` call. -pub unsafe trait Ioctl { - /// The type of the output data. - /// - /// Given a pointer, one should be able to construct an instance of this - /// type. - type Output; - - /// Does the `ioctl` mutate any data in the userspace? - /// - /// If the `ioctl` call does not mutate any data in the userspace, then - /// making this `false` enables optimizations that can make the call - /// faster. When in doubt, set this to `true`. - /// - /// # Safety - /// - /// This should only be set to `false` if the `ioctl` call does not mutate - /// any data in the userspace. Undefined behavior may occur if this is set - /// to `false` when it should be `true`. - const IS_MUTATING: bool; - - /// Get the opcode used by this `ioctl` command. - /// - /// There are different types of opcode depending on the operation. See - /// documentation for [`opcode`] for more information. - fn opcode(&self) -> Opcode; - - /// Get a pointer to the data to be passed to the `ioctl` command. - /// - /// See trait-level documentation for more information. - fn as_ptr(&mut self) -> *mut c::c_void; - - /// Cast the output data to the correct type. - /// - /// # Safety - /// - /// The `extract_output` value must be the resulting value after a - /// successful `ioctl` call, and `out` is the direct return value of an - /// `ioctl` call that did not fail. In this case `extract_output` is the - /// pointer that was passed to the `ioctl` call. - unsafe fn output_from_ptr( - out: IoctlOutput, - extract_output: *mut c::c_void, - ) -> Result<Self::Output>; -} - -/// Const functions for computing opcode values. -/// -/// Linux's headers define macros such as `_IO`, `_IOR`, `_IOW`, and `_IOWR` -/// for defining ioctl values in a structured way that encode whether they -/// are reading and/or writing, and other information about the ioctl. The -/// functions in this module correspond to those macros. -/// -/// If you're writing a driver and defining your own ioctl numbers, it's -/// recommended to use these functions to compute them. -#[cfg(any(linux_kernel, bsd))] -pub mod opcode { - use super::*; - - /// Create a new opcode from a direction, group, number, and size. - /// - /// This corresponds to the C macro `_IOC(direction, group, number, size)` - #[doc(alias = "_IOC")] - #[inline] - pub const fn from_components( - direction: Direction, - group: u8, - number: u8, - data_size: usize, - ) -> Opcode { - assert!(data_size <= Opcode::MAX as usize, "data size is too large"); - - platform::compose_opcode( - direction, - group as Opcode, - number as Opcode, - data_size as Opcode, - ) - } - - /// Create a new opcode from a group, a number, that uses no data. - /// - /// This corresponds to the C macro `_IO(group, number)`. - #[doc(alias = "_IO")] - #[inline] - pub const fn none(group: u8, number: u8) -> Opcode { - from_components(Direction::None, group, number, 0) - } - - /// Create a new reading opcode from a group, a number and the type of - /// data. - /// - /// This corresponds to the C macro `_IOR(group, number, T)`. - #[doc(alias = "_IOR")] - #[inline] - pub const fn read<T>(group: u8, number: u8) -> Opcode { - from_components(Direction::Read, group, number, mem::size_of::<T>()) - } - - /// Create a new writing opcode from a group, a number and the type of - /// data. - /// - /// This corresponds to the C macro `_IOW(group, number, T)`. - #[doc(alias = "_IOW")] - #[inline] - pub const fn write<T>(group: u8, number: u8) -> Opcode { - from_components(Direction::Write, group, number, mem::size_of::<T>()) - } - - /// Create a new reading and writing opcode from a group, a number and the - /// type of data. - /// - /// This corresponds to the C macro `_IOWR(group, number, T)`. - #[doc(alias = "_IOWR")] - #[inline] - pub const fn read_write<T>(group: u8, number: u8) -> Opcode { - from_components(Direction::ReadWrite, group, number, mem::size_of::<T>()) - } -} - -/// The direction that an `ioctl` is going. -/// -/// The direction is relative to userspace: `Read` means reading data from the -/// kernel, and `Write` means the kernel writing data to userspace. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Direction { - /// None of the above. - None, - - /// Read data from the kernel. - Read, - - /// Write data to the kernel. - Write, - - /// Read and write data to the kernel. - ReadWrite, -} - -/// The type used by the `ioctl` to signify the output. -pub type IoctlOutput = c::c_int; - -/// The type used by the `ioctl` to signify the command. -pub type Opcode = _Opcode; - -// Under raw Linux, this is an `unsigned int`. -#[cfg(linux_raw)] -type _Opcode = c::c_uint; - -// On libc Linux with GNU libc or uclibc, this is an `unsigned long`. -#[cfg(all( - not(linux_raw), - target_os = "linux", - any(target_env = "gnu", target_env = "uclibc") -))] -type _Opcode = c::c_ulong; - -// Musl uses `c_int`. -#[cfg(all( - not(linux_raw), - target_os = "linux", - not(target_env = "gnu"), - not(target_env = "uclibc") -))] -type _Opcode = c::c_int; - -// Android uses `c_int`. -#[cfg(all(not(linux_raw), target_os = "android"))] -type _Opcode = c::c_int; - -// BSD, Haiku, Hurd, Redox, and Vita use `unsigned long`. -#[cfg(any( - bsd, - target_os = "redox", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "vita" -))] -type _Opcode = c::c_ulong; - -// AIX, Emscripten, Fuchsia, Solaris, and WASI use a `int`. -#[cfg(any( - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "fuchsia", - target_os = "emscripten", - target_os = "nto", - target_os = "wasi", -))] -type _Opcode = c::c_int; - -// ESP-IDF uses a `c_uint`. -#[cfg(target_os = "espidf")] -type _Opcode = c::c_uint; - -// Windows has `ioctlsocket`, which uses `i32`. -#[cfg(windows)] -type _Opcode = i32; - -#[cfg(linux_kernel)] -#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_opcode_funcs() { - // `TUNGETDEVNETNS` is defined as `_IO('T', 227)`. - assert_eq!( - linux_raw_sys::ioctl::TUNGETDEVNETNS as Opcode, - opcode::none(b'T', 227) - ); - // `FS_IOC_GETVERSION` is defined as `_IOR('v', 1, long)`. - assert_eq!( - linux_raw_sys::ioctl::FS_IOC_GETVERSION as Opcode, - opcode::read::<c::c_long>(b'v', 1) - ); - // `TUNSETNOCSUM` is defined as `_IOW('T', 200, int)`. - assert_eq!( - linux_raw_sys::ioctl::TUNSETNOCSUM as Opcode, - opcode::write::<c::c_int>(b'T', 200) - ); - // `FIFREEZE` is defined as `_IOWR('X', 119, int)`. - assert_eq!( - linux_raw_sys::ioctl::FIFREEZE as Opcode, - opcode::read_write::<c::c_int>(b'X', 119) - ); - } -} diff --git a/vendor/rustix/src/ioctl/patterns.rs b/vendor/rustix/src/ioctl/patterns.rs deleted file mode 100644 index a08aae74..00000000 --- a/vendor/rustix/src/ioctl/patterns.rs +++ /dev/null @@ -1,268 +0,0 @@ -//! Implements typical patterns for `ioctl` usage. - -use super::{Ioctl, IoctlOutput, Opcode}; - -use crate::backend::c; -use crate::io::Result; - -use core::ptr::addr_of_mut; -use core::{fmt, mem}; - -/// Implements an `ioctl` with no real arguments. -/// -/// To compute a value for the `OPCODE` argument, see the functions in the -/// [`opcode`] module. -/// -/// [`opcode`]: crate::ioctl::opcode -pub struct NoArg<const OPCODE: Opcode> {} - -impl<const OPCODE: Opcode> fmt::Debug for NoArg<OPCODE> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("NoArg").field(&OPCODE).finish() - } -} - -impl<const OPCODE: Opcode> NoArg<OPCODE> { - /// Create a new no-argument `ioctl` object. - /// - /// # Safety - /// - /// - `OPCODE` must provide a valid opcode. - #[inline] - pub const unsafe fn new() -> Self { - Self {} - } -} - -unsafe impl<const OPCODE: Opcode> Ioctl for NoArg<OPCODE> { - type Output = (); - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> self::Opcode { - OPCODE - } - - fn as_ptr(&mut self) -> *mut c::c_void { - core::ptr::null_mut() - } - - unsafe fn output_from_ptr(_: IoctlOutput, _: *mut c::c_void) -> Result<Self::Output> { - Ok(()) - } -} - -/// Implements the traditional “getter” pattern for `ioctl`s. -/// -/// Some `ioctl`s just read data into the userspace. As this is a popular -/// pattern, this structure implements it. -/// -/// To compute a value for the `OPCODE` argument, see the functions in the -/// [`opcode`] module. -/// -/// [`opcode`]: crate::ioctl::opcode -pub struct Getter<const OPCODE: Opcode, Output> { - /// The output data. - output: mem::MaybeUninit<Output>, -} - -impl<const OPCODE: Opcode, Output> fmt::Debug for Getter<OPCODE, Output> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Getter").field(&OPCODE).finish() - } -} - -impl<const OPCODE: Opcode, Output> Getter<OPCODE, Output> { - /// Create a new getter-style `ioctl` object. - /// - /// # Safety - /// - /// - `OPCODE` must provide a valid opcode. - /// - For this opcode, `Output` must be the type that the kernel expects - /// to write into. - #[inline] - pub const unsafe fn new() -> Self { - Self { - output: mem::MaybeUninit::uninit(), - } - } -} - -unsafe impl<const OPCODE: Opcode, Output> Ioctl for Getter<OPCODE, Output> { - type Output = Output; - - const IS_MUTATING: bool = true; - - fn opcode(&self) -> self::Opcode { - OPCODE - } - - fn as_ptr(&mut self) -> *mut c::c_void { - self.output.as_mut_ptr().cast() - } - - unsafe fn output_from_ptr(_: IoctlOutput, ptr: *mut c::c_void) -> Result<Self::Output> { - Ok(ptr.cast::<Output>().read()) - } -} - -/// Implements the pattern for `ioctl`s where a pointer argument is given to -/// the `ioctl`. -/// -/// The opcode must be read-only. -/// -/// To compute a value for the `OPCODE` argument, see the functions in the -/// [`opcode`] module. -/// -/// [`opcode`]: crate::ioctl::opcode -pub struct Setter<const OPCODE: Opcode, Input> { - /// The input data. - input: Input, -} - -impl<const OPCODE: Opcode, Input: fmt::Debug> fmt::Debug for Setter<OPCODE, Input> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Setter") - .field(&OPCODE) - .field(&self.input) - .finish() - } -} - -impl<const OPCODE: Opcode, Input> Setter<OPCODE, Input> { - /// Create a new pointer setter-style `ioctl` object. - /// - /// # Safety - /// - /// - `OPCODE` must provide a valid opcode. - /// - For this opcode, `Input` must be the type that the kernel expects to - /// get. - #[inline] - pub const unsafe fn new(input: Input) -> Self { - Self { input } - } -} - -unsafe impl<const OPCODE: Opcode, Input> Ioctl for Setter<OPCODE, Input> { - type Output = (); - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> self::Opcode { - OPCODE - } - - fn as_ptr(&mut self) -> *mut c::c_void { - addr_of_mut!(self.input).cast::<c::c_void>() - } - - unsafe fn output_from_ptr(_: IoctlOutput, _: *mut c::c_void) -> Result<Self::Output> { - Ok(()) - } -} - -/// Implements an “updater” pattern for `ioctl`s. -/// -/// The ioctl takes a reference to a struct that it reads its input from, -/// then writes output to the same struct. -/// -/// To compute a value for the `OPCODE` argument, see the functions in the -/// [`opcode`] module. -/// -/// [`opcode`]: crate::ioctl::opcode -pub struct Updater<'a, const OPCODE: Opcode, Value> { - /// Reference to input/output data. - value: &'a mut Value, -} - -impl<'a, const OPCODE: Opcode, Value> Updater<'a, OPCODE, Value> { - /// Create a new pointer updater-style `ioctl` object. - /// - /// # Safety - /// - /// - `OPCODE` must provide a valid opcode. - /// - For this opcode, `Value` must be the type that the kernel expects to - /// get. - #[inline] - pub unsafe fn new(value: &'a mut Value) -> Self { - Self { value } - } -} - -unsafe impl<'a, const OPCODE: Opcode, T> Ioctl for Updater<'a, OPCODE, T> { - type Output = (); - - const IS_MUTATING: bool = true; - - fn opcode(&self) -> self::Opcode { - OPCODE - } - - fn as_ptr(&mut self) -> *mut c::c_void { - (self.value as *mut T).cast() - } - - unsafe fn output_from_ptr(_output: IoctlOutput, _ptr: *mut c::c_void) -> Result<()> { - Ok(()) - } -} - -/// Implements an `ioctl` that passes an integer into the `ioctl`. -/// -/// To compute a value for the `OPCODE` argument, see the functions in the -/// [`opcode`] module. -/// -/// [`opcode`]: crate::ioctl::opcode -pub struct IntegerSetter<const OPCODE: Opcode> { - /// The value to pass in. - /// - /// For strict provenance preservation, this is a pointer. - value: *mut c::c_void, -} - -impl<const OPCODE: Opcode> IntegerSetter<OPCODE> { - /// Create a new integer `Ioctl` helper containing a `usize`. - /// - /// # Safety - /// - /// - `OPCODE` must provide a valid opcode. - /// - For this opcode, it must expect an integer. - /// - The integer is in the valid range for this opcode. - #[inline] - pub const unsafe fn new_usize(value: usize) -> Self { - Self { value: value as _ } - } - - /// Create a new integer `Ioctl` helper containing a `*mut c_void`. - /// - /// # Safety - /// - /// - `OPCODE` must provide a valid opcode. - /// - For this opcode, it must expect an integer. - /// - The integer is in the valid range for this opcode. - #[inline] - pub const unsafe fn new_pointer(value: *mut c::c_void) -> Self { - Self { value } - } -} - -unsafe impl<const OPCODE: Opcode> Ioctl for IntegerSetter<OPCODE> { - type Output = (); - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> self::Opcode { - OPCODE - } - - fn as_ptr(&mut self) -> *mut c::c_void { - self.value - } - - unsafe fn output_from_ptr( - _out: IoctlOutput, - _extract_output: *mut c::c_void, - ) -> Result<Self::Output> { - Ok(()) - } -} diff --git a/vendor/rustix/src/kernel_sigset.rs b/vendor/rustix/src/kernel_sigset.rs deleted file mode 100644 index 706bcb8c..00000000 --- a/vendor/rustix/src/kernel_sigset.rs +++ /dev/null @@ -1,326 +0,0 @@ -//! The [`KernelSigSet`] type. - -#![allow(unsafe_code)] -#![allow(non_camel_case_types)] - -use crate::backend::c; -use crate::signal::Signal; -use core::fmt; -use linux_raw_sys::general::{kernel_sigset_t, _NSIG}; - -/// `kernel_sigset_t`—A set of signal numbers, as used by some syscalls. -/// -/// This is similar to `libc::sigset_t`, but with only enough space for the -/// signals currently known to be used by the kernel. libc implementations -/// reserve extra space so that if Linux defines new signals in the future -/// they can add support without breaking their dynamic linking ABI. Rustix -/// doesn't support a dynamic linking ABI, so if we need to increase the -/// size of `KernelSigSet` in the future, we can do so. -/// -/// It's also the case that the last time Linux changed the size of its -/// `kernel_sigset_t` was when it added support for POSIX.1b signals in 1999. -/// -/// `KernelSigSet` is guaranteed to have a subset of the layout of -/// `libc::sigset_t`. -/// -/// libc implementations typically also reserve some signal values for internal -/// use. In a process that contains a libc, some unsafe functions invoke -/// undefined behavior if passed a `KernelSigSet` that contains one of the -/// signals that the libc reserves. -#[repr(transparent)] -#[derive(Clone)] -pub struct KernelSigSet(kernel_sigset_t); - -impl KernelSigSet { - /// Create a new empty `KernelSigSet`. - pub const fn empty() -> Self { - const fn zeros<const N: usize>() -> [c::c_ulong; N] { - [0; N] - } - Self(kernel_sigset_t { sig: zeros() }) - } - - /// Create a new `KernelSigSet` with all signals set. - /// - /// This includes signals which are typically reserved for libc. - pub const fn all() -> Self { - const fn ones<const N: usize>() -> [c::c_ulong; N] { - [!0; N] - } - Self(kernel_sigset_t { sig: ones() }) - } - - /// Remove all signals. - pub fn clear(&mut self) { - *self = Self(kernel_sigset_t { - sig: Default::default(), - }); - } - - /// Insert a signal. - pub fn insert(&mut self, sig: Signal) { - let sigs_per_elt = core::mem::size_of_val(&self.0.sig[0]) * 8; - - let raw = (sig.as_raw().wrapping_sub(1)) as usize; - self.0.sig[raw / sigs_per_elt] |= 1 << (raw % sigs_per_elt); - } - - /// Insert all signals. - pub fn insert_all(&mut self) { - self.0.sig.fill(!0); - } - - /// Remove a signal. - pub fn remove(&mut self, sig: Signal) { - let sigs_per_elt = core::mem::size_of_val(&self.0.sig[0]) * 8; - - let raw = (sig.as_raw().wrapping_sub(1)) as usize; - self.0.sig[raw / sigs_per_elt] &= !(1 << (raw % sigs_per_elt)); - } - - /// Test whether a given signal is present. - pub fn contains(&self, sig: Signal) -> bool { - let sigs_per_elt = core::mem::size_of_val(&self.0.sig[0]) * 8; - - let raw = (sig.as_raw().wrapping_sub(1)) as usize; - (self.0.sig[raw / sigs_per_elt] & (1 << (raw % sigs_per_elt))) != 0 - } -} - -impl Default for KernelSigSet { - #[inline] - fn default() -> Self { - Self::empty() - } -} - -impl fmt::Debug for KernelSigSet { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut d = f.debug_set(); - - // Surprisingly, `_NSIG` is inclusive. - for i in 1..=_NSIG { - // SAFETY: This value is non-zero, in range, and only used for - // debug output. - let sig = unsafe { Signal::from_raw_unchecked(i as _) }; - - if self.contains(sig) { - d.entry(&sig); - } - } - - d.finish() - } -} - -#[cfg(test)] -mod tests { - use super::*; - #[cfg(linux_raw)] - use crate::runtime::{KERNEL_SIGRTMAX, KERNEL_SIGRTMIN}; - use core::mem::{align_of, size_of}; - - #[test] - fn test_assumptions() { - #[cfg(linux_raw)] - assert!(KERNEL_SIGRTMAX as usize - 1 < size_of::<KernelSigSet>() * 8); - } - - #[test] - fn test_layouts() { - assert!(size_of::<KernelSigSet>() <= size_of::<libc::sigset_t>()); - assert!(align_of::<KernelSigSet>() <= align_of::<libc::sigset_t>()); - } - - /// A bunch of signals for testing. - fn sigs() -> Vec<Signal> { - #[allow(unused_mut)] - let mut sigs = vec![ - Signal::HUP, - Signal::INT, - Signal::QUIT, - Signal::ILL, - Signal::TRAP, - Signal::ABORT, - Signal::BUS, - Signal::FPE, - Signal::KILL, - Signal::USR1, - Signal::SEGV, - Signal::USR2, - Signal::PIPE, - Signal::ALARM, - Signal::TERM, - Signal::CHILD, - Signal::CONT, - Signal::STOP, - Signal::TSTP, - Signal::TTIN, - Signal::TTOU, - Signal::URG, - Signal::XCPU, - Signal::XFSZ, - Signal::VTALARM, - Signal::PROF, - Signal::WINCH, - Signal::SYS, - unsafe { Signal::from_raw_unchecked(libc::SIGRTMIN()) }, - unsafe { Signal::from_raw_unchecked(libc::SIGRTMIN() + 7) }, - unsafe { Signal::from_raw_unchecked(libc::SIGRTMAX()) }, - ]; - - #[cfg(linux_raw)] - { - sigs.push(unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN) }); - sigs.push(unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 7) }); - sigs.push(unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMAX) }); - } - - sigs - } - - /// A bunch of non-reserved signals for testing. - fn libc_sigs() -> [Signal; 31] { - [ - Signal::HUP, - Signal::INT, - Signal::QUIT, - Signal::ILL, - Signal::TRAP, - Signal::ABORT, - Signal::BUS, - Signal::FPE, - Signal::KILL, - Signal::USR1, - Signal::SEGV, - Signal::USR2, - Signal::PIPE, - Signal::ALARM, - Signal::TERM, - Signal::CHILD, - Signal::CONT, - Signal::STOP, - Signal::TSTP, - Signal::TTIN, - Signal::TTOU, - Signal::URG, - Signal::XCPU, - Signal::XFSZ, - Signal::VTALARM, - Signal::PROF, - Signal::WINCH, - Signal::SYS, - unsafe { Signal::from_raw_unchecked(libc::SIGRTMIN()) }, - unsafe { Signal::from_raw_unchecked(libc::SIGRTMIN() + 7) }, - unsafe { Signal::from_raw_unchecked(libc::SIGRTMAX()) }, - ] - } - - #[test] - fn test_ops_plain() { - for sig in sigs() { - let mut set = KernelSigSet::empty(); - for sig in sigs() { - assert!(!set.contains(sig)); - } - - set.insert(sig); - assert!(set.contains(sig)); - for sig in sigs().iter().filter(|s| **s != sig) { - assert!(!set.contains(*sig)); - } - - set.remove(sig); - for sig in sigs() { - assert!(!set.contains(sig)); - } - } - } - - #[test] - fn test_clear() { - let mut set = KernelSigSet::empty(); - for sig in sigs() { - set.insert(sig); - } - - set.clear(); - - for sig in sigs() { - assert!(!set.contains(sig)); - } - } - - // io_uring libraries assume that libc's `sigset_t` matches the layout - // of the Linux kernel's `kernel_sigset_t`. Test that rustix's layout - // matches as well. - #[test] - fn test_libc_layout_compatibility() { - use crate::utils::as_ptr; - - let mut lc = unsafe { core::mem::zeroed::<libc::sigset_t>() }; - let mut ru = KernelSigSet::empty(); - let r = unsafe { libc::sigemptyset(&mut lc) }; - - assert_eq!(r, 0); - assert_eq!( - unsafe { - libc::memcmp( - as_ptr(&lc).cast(), - as_ptr(&ru).cast(), - core::mem::size_of::<KernelSigSet>(), - ) - }, - 0 - ); - - for sig in libc_sigs() { - ru.insert(sig); - assert_ne!( - unsafe { - libc::memcmp( - as_ptr(&lc).cast(), - as_ptr(&ru).cast(), - core::mem::size_of::<KernelSigSet>(), - ) - }, - 0 - ); - let r = unsafe { libc::sigaddset(&mut lc, sig.as_raw()) }; - assert_eq!(r, 0); - assert_eq!( - unsafe { - libc::memcmp( - as_ptr(&lc).cast(), - as_ptr(&ru).cast(), - core::mem::size_of::<KernelSigSet>(), - ) - }, - 0 - ); - ru.remove(sig); - assert_ne!( - unsafe { - libc::memcmp( - as_ptr(&lc).cast(), - as_ptr(&ru).cast(), - core::mem::size_of::<KernelSigSet>(), - ) - }, - 0 - ); - let r = unsafe { libc::sigdelset(&mut lc, sig.as_raw()) }; - assert_eq!(r, 0); - assert_eq!( - unsafe { - libc::memcmp( - as_ptr(&lc).cast(), - as_ptr(&ru).cast(), - core::mem::size_of::<KernelSigSet>(), - ) - }, - 0 - ); - } - } -} diff --git a/vendor/rustix/src/lib.rs b/vendor/rustix/src/lib.rs deleted file mode 100644 index 77f8a215..00000000 --- a/vendor/rustix/src/lib.rs +++ /dev/null @@ -1,426 +0,0 @@ -//! `rustix` provides efficient memory-safe and [I/O-safe] wrappers to -//! POSIX-like, Unix-like, Linux, and Winsock syscall-like APIs, with -//! configurable backends. -//! -//! With rustix, you can write code like this: -//! -//! ``` -//! # #[cfg(feature = "net")] -//! # fn read(sock: std::net::TcpStream, buf: &mut [u8]) -> std::io::Result<()> { -//! # use rustix::net::RecvFlags; -//! let (nread, _received) = rustix::net::recv(&sock, buf, RecvFlags::PEEK)?; -//! # let _ = nread; -//! # Ok(()) -//! # } -//! ``` -//! -//! instead of like this: -//! -//! ``` -//! # #[cfg(feature = "net")] -//! # fn read(sock: std::net::TcpStream, buf: &mut [u8]) -> std::io::Result<()> { -//! # #[cfg(unix)] -//! # use std::os::unix::io::AsRawFd; -//! # #[cfg(target_os = "wasi")] -//! # use std::os::wasi::io::AsRawFd; -//! # #[cfg(windows)] -//! # use windows_sys::Win32::Networking::WinSock as libc; -//! # #[cfg(windows)] -//! # use std::os::windows::io::AsRawSocket; -//! # const MSG_PEEK: i32 = libc::MSG_PEEK; -//! let nread = unsafe { -//! #[cfg(any(unix, target_os = "wasi"))] -//! let raw = sock.as_raw_fd(); -//! #[cfg(windows)] -//! let raw = sock.as_raw_socket(); -//! match libc::recv( -//! raw as _, -//! buf.as_mut_ptr().cast(), -//! buf.len().try_into().unwrap_or(i32::MAX as _), -//! MSG_PEEK, -//! ) { -//! -1 => return Err(std::io::Error::last_os_error()), -//! nread => nread as usize, -//! } -//! }; -//! # let _ = nread; -//! # Ok(()) -//! # } -//! ``` -//! -//! rustix's APIs perform the following tasks: -//! - Error values are translated to [`Result`]s. -//! - Buffers are passed as Rust slices. -//! - Out-parameters are presented as return values. -//! - Path arguments use [`Arg`], so they accept any string type. -//! - File descriptors are passed and returned via [`AsFd`] and [`OwnedFd`] -//! instead of bare integers, ensuring I/O safety. -//! - Constants use `enum`s and [`bitflags`] types, and enable [support for -//! externally defined flags]. -//! - Multiplexed functions (eg. `fcntl`, `ioctl`, etc.) are de-multiplexed. -//! - Variadic functions (eg. `openat`, etc.) are presented as non-variadic. -//! - Functions that return strings automatically allocate sufficient memory -//! and retry the syscall as needed to determine the needed length. -//! - Functions and types which need `l` prefixes or `64` suffixes to enable -//! large-file support (LFS) are used automatically. File sizes and offsets -//! are always presented as `u64` and `i64`. -//! - Behaviors that depend on the sizes of C types like `long` are hidden. -//! - In some places, more human-friendly and less historical-accident names -//! are used (and documentation aliases are used so that the original names -//! can still be searched for). -//! - Provide y2038 compatibility, on platforms which support this. -//! - Correct selected platform bugs, such as behavioral differences when -//! running under seccomp. -//! - Use `timespec` for timestamps and timeouts instead of `timeval` and -//! `c_int` milliseconds. -//! -//! Things they don't do include: -//! - Detecting whether functions are supported at runtime, except in specific -//! cases where new interfaces need to be detected to support y2038 and LFS. -//! - Hiding significant differences between platforms. -//! - Restricting ambient authorities. -//! - Imposing sandboxing features such as filesystem path or network address -//! sandboxing. -//! -//! See [`cap-std`], [`system-interface`], and [`io-streams`] for libraries -//! which do hide significant differences between platforms, and [`cap-std`] -//! which does perform sandboxing and restricts ambient authorities. -//! -//! [`cap-std`]: https://crates.io/crates/cap-std -//! [`system-interface`]: https://crates.io/crates/system-interface -//! [`io-streams`]: https://crates.io/crates/io-streams -//! [`bitflags`]: bitflags -//! [`AsFd`]: crate::fd::AsFd -//! [`OwnedFd`]: crate::fd::OwnedFd -//! [I/O-safe]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md -//! [`Arg`]: path::Arg -//! [support for externally defined flags]: bitflags#externally-defined-flags - -#![deny(missing_docs)] -#![allow(stable_features)] -#![cfg_attr(linux_raw, deny(unsafe_code))] -#![cfg_attr(rustc_attrs, feature(rustc_attrs))] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![cfg_attr(all(wasi_ext, target_os = "wasi", feature = "std"), feature(wasi_ext))] -#![cfg_attr(core_ffi_c, feature(core_ffi_c))] -#![cfg_attr(core_c_str, feature(core_c_str))] -#![cfg_attr(error_in_core, feature(error_in_core))] -#![cfg_attr(all(feature = "alloc", alloc_c_string), feature(alloc_c_string))] -#![cfg_attr(all(feature = "alloc", alloc_ffi), feature(alloc_ffi))] -#![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "rustc-dep-of-std", feature(ip))] -#![cfg_attr(feature = "rustc-dep-of-std", allow(internal_features))] -#![cfg_attr( - any(feature = "rustc-dep-of-std", core_intrinsics), - feature(core_intrinsics) -)] -#![cfg_attr(asm_experimental_arch, feature(asm_experimental_arch))] -#![cfg_attr(not(feature = "all-apis"), allow(dead_code))] -// It is common in Linux and libc APIs for types to vary between platforms. -#![allow(clippy::unnecessary_cast)] -// It is common in Linux and libc APIs for types to vary between platforms. -#![allow(clippy::useless_conversion)] -// This clippy lint gets too many false positives. -#![allow(clippy::needless_lifetimes)] -// Until `unnecessary_transmutes` is recognized by our MSRV, don't warn about -// it being unrecognized. -#![allow(unknown_lints)] -// Until `cast_signed` and `cast_unsigned` are supported by our MSRV, don't -// warn about transmutes that could be changed to them. -#![allow(unnecessary_transmutes)] -// Redox and WASI have enough differences that it isn't worth precisely -// conditionalizing all the `use`s for them. Similar for if we don't have -// "all-apis". -#![cfg_attr( - any(target_os = "redox", target_os = "wasi", not(feature = "all-apis")), - allow(unused_imports) -)] -// wasip2 conditionally gates stdlib APIs such as `OsStrExt`. -// <https://github.com/rust-lang/rust/issues/130323> -#![cfg_attr( - all( - target_os = "wasi", - target_env = "p2", - any(feature = "fs", feature = "mount", feature = "net"), - wasip2, - ), - feature(wasip2) -)] - -#[cfg(all(feature = "alloc", feature = "rustc-dep-of-std"))] -extern crate rustc_std_workspace_alloc as alloc; - -#[cfg(all(feature = "alloc", not(feature = "rustc-dep-of-std")))] -extern crate alloc; - -// Use `static_assertions` macros if we have them, or a polyfill otherwise. -#[cfg(all(test, static_assertions))] -#[macro_use] -#[allow(unused_imports)] -extern crate static_assertions; -#[cfg(all(test, not(static_assertions)))] -#[macro_use] -#[allow(unused_imports)] -mod static_assertions; - -pub mod buffer; -#[cfg(not(windows))] -#[macro_use] -pub(crate) mod cstr; -#[macro_use] -pub(crate) mod utils; -// Polyfill for `std` in `no_std` builds. -#[cfg_attr(feature = "std", path = "maybe_polyfill/std/mod.rs")] -#[cfg_attr(not(feature = "std"), path = "maybe_polyfill/no_std/mod.rs")] -pub(crate) mod maybe_polyfill; -#[cfg(test)] -#[macro_use] -pub(crate) mod check_types; -#[macro_use] -pub(crate) mod bitcast; - -// linux_raw: Weak symbols are used by the use-libc-auxv feature for -// glibc 2.15 support. -// -// libc: Weak symbols are used to call various functions available in some -// versions of libc and not others. -#[cfg(any( - all(linux_raw, feature = "use-libc-auxv"), - all(libc, not(any(windows, target_os = "espidf", target_os = "wasi"))) -))] -#[macro_use] -mod weak; - -// Pick the backend implementation to use. -#[cfg_attr(libc, path = "backend/libc/mod.rs")] -#[cfg_attr(linux_raw, path = "backend/linux_raw/mod.rs")] -#[cfg_attr(wasi, path = "backend/wasi/mod.rs")] -mod backend; - -/// Export the `*Fd` types and traits that are used in rustix's public API. -/// -/// This module exports the types and traits from [`std::os::fd`], or polyills -/// on Rust < 1.66 or on Windows. -/// -/// On Windows, the polyfill consists of aliases of the socket types and -/// traits, For example, [`OwnedSocket`] is aliased to `OwnedFd`, and so on, -/// and there are blanket impls for `AsFd` etc. that map to `AsSocket` impls. -/// These blanket impls suffice for using the traits, however not for -/// implementing them, so this module also exports `AsSocket` and the other -/// traits as-is so that users can implement them if needed. -/// -/// [`OwnedSocket`]: https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedSocket.html -pub mod fd { - pub use super::backend::fd::*; -} - -// The public API modules. -#[cfg(feature = "event")] -#[cfg_attr(docsrs, doc(cfg(feature = "event")))] -pub mod event; -pub mod ffi; -#[cfg(not(windows))] -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -pub mod fs; -pub mod io; -#[cfg(linux_kernel)] -#[cfg(feature = "io_uring")] -#[cfg_attr(docsrs, doc(cfg(feature = "io_uring")))] -pub mod io_uring; -pub mod ioctl; -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[cfg(feature = "mm")] -#[cfg_attr(docsrs, doc(cfg(feature = "mm")))] -pub mod mm; -#[cfg(linux_kernel)] -#[cfg(feature = "mount")] -#[cfg_attr(docsrs, doc(cfg(feature = "mount")))] -pub mod mount; -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "net")] -#[cfg_attr(docsrs, doc(cfg(feature = "net")))] -pub mod net; -#[cfg(not(any(windows, target_os = "espidf")))] -#[cfg(feature = "param")] -#[cfg_attr(docsrs, doc(cfg(feature = "param")))] -pub mod param; -#[cfg(not(windows))] -#[cfg(any(feature = "fs", feature = "mount", feature = "net"))] -#[cfg_attr( - docsrs, - doc(cfg(any(feature = "fs", feature = "mount", feature = "net"))) -)] -pub mod path; -#[cfg(feature = "pipe")] -#[cfg_attr(docsrs, doc(cfg(feature = "pipe")))] -#[cfg(not(any(windows, target_os = "wasi")))] -pub mod pipe; -#[cfg(not(windows))] -#[cfg(feature = "process")] -#[cfg_attr(docsrs, doc(cfg(feature = "process")))] -pub mod process; -#[cfg(not(windows))] -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "pty")] -#[cfg_attr(docsrs, doc(cfg(feature = "pty")))] -pub mod pty; -#[cfg(not(windows))] -#[cfg(feature = "rand")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] -pub mod rand; -#[cfg(not(any( - windows, - target_os = "android", - target_os = "espidf", - target_os = "horizon", - target_os = "vita", - target_os = "wasi" -)))] -#[cfg(feature = "shm")] -#[cfg_attr(docsrs, doc(cfg(feature = "shm")))] -pub mod shm; -#[cfg(not(windows))] -#[cfg(feature = "stdio")] -#[cfg_attr(docsrs, doc(cfg(feature = "stdio")))] -pub mod stdio; -#[cfg(feature = "system")] -#[cfg(not(any(windows, target_os = "wasi")))] -#[cfg_attr(docsrs, doc(cfg(feature = "system")))] -pub mod system; -#[cfg(not(any(windows, target_os = "horizon", target_os = "vita")))] -#[cfg(feature = "termios")] -#[cfg_attr(docsrs, doc(cfg(feature = "termios")))] -pub mod termios; -#[cfg(not(windows))] -#[cfg(feature = "thread")] -#[cfg_attr(docsrs, doc(cfg(feature = "thread")))] -pub mod thread; -#[cfg(not(any(windows, target_os = "espidf")))] -#[cfg(feature = "time")] -#[cfg_attr(docsrs, doc(cfg(feature = "time")))] -pub mod time; - -// "runtime" is also a public API module, but it's only for libc-like users. -#[cfg(not(windows))] -#[cfg(feature = "runtime")] -#[cfg(linux_raw)] -#[cfg_attr(not(document_experimental_runtime_api), doc(hidden))] -#[cfg_attr(docsrs, doc(cfg(feature = "runtime")))] -pub mod runtime; - -// Declare "fs" as a non-public module if "fs" isn't enabled but we need it for -// reading procfs. -#[cfg(not(windows))] -#[cfg(not(feature = "fs"))] -#[cfg(all( - linux_raw, - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) -))] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -pub(crate) mod fs; - -// Similarly, declare `path` as a non-public module if needed. -#[cfg(not(windows))] -#[cfg(not(any(feature = "fs", feature = "mount", feature = "net")))] -#[cfg(all( - linux_raw, - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "thread", - feature = "time", - target_arch = "x86", - ) -))] -pub(crate) mod path; - -// Private modules used by multiple public modules. -#[cfg(not(any(windows, target_os = "espidf")))] -#[cfg(any(feature = "thread", feature = "time"))] -mod clockid; -#[cfg(linux_kernel)] -#[cfg(any(feature = "io_uring", feature = "runtime"))] -mod kernel_sigset; -#[cfg(not(any(windows, target_os = "wasi")))] -#[cfg(any( - feature = "process", - feature = "runtime", - feature = "termios", - feature = "thread", - all(bsd, feature = "event"), - all(linux_kernel, feature = "net") -))] -mod pid; -#[cfg(any(feature = "process", feature = "thread"))] -#[cfg(linux_kernel)] -mod prctl; -#[cfg(not(any(windows, target_os = "espidf", target_os = "wasi")))] -#[cfg(any( - feature = "io_uring", - feature = "process", - feature = "runtime", - all(bsd, feature = "event") -))] -mod signal; -#[cfg(any( - feature = "fs", - feature = "event", - feature = "process", - feature = "runtime", - feature = "thread", - feature = "time", - all(feature = "event", any(bsd, linux_kernel, windows, target_os = "wasi")), - all( - linux_raw, - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "process", - feature = "runtime", - feature = "time", - target_arch = "x86", - ) - ) -))] -mod timespec; -#[cfg(not(any(windows, target_os = "wasi")))] -#[cfg(any( - feature = "fs", - feature = "process", - feature = "thread", - all( - linux_raw, - not(feature = "use-libc-auxv"), - not(feature = "use-explicitly-provided-auxv"), - any( - feature = "param", - feature = "runtime", - feature = "time", - target_arch = "x86", - ) - ), - all(linux_kernel, feature = "net") -))] -mod ugid; - -#[cfg(doc)] -#[cfg_attr(docsrs, doc(cfg(doc)))] -pub mod not_implemented; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/io/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/io/mod.rs deleted file mode 100644 index f0ad7504..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/io/mod.rs +++ /dev/null @@ -1,107 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/sys/unix/io.rs -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. - -#![allow(unsafe_code)] -use crate::backend::c; -#[cfg(not(linux_raw))] -use c::size_t as __kernel_size_t; -use core::marker::PhantomData; -use core::slice; -#[cfg(linux_raw)] -use linux_raw_sys::general::__kernel_size_t; - -/// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html> -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: c::iovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.new> - #[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() as _, - }, - _p: PhantomData, - } - } - - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.advance> - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n as _ { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - // `__kernel_size_t` will always have the same size as `usize`, but it is a `u32` on - // 32-bit platforms and `u64` on 64-bit platforms when using `linux_raw` backend - self.vec.iov_len -= n as __kernel_size_t; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.as_slice> - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) } - } -} - -/// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html> -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: c::iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.new> - #[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() as _, - }, - _p: PhantomData, - } - } - - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.advance> - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n as _ { - panic!("advancing IoSliceMut beyond its length"); - } - - unsafe { - // `__kernel_size_t` will always have the same size as `usize`, but it is a `u32` on - // 32-bit platforms and `u64` on 64-bit platforms when using `linux_raw` backend - self.vec.iov_len -= n as __kernel_size_t; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.as_slice> - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) } - } - - /// <https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.as_slice_mut> - #[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 as usize) - } - } -} diff --git a/vendor/rustix/src/maybe_polyfill/no_std/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/mod.rs deleted file mode 100644 index f29d4c34..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! Polyfill of parts of the standard library for `no_std` builds. -//! -//! All code in this subtree is derived from the standard library and licensed -//! MIT or Apache 2.0 at your option. -//! -//! This implementation is used when `std` is not available and polyfills the -//! necessary items from `std`. When the `std` feature is specified (so the -//! standard library is available), the file `src/polyfill/std` is used -//! instead, which just imports the respective items from `std`. - -#[cfg(not(windows))] -pub mod io; -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "net")] -pub mod net; -pub mod os; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs deleted file mode 100644 index bff56b13..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/net/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[allow(unused_imports)] -pub use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs deleted file mode 100644 index ea559534..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/os/fd/mod.rs at revision -//! fa68e73e9947be8ffc5b3b46d899e4953a44e7e9. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. -//! -//! Owned and borrowed Unix-like file descriptors. -//! -//! This module is supported on Unix platforms and WASI, which both use a -//! similar file descriptor system for referencing OS resources. - -#![cfg_attr(staged_api, stable(feature = "os_fd", since = "1.66.0"))] -#![deny(unsafe_op_in_unsafe_fn)] - -// `RawFd`, `AsRawFd`, etc. -mod raw; - -// `OwnedFd`, `AsFd`, etc. -mod owned; - -// Export the types and traits for the public API. -#[cfg_attr(staged_api, stable(feature = "os_fd", since = "1.66.0"))] -pub use owned::*; -#[cfg_attr(staged_api, stable(feature = "os_fd", since = "1.66.0"))] -pub use raw::*; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs deleted file mode 100644 index b6aea61a..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/owned.rs +++ /dev/null @@ -1,301 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/os/fd/owned.rs at revision -//! 334a54cd83191f38ad8046ed94c45de735c86c65. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. -//! -//! Owned and borrowed Unix-like file descriptors. - -#![cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -#![deny(unsafe_op_in_unsafe_fn)] -#![allow(unsafe_code)] - -use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -use crate::io::close; -use core::fmt; -use core::marker::PhantomData; -use core::mem::forget; - -/// A borrowed file descriptor. -/// -/// This has a lifetime parameter to tie it to the lifetime of something that owns the file -/// descriptor. For the duration of that lifetime, it is guaranteed that nobody will close the file -/// descriptor. -/// -/// This uses `repr(transparent)` and has the representation of a host file -/// descriptor, so it can be used in FFI in places where a file descriptor is -/// passed as an argument, it is not captured or consumed, and it never has the -/// value `-1`. -/// -/// This type does not have a [`ToOwned`][crate::borrow::ToOwned] -/// implementation. Calling `.to_owned()` on a variable of this type will call -/// it on `&BorrowedFd` and use `Clone::clone()` like `ToOwned` does for all -/// types implementing `Clone`. The result will be descriptor borrowed under -/// the same lifetime. -/// -/// To obtain an [`OwnedFd`], you can use [`BorrowedFd::try_clone_to_owned`] -/// instead, but this is not supported on all platforms. -#[derive(Copy, Clone)] -#[repr(transparent)] -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0))] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] -#[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -pub struct BorrowedFd<'fd> { - fd: RawFd, - _phantom: PhantomData<&'fd OwnedFd>, -} - -/// An owned file descriptor. -/// -/// This closes the file descriptor on drop. It is guaranteed that nobody else will close the file -/// descriptor. -/// -/// This uses `repr(transparent)` and has the representation of a host file -/// descriptor, so it can be used in FFI in places where a file descriptor is -/// passed as a consumed argument or returned as an owned value, and it never -/// has the value `-1`. -/// -/// You can use [`AsFd::as_fd`] to obtain a [`BorrowedFd`]. -#[repr(transparent)] -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0))] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -#[cfg_attr(rustc_attrs, rustc_nonnull_optimization_guaranteed)] -pub struct OwnedFd { - fd: RawFd, -} - -impl BorrowedFd<'_> { - /// Returns a `BorrowedFd` holding the given raw file descriptor. - /// - /// # Safety - /// - /// The resource pointed to by `fd` must remain open for the duration of - /// the returned `BorrowedFd`, and it must not have the value `-1`. - #[inline] - #[cfg_attr( - staged_api, - rustc_const_stable(feature = "io_safety", since = "1.63.0") - )] - #[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] - pub const unsafe fn borrow_raw(fd: RawFd) -> Self { - assert!(fd != u32::MAX as RawFd); - // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - #[allow(unused_unsafe)] - unsafe { - Self { - fd, - _phantom: PhantomData, - } - } - } -} - -impl OwnedFd { - /// Creates a new `OwnedFd` instance that shares the same underlying file handle - /// as the existing `OwnedFd` instance. - #[cfg(not(target_arch = "wasm32"))] - pub fn try_clone(&self) -> crate::io::Result<Self> { - // We want to atomically duplicate this file descriptor and set the - // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This - // is a POSIX flag that was added to Linux in 2.6.24. - #[cfg(not(target_os = "espidf"))] - let fd = crate::io::fcntl_dupfd_cloexec(self, 0)?; - - // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics - // will never be supported, as this is a bare metal framework with - // no capabilities for multi-process execution. While F_DUPFD is also - // not supported yet, it might be (currently it returns ENOSYS). - #[cfg(target_os = "espidf")] - let fd = crate::io::fcntl_dupfd(self, 0)?; - - Ok(fd.into()) - } - - /// Creates a new `OwnedFd` instance that shares the same underlying file handle - /// as the existing `OwnedFd` instance. - #[cfg(target_arch = "wasm32")] - pub fn try_clone(&self) -> crate::io::Result<Self> { - Err(crate::io::Errno::NOSYS) - } -} - -impl BorrowedFd<'_> { - /// Creates a new `OwnedFd` instance that shares the same underlying file - /// description as the existing `BorrowedFd` instance. - #[cfg(not(any(target_arch = "wasm32", target_os = "hermit")))] - #[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] - pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> { - // Avoid using file descriptors below 3 as they are used for stdio - - // We want to atomically duplicate this file descriptor and set the - // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This - // is a POSIX flag that was added to Linux in 2.6.24. - #[cfg(not(target_os = "espidf"))] - let fd = crate::io::fcntl_dupfd_cloexec(self, 3)?; - - // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics - // will never be supported, as this is a bare metal framework with - // no capabilities for multi-process execution. While F_DUPFD is also - // not supported yet, it might be (currently it returns ENOSYS). - #[cfg(target_os = "espidf")] - let fd = crate::io::fcntl_dupfd(self, 3)?; - - Ok(fd) - } - - /// Creates a new `OwnedFd` instance that shares the same underlying file - /// description as the existing `BorrowedFd` instance. - #[cfg(any(target_arch = "wasm32", target_os = "hermit"))] - #[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] - pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> { - Err(crate::io::Errno::NOSYS) - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl AsRawFd for BorrowedFd<'_> { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl AsRawFd for OwnedFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl IntoRawFd for OwnedFd { - #[inline] - fn into_raw_fd(self) -> RawFd { - let fd = self.fd; - forget(self); - fd - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl FromRawFd for OwnedFd { - /// Constructs a new instance of `Self` from the given raw file descriptor. - /// - /// # Safety - /// - /// The resource pointed to by `fd` must be open and suitable for assuming - /// [ownership][io-safety]. The resource must not require any cleanup other than `close`. - /// - /// [io-safety]: io#io-safety - #[inline] - unsafe fn from_raw_fd(fd: RawFd) -> Self { - assert_ne!(fd, u32::MAX as RawFd); - // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - #[allow(unused_unsafe)] - unsafe { - Self { fd } - } - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl Drop for OwnedFd { - #[inline] - fn drop(&mut self) { - unsafe { - // Errors are ignored when closing a file descriptor. The reason - // for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file - // descriptor opened after we closed ours. - close(self.fd as _); - } - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl fmt::Debug for BorrowedFd<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("BorrowedFd").field("fd", &self.fd).finish() - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl fmt::Debug for OwnedFd { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OwnedFd").field("fd", &self.fd).finish() - } -} - -/// A trait to borrow the file descriptor from an underlying object. -/// -/// This is only available on unix platforms and must be imported in order to -/// call the method. Windows platforms have a corresponding `AsHandle` and -/// `AsSocket` set of traits. -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -pub trait AsFd { - /// Borrows the file descriptor. - /// - /// # Example - /// - /// ```no_run - /// # #![feature(io_safety)] - /// use std::fs::File; - /// # use std::io; - /// # #[cfg(target_os = "wasi")] - /// # use std::os::wasi::io::{AsFd, BorrowedFd}; - /// # #[cfg(unix)] - /// # use std::os::unix::io::{AsFd, BorrowedFd}; - /// - /// let mut f = File::open("foo.txt")?; - /// # #[cfg(any(unix, target_os = "wasi"))] - /// let borrowed_fd: BorrowedFd<'_> = f.as_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] - fn as_fd(&self) -> BorrowedFd<'_>; -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl<T: AsFd> AsFd for &T { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - T::as_fd(self) - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl<T: AsFd> AsFd for &mut T { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - T::as_fd(self) - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl AsFd for BorrowedFd<'_> { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - *self - } -} - -#[cfg_attr(staged_api, unstable(feature = "io_safety", issue = "87074"))] -impl AsFd for OwnedFd { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - // SAFETY: `OwnedFd` and `BorrowedFd` have the same validity - // invariants, and the `BorrowedFd` is bounded by the lifetime - // of `&self`. - unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } - } -} diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs deleted file mode 100644 index 8f6b75ae..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/fd/raw.rs +++ /dev/null @@ -1,164 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/os/fd/raw.rs at revision -//! 334a54cd83191f38ad8046ed94c45de735c86c65. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. -//! -//! Raw Unix-like file descriptors. - -#![cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -#![allow(unsafe_code)] - -use crate::backend::c; - -/// Raw file descriptors. -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub type RawFd = c::c_int; - -/// A trait to extract the raw file descriptor from an underlying object. -/// -/// This is only available on unix and WASI platforms and must be imported in -/// order to call the method. Windows platforms have a corresponding -/// `AsRawHandle` and `AsRawSocket` set of traits. -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub trait AsRawFd { - /// Extracts the raw file descriptor. - /// - /// This function is typically used to **borrow** an owned file descriptor. - /// When used in this way, this method does **not** pass ownership of the - /// raw file descriptor to the caller, and the file descriptor is only - /// guaranteed to be valid while the original object has not yet been - /// destroyed. - /// - /// However, borrowing is not strictly required. See [`AsFd::as_fd`] - /// for an API which strictly borrows a file descriptor. - /// - /// # Example - /// - /// ```no_run - /// use std::fs::File; - /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{AsRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{AsRawFd, RawFd}; - /// - /// let mut f = File::open("foo.txt")?; - /// // `raw_fd` is only valid as long as `f` exists. - /// #[cfg(any(unix, target_os = "wasi"))] - /// let raw_fd: RawFd = f.as_raw_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - fn as_raw_fd(&self) -> RawFd; -} - -/// A trait to express the ability to construct an object from a raw file -/// descriptor. -#[cfg_attr(staged_api, stable(feature = "from_raw_os", since = "1.1.0"))] -pub trait FromRawFd { - /// Constructs a new instance of `Self` from the given raw file - /// descriptor. - /// - /// This function is typically used to **consume ownership** of the - /// specified file descriptor. When used in this way, the returned object - /// will take responsibility for closing it when the object goes out of - /// scope. - /// - /// However, consuming ownership is not strictly required. Use a - /// [`From<OwnedFd>::from`] implementation for an API which strictly - /// consumes ownership. - /// - /// # Safety - /// - /// The `fd` passed in must be an [owned file descriptor][io-safety]; - /// in particular, it must be open. - /// - /// [io-safety]: io#io-safety - /// - /// # Example - /// - /// ```no_run - /// use std::fs::File; - /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd}; - /// - /// let f = File::open("foo.txt")?; - /// # #[cfg(any(unix, target_os = "wasi"))] - /// let raw_fd: RawFd = f.into_raw_fd(); - /// // SAFETY: no other functions should call `from_raw_fd`, so there - /// // is only one owner for the file descriptor. - /// # #[cfg(any(unix, target_os = "wasi"))] - /// let f = unsafe { File::from_raw_fd(raw_fd) }; - /// # Ok::<(), io::Error>(()) - /// ``` - #[cfg_attr(staged_api, stable(feature = "from_raw_os", since = "1.1.0"))] - unsafe fn from_raw_fd(fd: RawFd) -> Self; -} - -/// A trait to express the ability to consume an object and acquire ownership of -/// its raw file descriptor. -#[cfg_attr(staged_api, stable(feature = "into_raw_os", since = "1.4.0"))] -pub trait IntoRawFd { - /// Consumes this object, returning the raw underlying file descriptor. - /// - /// This function is typically used to **transfer ownership** of the underlying - /// file descriptor to the caller. When used in this way, callers are then the unique - /// owners of the file descriptor and must close it once it's no longer needed. - /// - /// However, transferring ownership is not strictly required. Use a - /// [`Into<OwnedFd>::into`] implementation for an API which strictly - /// transfers ownership. - /// - /// # Example - /// - /// ```no_run - /// use std::fs::File; - /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{IntoRawFd, RawFd}; - /// - /// let f = File::open("foo.txt")?; - /// #[cfg(any(unix, target_os = "wasi"))] - /// let raw_fd: RawFd = f.into_raw_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[cfg_attr(staged_api, stable(feature = "into_raw_os", since = "1.4.0"))] - fn into_raw_fd(self) -> RawFd; -} - -#[cfg_attr( - staged_api, - stable(feature = "raw_fd_reflexive_traits", since = "1.48.0") -)] -impl AsRawFd for RawFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - *self - } -} -#[cfg_attr( - staged_api, - stable(feature = "raw_fd_reflexive_traits", since = "1.48.0") -)] -impl IntoRawFd for RawFd { - #[inline] - fn into_raw_fd(self) -> RawFd { - self - } -} -#[cfg_attr( - staged_api, - stable(feature = "raw_fd_reflexive_traits", since = "1.48.0") -)] -impl FromRawFd for RawFd { - #[inline] - unsafe fn from_raw_fd(fd: RawFd) -> RawFd { - fd - } -} diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/mod.rs deleted file mode 100644 index 67f41f5b..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[cfg(any(unix, target_os = "wasi"))] -pub mod fd; -#[cfg(windows)] -pub mod windows; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/mod.rs deleted file mode 100644 index 77abd03c..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod raw; -mod socket; - -pub use raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; -pub use socket::{AsSocket, BorrowedSocket, OwnedSocket}; diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/raw.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/raw.rs deleted file mode 100644 index 63edf7f6..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/raw.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/os/windows/io/raw.rs -//! at revision -//! 4f9b394c8a24803e57ba892fa00e539742ebafc0. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. - -use super::super::raw; - -/// Raw SOCKETs. -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub type RawSocket = raw::SOCKET; - -/// Extracts raw sockets. -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -pub trait AsRawSocket { - /// Extracts the raw socket. - /// - /// This function is typically used to **borrow** an owned socket. - /// When used in this way, this method does **not** pass ownership of the - /// raw socket to the caller, and the socket is only guaranteed - /// to be valid while the original object has not yet been destroyed. - /// - /// However, borrowing is not strictly required. See [`AsSocket::as_socket`] - /// for an API which strictly borrows a socket. - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] - fn as_raw_socket(&self) -> RawSocket; -} - -/// Creates I/O objects from raw sockets. -#[cfg_attr(staged_api, stable(feature = "from_raw_os", since = "1.1.0"))] -pub trait FromRawSocket { - /// Constructs a new I/O object from the specified raw socket. - /// - /// This function is typically used to **consume ownership** of the socket - /// given, passing responsibility for closing the socket to the returned - /// object. When used in this way, the returned object - /// will take responsibility for closing it when the object goes out of - /// scope. - /// - /// However, consuming ownership is not strictly required. Use a - /// `From<OwnedSocket>::from` implementation for an API which strictly - /// consumes ownership. - /// - /// # Safety - /// - /// The `socket` passed in must: - /// - be an [owned socket][io-safety]; in particular, it must be open. - /// - be a socket that may be freed via [`closesocket`]. - /// - /// [`closesocket`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-closesocket - /// [io-safety]: io#io-safety - #[cfg_attr(staged_api, stable(feature = "from_raw_os", since = "1.1.0"))] - unsafe fn from_raw_socket(sock: RawSocket) -> Self; -} - -/// A trait to express the ability to consume an object and acquire ownership of -/// its raw `SOCKET`. -#[cfg_attr(staged_api, stable(feature = "into_raw_os", since = "1.4.0"))] -pub trait IntoRawSocket { - /// Consumes this object, returning the raw underlying socket. - /// - /// This function is typically used to **transfer ownership** of the underlying - /// socket to the caller. When used in this way, callers are then the unique - /// owners of the socket and must close it once it's no longer needed. - /// - /// However, transferring ownership is not strictly required. Use a - /// `Into<OwnedSocket>::into` implementation for an API which strictly - /// transfers ownership. - #[cfg_attr(staged_api, stable(feature = "into_raw_os", since = "1.4.0"))] - fn into_raw_socket(self) -> RawSocket; -} diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/socket.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/socket.rs deleted file mode 100644 index 87692b37..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/io/socket.rs +++ /dev/null @@ -1,198 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/os/windows/io/socket.rs -//! at revision -//! 4f9b394c8a24803e57ba892fa00e539742ebafc0. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. - -use super::raw::*; -use crate::backend::c; -use core::fmt; -use core::marker::PhantomData; -use core::mem::forget; - -/// A borrowed socket. -/// -/// This has a lifetime parameter to tie it to the lifetime of something that -/// owns the socket. -/// -/// This uses `repr(transparent)` and has the representation of a host socket, -/// so it can be used in FFI in places where a socket is passed as an argument, -/// it is not captured or consumed, and it never has the value -/// `INVALID_SOCKET`. -/// -/// This type's `.to_owned()` implementation returns another `BorrowedSocket` -/// rather than an `OwnedSocket`. It just makes a trivial copy of the raw -/// socket, which is then borrowed under the same lifetime. -#[derive(Copy, Clone)] -#[repr(transparent)] -#[cfg_attr(staged_api, rustc_layout_scalar_valid_range_start(0))] -// This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr( - all(staged_api, target_pointer_width = "32"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE) -)] -#[cfg_attr( - all(staged_api, target_pointer_width = "64"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) -)] -#[cfg_attr(staged_api, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -pub struct BorrowedSocket<'socket> { - socket: RawSocket, - _phantom: PhantomData<&'socket OwnedSocket>, -} - -/// An owned socket. -/// -/// This closes the socket on drop. -/// -/// This uses `repr(transparent)` and has the representation of a host socket, -/// so it can be used in FFI in places where a socket is passed as a consumed -/// argument or returned as an owned value, and it never has the value -/// `INVALID_SOCKET`. -#[repr(transparent)] -#[cfg_attr(staged_api, rustc_layout_scalar_valid_range_start(0))] -// This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr( - all(staged_api, target_pointer_width = "32"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE) -)] -#[cfg_attr( - all(staged_api, target_pointer_width = "64"), - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) -)] -#[cfg_attr(staged_api, rustc_nonnull_optimization_guaranteed)] -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -pub struct OwnedSocket { - socket: RawSocket, -} - -impl BorrowedSocket<'_> { - /// Returns a `BorrowedSocket` holding the given raw socket. - /// - /// # Safety - /// - /// The resource pointed to by `raw` must remain open for the duration of - /// the returned `BorrowedSocket`, and it must not have the value - /// `INVALID_SOCKET`. - #[inline] - #[cfg_attr( - staged_api, - rustc_const_stable(feature = "io_safety", since = "1.63.0") - )] - #[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] - pub const unsafe fn borrow_raw(socket: RawSocket) -> Self { - assert!(socket != c::INVALID_SOCKET as RawSocket); - Self { - socket, - _phantom: PhantomData, - } - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl AsRawSocket for BorrowedSocket<'_> { - #[inline] - fn as_raw_socket(&self) -> RawSocket { - self.socket - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl AsRawSocket for OwnedSocket { - #[inline] - fn as_raw_socket(&self) -> RawSocket { - self.socket - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl IntoRawSocket for OwnedSocket { - #[inline] - fn into_raw_socket(self) -> RawSocket { - let socket = self.socket; - forget(self); - socket - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl FromRawSocket for OwnedSocket { - #[inline] - unsafe fn from_raw_socket(socket: RawSocket) -> Self { - debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket); - Self { socket } - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl Drop for OwnedSocket { - #[inline] - fn drop(&mut self) { - unsafe { - let _ = c::closesocket(self.socket as c::SOCKET); - } - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl fmt::Debug for BorrowedSocket<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("BorrowedSocket") - .field("socket", &self.socket) - .finish() - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl fmt::Debug for OwnedSocket { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OwnedSocket") - .field("socket", &self.socket) - .finish() - } -} - -/// A trait to borrow the socket from an underlying object. -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -pub trait AsSocket { - /// Borrows the socket. - #[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] - fn as_socket(&self) -> BorrowedSocket<'_>; -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl<T: AsSocket> AsSocket for &T { - #[inline] - fn as_socket(&self) -> BorrowedSocket<'_> { - T::as_socket(self) - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl<T: AsSocket> AsSocket for &mut T { - #[inline] - fn as_socket(&self) -> BorrowedSocket<'_> { - T::as_socket(self) - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl AsSocket for BorrowedSocket<'_> { - #[inline] - fn as_socket(&self) -> BorrowedSocket<'_> { - *self - } -} - -#[cfg_attr(staged_api, stable(feature = "io_safety", since = "1.63.0"))] -impl AsSocket for OwnedSocket { - #[inline] - fn as_socket(&self) -> BorrowedSocket<'_> { - // Safety: `OwnedSocket` and `BorrowedSocket` have the same validity - // invariants, and the `BorrowdSocket` is bounded by the lifetime - // of `&self`. - unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } - } -} diff --git a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/mod.rs b/vendor/rustix/src/maybe_polyfill/no_std/os/windows/mod.rs deleted file mode 100644 index 02f38949..00000000 --- a/vendor/rustix/src/maybe_polyfill/no_std/os/windows/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/os/windows/raw.rs, -//! library/std/src/os/windows/io/raw.rs and -//! library/std/src/os/windows/io/socket.rs -//! at revision -//! 4f9b394c8a24803e57ba892fa00e539742ebafc0. -//! -//! All code in this file is licensed MIT or Apache 2.0 at your option. - -mod raw { - #[cfg(target_pointer_width = "32")] - #[cfg_attr(staged_api, stable(feature = "raw_ext", since = "1.1.0"))] - pub type SOCKET = u32; - #[cfg(target_pointer_width = "64")] - #[cfg_attr(staged_api, stable(feature = "raw_ext", since = "1.1.0"))] - pub type SOCKET = u64; -} - -pub mod io; diff --git a/vendor/rustix/src/maybe_polyfill/std/mod.rs b/vendor/rustix/src/maybe_polyfill/std/mod.rs deleted file mode 100644 index 17b28095..00000000 --- a/vendor/rustix/src/maybe_polyfill/std/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Imports from `std` that would be polyfilled for `no_std` builds (see -//! `src/polyfill/no_std`). -//! -//! This implementation is used when `std` is available and just imports the -//! necessary items from `std`. For `no_std` builds, the file -//! `src/polyfill/no_std` is used instead, which doesn't depend on the standard -//! library. - -#[cfg(not(windows))] -pub mod io { - pub use std::io::{IoSlice, IoSliceMut}; -} - -#[cfg(not(target_os = "wasi"))] -#[cfg(feature = "net")] -pub mod net { - pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; -} - -pub mod os { - pub mod fd { - // Change to use `std::os::fd` when MSRV becomes Rust 1.66 or higher. - - #[cfg(target_os = "wasi")] - pub use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; - #[cfg(unix)] - pub use std::os::unix::io::{ - AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd, - }; - } - - #[cfg(windows)] - pub mod windows { - pub mod io { - pub use std::os::windows::io::{ - AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, - RawSocket, - }; - } - } -} diff --git a/vendor/rustix/src/mm/madvise.rs b/vendor/rustix/src/mm/madvise.rs deleted file mode 100644 index 4ab910e8..00000000 --- a/vendor/rustix/src/mm/madvise.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! The `madvise` function. -//! -//! # Safety -//! -//! `madvise` operates on a raw pointer. Some forms of `madvise` may -//! mutate the memory or have other side effects. -#![allow(unsafe_code)] - -use crate::{backend, io}; -use core::ffi::c_void; - -pub use backend::mm::types::Advice; - -/// `posix_madvise(addr, len, advice)`—Declares an expected access pattern -/// for a memory-mapped file. -/// -/// # Safety -/// -/// `addr` must be a valid pointer to memory that is appropriate to call -/// `posix_madvise` on. Some forms of `advice` may mutate the memory or evoke a -/// variety of side-effects on the mapping and/or the file. -/// -/// # References -/// - [POSIX] -/// - [Linux `madvise`] -/// - [Linux `posix_madvise`] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_madvise.html -/// [Linux `madvise`]: https://man7.org/linux/man-pages/man2/madvise.2.html -/// [Linux `posix_madvise`]: https://man7.org/linux/man-pages/man3/posix_madvise.3.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/madvise.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=madvise&sektion=2 -/// [NetBSD]: https://man.netbsd.org/madvise.2 -/// [OpenBSD]: https://man.openbsd.org/madvise.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=madvise§ion=2 -/// [illumos]: https://illumos.org/man/3C/madvise -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Memory_002dmapped-I_002fO.html#index-madvise -#[inline] -#[doc(alias = "posix_madvise")] -pub unsafe fn madvise(addr: *mut c_void, len: usize, advice: Advice) -> io::Result<()> { - backend::mm::syscalls::madvise(addr, len, advice) -} diff --git a/vendor/rustix/src/mm/mmap.rs b/vendor/rustix/src/mm/mmap.rs deleted file mode 100644 index ec5a6d7c..00000000 --- a/vendor/rustix/src/mm/mmap.rs +++ /dev/null @@ -1,443 +0,0 @@ -//! The `mmap` API. -//! -//! # Safety -//! -//! `mmap` and related functions manipulate raw pointers and have special -//! semantics. -#![allow(unsafe_code)] - -use crate::{backend, io}; -use backend::fd::AsFd; -use core::ffi::c_void; - -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -pub use backend::mm::types::MlockAllFlags; -#[cfg(linux_kernel)] -pub use backend::mm::types::MlockFlags; -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -pub use backend::mm::types::MremapFlags; -pub use backend::mm::types::{MapFlags, MprotectFlags, ProtFlags}; - -impl MapFlags { - /// Create `MAP_HUGETLB` with provided size of huge page. - /// - /// Under the hood it computes - /// `MAP_HUGETLB | (huge_page_size_log2 << MAP_HUGE_SHIFT)`. - /// `huge_page_size_log2` denotes logarithm of huge page size to use and - /// should be between 16 and 63 (inclusive). - /// - /// ``` - /// use rustix::mm::MapFlags; - /// - /// let f = MapFlags::hugetlb_with_size_log2(30).unwrap(); - /// assert_eq!(f, MapFlags::HUGETLB | MapFlags::HUGE_1GB); - /// ``` - #[cfg(linux_kernel)] - pub const fn hugetlb_with_size_log2(huge_page_size_log2: u32) -> Option<Self> { - use crate::backend::c; - if 16 <= huge_page_size_log2 && huge_page_size_log2 <= 63 { - let bits = bitcast!(c::MAP_HUGETLB) | (huge_page_size_log2 << c::MAP_HUGE_SHIFT); - Self::from_bits(bits) - } else { - None - } - } -} - -/// `mmap(ptr, len, prot, flags, fd, offset)`—Create a file-backed memory -/// mapping. -/// -/// For anonymous mappings (`MAP_ANON`/`MAP_ANONYMOUS`), see -/// [`mmap_anonymous`]. -/// -/// # Safety -/// -/// If `ptr` is not null, it must be aligned to the applicable page size, and -/// the range of memory starting at `ptr` and extending for `len` bytes, -/// rounded up to the applicable page size, must be valid to mutate using -/// `ptr`'s provenance. -/// -/// If there exist any Rust references referring to the memory region, or if -/// you subsequently create a Rust reference referring to the resulting region, -/// it is your responsibility to ensure that the Rust reference invariants are -/// preserved, including ensuring that the memory is not mutated in a way that -/// a Rust reference would not expect. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mmap.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mmap.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mmap.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mmap&sektion=2 -/// [NetBSD]: https://man.netbsd.org/mmap.2 -/// [OpenBSD]: https://man.openbsd.org/mmap.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mmap§ion=2 -/// [illumos]: https://illumos.org/man/2/mmap -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Memory_002dmapped-I_002fO.html#index-mmap -#[inline] -pub unsafe fn mmap<Fd: AsFd>( - ptr: *mut c_void, - len: usize, - prot: ProtFlags, - flags: MapFlags, - fd: Fd, - offset: u64, -) -> io::Result<*mut c_void> { - backend::mm::syscalls::mmap(ptr, len, prot, flags, fd.as_fd(), offset) -} - -/// `mmap(ptr, len, prot, MAP_ANONYMOUS | flags, -1, 0)`—Create an anonymous -/// memory mapping. -/// -/// For file-backed mappings, see [`mmap`]. -/// -/// # Safety -/// -/// If `ptr` is not null, it must be aligned to the applicable page size, and -/// the range of memory starting at `ptr` and extending for `len` bytes, -/// rounded up to the applicable page size, must be valid to mutate with -/// `ptr`'s provenance. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mmap.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mmap.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mmap.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mmap&sektion=2 -/// [NetBSD]: https://man.netbsd.org/mmap.2 -/// [OpenBSD]: https://man.openbsd.org/mmap.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mmap§ion=2 -/// [illumos]: https://illumos.org/man/2/mmap -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Memory_002dmapped-I_002fO.html#index-mmap -#[inline] -#[doc(alias = "mmap")] -pub unsafe fn mmap_anonymous( - ptr: *mut c_void, - len: usize, - prot: ProtFlags, - flags: MapFlags, -) -> io::Result<*mut c_void> { - backend::mm::syscalls::mmap_anonymous(ptr, len, prot, flags) -} - -/// `munmap(ptr, len)`—Remove a memory mapping. -/// -/// # Safety -/// -/// `ptr` must be aligned to the applicable page size, and the range of memory -/// starting at `ptr` and extending for `len` bytes, rounded up to the -/// applicable page size, must be valid to mutate with `ptr`'s provenance. And -/// there must be no Rust references referring to that memory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/munmap.html -/// [Linux]: https://man7.org/linux/man-pages/man2/munmap.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/munmap.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=munmap&sektion=2 -/// [NetBSD]: https://man.netbsd.org/munmap.2 -/// [OpenBSD]: https://man.openbsd.org/munmap.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=munmap§ion=2 -/// [illumos]: https://illumos.org/man/2/munmap -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Memory_002dmapped-I_002fO.html#index-munmap -#[inline] -pub unsafe fn munmap(ptr: *mut c_void, len: usize) -> io::Result<()> { - backend::mm::syscalls::munmap(ptr, len) -} - -/// `mremap(old_address, old_size, new_size, flags)`—Resize, modify, and/or -/// move a memory mapping. -/// -/// For moving a mapping to a fixed address (`MREMAP_FIXED`), see -/// [`mremap_fixed`]. -/// -/// # Safety -/// -/// `old_address` must be aligned to the applicable page size, and the range of -/// memory starting at `old_address` and extending for `old_size` bytes, -/// rounded up to the applicable page size, must be valid to mutate with -/// `old_address`'s provenance. If `MremapFlags::MAY_MOVE` is set in `flags`, -/// there must be no Rust references referring to that the memory. -/// -/// If `new_size` is less than `old_size`, than there must be no Rust -/// references referring to the memory starting at offset `new_size` and ending -/// at `old_size`. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mremap.2.html -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -#[inline] -pub unsafe fn mremap( - old_address: *mut c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, -) -> io::Result<*mut c_void> { - backend::mm::syscalls::mremap(old_address, old_size, new_size, flags) -} - -/// `mremap(old_address, old_size, new_size, MREMAP_FIXED | flags)`—Resize, -/// modify, and/or move a memory mapping to a specific address. -/// -/// For `mremap` without moving to a specific address, see [`mremap`]. -/// [`mremap_fixed`]. -/// -/// # Safety -/// -/// `old_address` and `new_address` must be aligned to the applicable page -/// size, the range of memory starting at `old_address` and extending for -/// `old_size` bytes, rounded up to the applicable page size, must be valid to -/// mutate with `old_address`'s provenance, and the range of memory starting at -/// `new_address` and extending for `new_size` bytes, rounded up to the -/// applicable page size, must be valid to mutate with `new_address`'s -/// provenance. -/// -/// There must be no Rust references referring to either of those memory -/// regions. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mremap.2.html -#[cfg(any(target_os = "emscripten", target_os = "linux"))] -#[inline] -#[doc(alias = "mremap")] -pub unsafe fn mremap_fixed( - old_address: *mut c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, - new_address: *mut c_void, -) -> io::Result<*mut c_void> { - backend::mm::syscalls::mremap_fixed(old_address, old_size, new_size, flags, new_address) -} - -/// `mprotect(ptr, len, flags)`—Change the protection flags of a region of -/// memory. -/// -/// # Safety -/// -/// The range of memory starting at `ptr` and extending for `len` bytes, -/// rounded up to the applicable page size, must be valid to read with `ptr`'s -/// provenance. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mprotect.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mprotect.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mprotect.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mprotect&sektion=2 -/// [NetBSD]: https://man.netbsd.org/mprotect.2 -/// [OpenBSD]: https://man.openbsd.org/mprotect.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mprotect§ion=2 -/// [illumos]: https://illumos.org/man/2/mprotect -#[inline] -pub unsafe fn mprotect(ptr: *mut c_void, len: usize, flags: MprotectFlags) -> io::Result<()> { - backend::mm::syscalls::mprotect(ptr, len, flags) -} - -/// `mlock(ptr, len)`—Lock memory into RAM. -/// -/// Some implementations implicitly round the memory region out to the nearest -/// page boundaries, so this function may lock more memory than explicitly -/// requested if the memory isn't page-aligned. Other implementations fail if -/// the memory isn't page-aligned. -/// -/// See [`mlock_with`] to pass additional flags. -/// -/// # Safety -/// -/// The range of memory starting at `ptr`, rounded down to the applicable page -/// boundary, and extending for `len` bytes, rounded up to the applicable page -/// size, must be valid to read with `ptr`'s provenance. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlock.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mlock.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mlock.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mlock&sektion=2 -/// [NetBSD]: https://man.netbsd.org/mlock.2 -/// [OpenBSD]: https://man.openbsd.org/mlock.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mlock§ion=2 -/// [illumos]: https://illumos.org/man/3C/mlock -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Page-Lock-Functions.html#index-mlock -#[inline] -pub unsafe fn mlock(ptr: *mut c_void, len: usize) -> io::Result<()> { - backend::mm::syscalls::mlock(ptr, len) -} - -/// `mlock2(ptr, len, flags)`—Lock memory into RAM, with flags. -/// -/// `mlock_with` is the same as [`mlock`] but adds an additional flags operand. -/// -/// Some implementations implicitly round the memory region out to the nearest -/// page boundaries, so this function may lock more memory than explicitly -/// requested if the memory isn't page-aligned. -/// -/// # Safety -/// -/// The range of memory starting at `ptr`, rounded down to the applicable page -/// boundary, and extending for `len` bytes, rounded up to the applicable page -/// size, must be valid to read with `ptr`'s provenance. -/// -/// # References -/// - [Linux] -/// - [glibc] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mlock2.2.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Page-Lock-Functions.html#index-mlock2 -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "mlock2")] -pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io::Result<()> { - backend::mm::syscalls::mlock_with(ptr, len, flags) -} - -/// `munlock(ptr, len)`—Unlock memory. -/// -/// Some implementations implicitly round the memory region out to the nearest -/// page boundaries, so this function may unlock more memory than explicitly -/// requested if the memory isn't page-aligned. -/// -/// # Safety -/// -/// The range of memory starting at `ptr`, rounded down to the applicable page -/// boundary, and extending for `len` bytes, rounded up to the applicable page -/// size, must be valid to read with `ptr`'s provenance. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/munlock.html -/// [Linux]: https://man7.org/linux/man-pages/man2/munlock.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/munlock.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=munlock&sektion=2 -/// [NetBSD]: https://man.netbsd.org/munlock.2 -/// [OpenBSD]: https://man.openbsd.org/munlock.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=munlock§ion=2 -/// [illumos]: https://illumos.org/man/3C/munlock -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Page-Lock-Functions.html#index-munlock -#[inline] -pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> { - backend::mm::syscalls::munlock(ptr, len) -} - -/// Locks all pages mapped into the address space of the calling process. -/// -/// This includes the pages of the code, data, and stack segment, as well as -/// shared libraries, user space kernel data, shared memory, and memory-mapped -/// files. All mapped pages are guaranteed to be resident in RAM when the call -/// returns successfully; the pages are guaranteed to stay in RAM until later -/// unlocked. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlockall.html -/// [Linux]: https://man7.org/linux/man-pages/man2/mlockall.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mlockall&sektion=2 -/// [NetBSD]: https://man.netbsd.org/mlockall.2 -/// [OpenBSD]: https://man.openbsd.org/mlockall.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=mlockall§ion=2 -/// [illumos]: https://illumos.org/man/3C/mlockall -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Page-Lock-Functions.html#index-mlockall -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -#[inline] -pub fn mlockall(flags: MlockAllFlags) -> io::Result<()> { - backend::mm::syscalls::mlockall(flags) -} - -/// Unlocks all pages mapped into the address space of the calling process. -/// -/// # Warning -/// -/// This function is aware of all the memory pages in the process, as if it -/// were a debugger. It unlocks all the pages, which could potentially -/// compromise security assumptions made by code about memory it has -/// encapsulated. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/munlockall.html -/// [Linux]: https://man7.org/linux/man-pages/man2/munlockall.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=munlockall&sektion=2 -/// [NetBSD]: https://man.netbsd.org/munlockall.2 -/// [OpenBSD]: https://man.openbsd.org/munlockall.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=munlockall§ion=2 -/// [illumos]: https://illumos.org/man/3C/munlockall -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Page-Lock-Functions.html#index-munlockall -#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] -#[inline] -pub fn munlockall() -> io::Result<()> { - backend::mm::syscalls::munlockall() -} diff --git a/vendor/rustix/src/mm/mod.rs b/vendor/rustix/src/mm/mod.rs deleted file mode 100644 index 7505cac0..00000000 --- a/vendor/rustix/src/mm/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! Memory map operations. - -#[cfg(not(target_os = "redox"))] -mod madvise; -mod mmap; -mod msync; -#[cfg(linux_kernel)] -mod userfaultfd; - -#[cfg(not(target_os = "redox"))] -pub use madvise::{madvise, Advice}; -pub use mmap::*; -pub use msync::{msync, MsyncFlags}; -#[cfg(linux_kernel)] -pub use userfaultfd::{userfaultfd, UserfaultfdFlags}; diff --git a/vendor/rustix/src/mm/msync.rs b/vendor/rustix/src/mm/msync.rs deleted file mode 100644 index c6723436..00000000 --- a/vendor/rustix/src/mm/msync.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! The `msync` function. -//! -//! # Safety -//! -//! `msync` operates on a raw pointer. Some forms of `msync` may mutate the -//! memory or have other side effects. -#![allow(unsafe_code)] - -use crate::{backend, io}; -use core::ffi::c_void; - -pub use backend::mm::types::MsyncFlags; - -/// `msync(addr, len, flags)`—Synchronizes a memory-mapping with its backing -/// storage. -/// -/// # Safety -/// -/// `addr` must be a valid pointer to memory that is appropriate to call -/// `msync` on. Some forms of `msync` may mutate the memory or evoke a variety -/// of side-effects on the mapping and/or the file. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/msync.html -/// [Linux]: https://man7.org/linux/man-pages/man2/msync.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/msync.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=msync&sektion=2 -/// [NetBSD]: https://man.netbsd.org/msync.2 -/// [OpenBSD]: https://man.openbsd.org/msync.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=msync§ion=2 -/// [illumos]: https://illumos.org/man/3C/msync -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Memory_002dmapped-I_002fO.html#index-msync -#[inline] -pub unsafe fn msync(addr: *mut c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - backend::mm::syscalls::msync(addr, len, flags) -} diff --git a/vendor/rustix/src/mm/userfaultfd.rs b/vendor/rustix/src/mm/userfaultfd.rs deleted file mode 100644 index 46ab07eb..00000000 --- a/vendor/rustix/src/mm/userfaultfd.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! The Linux `userfaultfd` API. -//! -//! # Safety -//! -//! Calling `userfaultfd` is safe, but the returned file descriptor lets users -//! observe and manipulate process memory in magical ways. -#![allow(unsafe_code)] - -use crate::fd::OwnedFd; -use crate::{backend, io}; - -pub use backend::mm::types::UserfaultfdFlags; - -/// `userfaultfd(flags)`—Create userspace page-fault handler. -/// -/// # Safety -/// -/// The call itself is safe, but the returned file descriptor lets users -/// observe and manipulate process memory in magical ways. -/// -/// # References -/// - [Linux] -/// - [Linux userfaultfd] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/userfaultfd.2.html -/// [Linux userfaultfd]: https://www.kernel.org/doc/Documentation/vm/userfaultfd.txt -#[inline] -pub unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { - backend::mm::syscalls::userfaultfd(flags) -} diff --git a/vendor/rustix/src/mount/fsopen.rs b/vendor/rustix/src/mount/fsopen.rs deleted file mode 100644 index bd4b7be8..00000000 --- a/vendor/rustix/src/mount/fsopen.rs +++ /dev/null @@ -1,233 +0,0 @@ -//! `fsopen` and related functions in Linux's `mount` API. - -use crate::backend::mount::types::{ - FsMountFlags, FsOpenFlags, FsPickFlags, MountAttrFlags, MoveMountFlags, OpenTreeFlags, -}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::{backend, io, path}; - -/// `fsopen(fs_name, flags)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsopen.md -#[inline] -pub fn fsopen<Fs: path::Arg>(fs_name: Fs, flags: FsOpenFlags) -> io::Result<OwnedFd> { - fs_name.into_with_c_str(|fs_name| backend::mount::syscalls::fsopen(fs_name, flags)) -} - -/// `fsmount(fs_fd, flags, attr_flags)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsmount.md -#[inline] -pub fn fsmount( - fs_fd: BorrowedFd<'_>, - flags: FsMountFlags, - attr_flags: MountAttrFlags, -) -> io::Result<OwnedFd> { - backend::mount::syscalls::fsmount(fs_fd, flags, attr_flags) -} - -/// `move_mount(from_dfd, from_pathname, to_dfd, to_pathname, flags)` -/// -/// This is not the same as `mount` with the `MS_MOVE` flag. If you want to -/// use that, use [`mount_move`] instead. -/// -/// # References -/// - [Unfinished draft] -/// -/// [`mount_move`]: crate::mount::mount_move -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/move_mount.md -#[inline] -pub fn move_mount<From: path::Arg, To: path::Arg>( - from_dfd: BorrowedFd<'_>, - from_pathname: From, - to_dfd: BorrowedFd<'_>, - to_pathname: To, - flags: MoveMountFlags, -) -> io::Result<()> { - from_pathname.into_with_c_str(|from_pathname| { - to_pathname.into_with_c_str(|to_pathname| { - backend::mount::syscalls::move_mount( - from_dfd, - from_pathname, - to_dfd, - to_pathname, - flags, - ) - }) - }) -} - -/// `open_tree(dfd, filename, flags)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/open_tree.md -#[inline] -pub fn open_tree<Path: path::Arg>( - dfd: BorrowedFd<'_>, - filename: Path, - flags: OpenTreeFlags, -) -> io::Result<OwnedFd> { - filename.into_with_c_str(|filename| backend::mount::syscalls::open_tree(dfd, filename, flags)) -} - -/// `fspick(dfd, path, flags)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fspick.md -#[inline] -pub fn fspick<Path: path::Arg>( - dfd: BorrowedFd<'_>, - path: Path, - flags: FsPickFlags, -) -> io::Result<OwnedFd> { - path.into_with_c_str(|path| backend::mount::syscalls::fspick(dfd, path, flags)) -} - -/// `fsconfig(fs_fd, FSCONFIG_SET_FLAG, key, NULL, 0)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_set_flag<Key: path::Arg>(fs_fd: BorrowedFd<'_>, key: Key) -> io::Result<()> { - key.into_with_c_str(|key| backend::mount::syscalls::fsconfig_set_flag(fs_fd, key)) -} - -/// `fsconfig(fs_fd, FSCONFIG_SET_STRING, key, value, 0)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_set_string<Key: path::Arg, Value: path::Arg>( - fs_fd: BorrowedFd<'_>, - key: Key, - value: Value, -) -> io::Result<()> { - key.into_with_c_str(|key| { - value.into_with_c_str(|value| { - backend::mount::syscalls::fsconfig_set_string(fs_fd, key, value) - }) - }) -} - -/// `fsconfig(fs_fd, FSCONFIG_SET_BINARY, key, value, value.len())` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_set_binary<Key: path::Arg>( - fs_fd: BorrowedFd<'_>, - key: Key, - value: &[u8], -) -> io::Result<()> { - key.into_with_c_str(|key| backend::mount::syscalls::fsconfig_set_binary(fs_fd, key, value)) -} - -/// `fsconfig(fs_fd, FSCONFIG_SET_PATH, key, path, fd)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_set_path<Key: path::Arg, Path: path::Arg>( - fs_fd: BorrowedFd<'_>, - key: Key, - path: Path, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - key.into_with_c_str(|key| { - path.into_with_c_str(|path| { - backend::mount::syscalls::fsconfig_set_path(fs_fd, key, path, fd) - }) - }) -} - -/// `fsconfig(fs_fd, FSCONFIG_SET_PATH_EMPTY, key, "", fd)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_set_path_empty<Key: path::Arg>( - fs_fd: BorrowedFd<'_>, - key: Key, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - key.into_with_c_str(|key| backend::mount::syscalls::fsconfig_set_path_empty(fs_fd, key, fd)) -} - -/// `fsconfig(fs_fd, FSCONFIG_SET_FD, key, NULL, fd)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_set_fd<Key: path::Arg>( - fs_fd: BorrowedFd<'_>, - key: Key, - fd: BorrowedFd<'_>, -) -> io::Result<()> { - key.into_with_c_str(|key| backend::mount::syscalls::fsconfig_set_fd(fs_fd, key, fd)) -} - -/// `fsconfig(fs_fd, FSCONFIG_CMD_CREATE, key, NULL, 0)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_create(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - backend::mount::syscalls::fsconfig_create(fs_fd) -} - -/// `fsconfig(fs_fd, FSCONFIG_CMD_RECONFIGURE, key, NULL, 0)` -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_reconfigure(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - backend::mount::syscalls::fsconfig_reconfigure(fs_fd) -} - -/// `fsconfig(fs_fd, FSCONFIG_CMD_CREATE_EXCL, key, NULL, 0)` -/// -/// This function was added in Linux 6.6. -/// -/// # References -/// - [Unfinished draft] -/// -/// [Unfinished draft]: https://github.com/sunfishcode/linux-mount-api-documentation/blob/main/fsconfig.md -#[inline] -#[doc(alias = "fsconfig")] -pub fn fsconfig_create_exclusive(fs_fd: BorrowedFd<'_>) -> io::Result<()> { - backend::mount::syscalls::fsconfig_create_excl(fs_fd) -} diff --git a/vendor/rustix/src/mount/mod.rs b/vendor/rustix/src/mount/mod.rs deleted file mode 100644 index 3c133d38..00000000 --- a/vendor/rustix/src/mount/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Linux `mount` API. - -mod fsopen; -mod mount_unmount; -mod types; - -pub use fsopen::*; -pub use mount_unmount::*; -pub use types::*; diff --git a/vendor/rustix/src/mount/mount_unmount.rs b/vendor/rustix/src/mount/mount_unmount.rs deleted file mode 100644 index 6a27845c..00000000 --- a/vendor/rustix/src/mount/mount_unmount.rs +++ /dev/null @@ -1,183 +0,0 @@ -//! Linux `mount`. - -use crate::backend::mount::types::{ - InternalMountFlags, MountFlags, MountFlagsArg, MountPropagationFlags, UnmountFlags, -}; -use crate::ffi::CStr; -use crate::path::{self, option_into_with_c_str}; -use crate::{backend, io}; - -/// `mount(source, target, filesystemtype, mountflags, data)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html -#[inline] -pub fn mount< - 'a, - Source: path::Arg, - Target: path::Arg, - Fs: path::Arg, - Data: Into<Option<&'a CStr>>, ->( - source: Source, - target: Target, - file_system_type: Fs, - flags: MountFlags, - data: Data, -) -> io::Result<()> { - source.into_with_c_str(|source| { - target.into_with_c_str(|target| { - file_system_type.into_with_c_str(|file_system_type| { - option_into_with_c_str(data.into(), |data| { - backend::mount::syscalls::mount( - Some(source), - target, - Some(file_system_type), - MountFlagsArg(flags.bits()), - data, - ) - }) - }) - }) - }) -} - -/// `mount(NULL, target, NULL, MS_REMOUNT | mountflags, data)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html -#[inline] -#[doc(alias = "mount")] -#[doc(alias = "MS_REMOUNT")] -pub fn mount_remount<Target: path::Arg, Data: path::Arg>( - target: Target, - flags: MountFlags, - data: Data, -) -> io::Result<()> { - target.into_with_c_str(|target| { - data.into_with_c_str(|data| { - backend::mount::syscalls::mount( - None, - target, - None, - MountFlagsArg(InternalMountFlags::REMOUNT.bits() | flags.bits()), - Some(data), - ) - }) - }) -} - -/// `mount(source, target, NULL, MS_BIND, NULL)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html -#[inline] -#[doc(alias = "mount")] -#[doc(alias = "MS_BIND")] -pub fn mount_bind<Source: path::Arg, Target: path::Arg>( - source: Source, - target: Target, -) -> io::Result<()> { - source.into_with_c_str(|source| { - target.into_with_c_str(|target| { - backend::mount::syscalls::mount( - Some(source), - target, - None, - MountFlagsArg(MountFlags::BIND.bits()), - None, - ) - }) - }) -} - -/// `mount(source, target, NULL, MS_BIND | MS_REC, NULL)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html -#[inline] -#[doc(alias = "mount")] -#[doc(alias = "MS_REC")] -pub fn mount_bind_recursive<Source: path::Arg, Target: path::Arg>( - source: Source, - target: Target, -) -> io::Result<()> { - source.into_with_c_str(|source| { - target.into_with_c_str(|target| { - backend::mount::syscalls::mount( - Some(source), - target, - None, - MountFlagsArg(MountFlags::BIND.bits() | MountPropagationFlags::REC.bits()), - None, - ) - }) - }) -} - -/// `mount(NULL, target, NULL, mountflags, NULL)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html -#[inline] -#[doc(alias = "mount")] -pub fn mount_change<Target: path::Arg>( - target: Target, - flags: MountPropagationFlags, -) -> io::Result<()> { - target.into_with_c_str(|target| { - backend::mount::syscalls::mount(None, target, None, MountFlagsArg(flags.bits()), None) - }) -} - -/// `mount(source, target, NULL, MS_MOVE, NULL)` -/// -/// This is not the same as the `move_mount` syscall. If you want to use that, -/// use [`move_mount`] instead. -/// -/// # References -/// - [Linux] -/// -/// [`move_mount`]: crate::mount::move_mount -/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html -#[inline] -#[doc(alias = "mount")] -#[doc(alias = "MS_MOVE")] -pub fn mount_move<Source: path::Arg, Target: path::Arg>( - source: Source, - target: Target, -) -> io::Result<()> { - source.into_with_c_str(|source| { - target.into_with_c_str(|target| { - backend::mount::syscalls::mount( - Some(source), - target, - None, - MountFlagsArg(InternalMountFlags::MOVE.bits()), - None, - ) - }) - }) -} - -/// `umount2(target, flags)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/umount.2.html -#[inline] -#[doc(alias = "umount", alias = "umount2")] -pub fn unmount<Target: path::Arg>(target: Target, flags: UnmountFlags) -> io::Result<()> { - target.into_with_c_str(|target| backend::mount::syscalls::unmount(target, flags)) -} diff --git a/vendor/rustix/src/mount/types.rs b/vendor/rustix/src/mount/types.rs deleted file mode 100644 index 6096e76d..00000000 --- a/vendor/rustix/src/mount/types.rs +++ /dev/null @@ -1 +0,0 @@ -pub use crate::backend::mount::types::*; diff --git a/vendor/rustix/src/net/addr.rs b/vendor/rustix/src/net/addr.rs deleted file mode 100644 index 13e5c24f..00000000 --- a/vendor/rustix/src/net/addr.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Types for implementers of socket address types or code that is generic over -//! address types. -//! -//! The concrete address types and [`SocketAddrAny`] are in -//! [the parent module][`super`]. - -#![allow(unsafe_code)] -use core::mem::{size_of, MaybeUninit}; -use core::ptr; - -use crate::backend::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; -use crate::utils::as_ptr; - -use super::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; - -pub use crate::backend::net::addr::SocketAddrStorage; - -#[cfg(unix)] -use super::SocketAddrUnix; - -/// Opaque type equivalent to `sockaddr` in C. -/// -/// This is always used behind a raw pointer that is cast from a pointer to a -/// `sockaddr`-compatible C type, and then cast back to a `sockaddr` pointer to -/// be passed to a system call. -#[repr(C)] -pub struct SocketAddrOpaque { - _data: [u8; 0], -} - -/// A type for the length of a socket address. -/// -/// This type will always be big enough to hold any socket address, but never -/// bigger than `usize`. -#[doc(alias = "socklen_t")] -pub type SocketAddrLen = u32; - -/// A trait abstracting over the types that can be passed as a `sockaddr`. -/// -/// # Safety -/// -/// Implementers of this trait must ensure that `with_sockaddr` calls `f` with -/// a pointer that is readable for the passed length, and points to data that -/// is a valid socket address for the system calls that accept `sockaddr` as a -/// const pointer. -pub unsafe trait SocketAddrArg { - /// Call a closure with the pointer and length to the corresponding C type. - /// - /// The memory pointed to by the pointer of size length is guaranteed to be - /// valid only for the duration of the call. - /// - /// The API uses a closure so that: - /// - The libc types are not exposed in the rustix API. - /// - Types like `SocketAddrUnix` that contain their corresponding C type - /// can pass it directly without a copy. - /// - Other socket types can construct their C-compatible struct on the - /// stack and call the closure with a pointer to it. - /// - /// # Safety - /// - /// For `f` to use its pointer argument, it'll contain an `unsafe` block. - /// The caller of `with_sockaddr` here is responsible for ensuring that the - /// safety condition for that `unsafe` block is satisfied by the guarantee - /// that `with_sockaddr` here provides. - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R; - - /// Convert to `SocketAddrAny`. - fn as_any(&self) -> SocketAddrAny { - let mut storage = MaybeUninit::<SocketAddrStorage>::uninit(); - // SAFETY: We've allocated `storage` here, we're writing to it, and - // we're using the number of bytes written. - unsafe { - let len = self.write_sockaddr(storage.as_mut_ptr()); - SocketAddrAny::new(storage, len) - } - } - - /// Encode an address into a `SocketAddrStorage`. - /// - /// Returns the number of bytes that were written. - /// - /// For a safe interface to this functionality, use [`as_any`]. - /// - /// [`as_any`]: Self::as_any - /// - /// # Safety - /// - /// `storage` must be valid to write up to `size_of<SocketAddrStorage>()` - /// bytes to. - unsafe fn write_sockaddr(&self, storage: *mut SocketAddrStorage) -> SocketAddrLen { - // The closure dereferences exactly `len` bytes at `ptr`. - self.with_sockaddr(|ptr, len| { - ptr::copy_nonoverlapping(ptr.cast::<u8>(), storage.cast::<u8>(), len as usize); - len - }) - } -} - -/// Helper for implementing `SocketAddrArg::with_sockaddr`. -/// -/// # Safety -/// -/// This calls `f` with a pointer to an object it has a reference to, with the -/// and the length of that object, so they'll be valid for the duration of the -/// call. -pub(crate) unsafe fn call_with_sockaddr<A, R>( - addr: &A, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, -) -> R { - let ptr = as_ptr(addr).cast(); - let len = size_of::<A>() as SocketAddrLen; - f(ptr, len) -} - -// SAFETY: This just forwards to the inner `SocketAddrArg` implementations. -unsafe impl SocketAddrArg for SocketAddr { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - match self { - Self::V4(v4) => v4.with_sockaddr(f), - Self::V6(v6) => v6.with_sockaddr(f), - } - } -} - -// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which handles -// calling `f` with the needed preconditions. -unsafe impl SocketAddrArg for SocketAddrV4 { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - call_with_sockaddr(&encode_sockaddr_v4(self), f) - } -} - -// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which handles -// calling `f` with the needed preconditions. -unsafe impl SocketAddrArg for SocketAddrV6 { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - call_with_sockaddr(&encode_sockaddr_v6(self), f) - } -} - -#[cfg(unix)] -// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which handles -// calling `f` with the needed preconditions. -unsafe impl SocketAddrArg for SocketAddrUnix { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - f(as_ptr(&self.unix).cast(), self.addr_len()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::backend::c; - - #[test] - fn test_layouts() { - assert_eq_size!(SocketAddrLen, c::socklen_t); - - #[cfg(not(any(windows, target_os = "redox")))] - assert_eq!( - memoffset::span_of!(c::msghdr, msg_namelen).len(), - size_of::<SocketAddrLen>() - ); - - assert!(size_of::<SocketAddrLen>() <= size_of::<usize>()); - } -} diff --git a/vendor/rustix/src/net/mod.rs b/vendor/rustix/src/net/mod.rs deleted file mode 100644 index e5560905..00000000 --- a/vendor/rustix/src/net/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Network-related operations. -//! -//! On Windows, one must call [`wsa_startup`] in the process before calling any -//! of these APIs. [`wsa_cleanup`] may be used in the process if these APIs are -//! no longer needed. -//! -//! [`wsa_startup`]: https://docs.rs/rustix/*/x86_64-pc-windows-msvc/rustix/net/fn.wsa_startup.html -//! [`wsa_cleanup`]: https://docs.rs/rustix/*/x86_64-pc-windows-msvc/rustix/net/fn.wsa_cleanup.html - -pub mod addr; -mod send_recv; -mod socket; -mod socket_addr_any; -#[cfg(not(any(windows, target_os = "wasi")))] -mod socketpair; -mod types; -#[cfg(windows)] -mod wsa; - -#[cfg(linux_kernel)] -pub mod netdevice; -pub mod sockopt; - -pub use crate::maybe_polyfill::net::{ - IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, -}; -pub use send_recv::*; -pub use socket::*; -pub use socket_addr_any::SocketAddrAny; -pub(crate) use socket_addr_any::SocketAddrBuf; -#[cfg(not(any(windows, target_os = "wasi")))] -pub use socketpair::socketpair; -pub use types::*; -#[cfg(windows)] -pub use wsa::{wsa_cleanup, wsa_startup}; diff --git a/vendor/rustix/src/net/netdevice.rs b/vendor/rustix/src/net/netdevice.rs deleted file mode 100644 index 1ddd918e..00000000 --- a/vendor/rustix/src/net/netdevice.rs +++ /dev/null @@ -1,107 +0,0 @@ -//! Low-level Linux network device access -//! -//! The methods in this module take a socket's file descriptor to communicate -//! with the kernel in their ioctl call: -//! - glibc uses an `AF_UNIX`, `AF_INET`, or `AF_INET6` socket. The address -//! family itself does not matter and glibc tries the next address family if -//! socket creation with one fails. -//! - Android (bionic) uses an `AF_INET` socket. -//! - Both create the socket with `SOCK_DGRAM|SOCK_CLOEXEC` type/flag. -//! - The [manual pages] specify that the ioctl calls “can be used on any -//! socket's file descriptor regardless of the family or type”. -//! -//! # References -//! - [Linux] -//! -//! [manual pages]: https://man7.org/linux/man-pages/man7/netdevice.7.html -//! [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html - -use crate::fd::AsFd; -use crate::io; -#[cfg(feature = "alloc")] -use alloc::string::String; - -/// `ioctl(fd, SIOCGIFINDEX, ifreq)`—Returns the interface index for a given -/// name. -/// -/// See the [module-level documentation] for information about `fd` usage. -/// -/// # References -/// - [Linux] -/// -/// [module-level documentation]: self -/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html -#[inline] -#[doc(alias = "SIOCGIFINDEX")] -pub fn name_to_index<Fd: AsFd>(fd: Fd, if_name: &str) -> io::Result<u32> { - crate::backend::net::netdevice::name_to_index(fd.as_fd(), if_name) -} - -/// `ioctl(fd, SIOCGIFNAME, ifreq)`—Returns the interface name for a given -/// index. -/// -/// See the [module-level documentation] for information about `fd` usage. -/// -/// # References -/// - [Linux] -/// -/// [module-level documentation]: self -/// [Linux]: https://man7.org/linux/man-pages/man7/netdevice.7.html -#[inline] -#[doc(alias = "SIOCGIFNAME")] -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn index_to_name<Fd: AsFd>(fd: Fd, index: u32) -> io::Result<String> { - crate::backend::net::netdevice::index_to_name(fd.as_fd(), index) -} - -#[cfg(test)] -mod tests { - use crate::backend::net::netdevice::{index_to_name, name_to_index}; - use crate::fd::AsFd; - use crate::net::{AddressFamily, SocketFlags, SocketType}; - - #[test] - fn test_name_to_index() { - let fd = crate::net::socket_with( - AddressFamily::INET, - SocketType::DGRAM, - SocketFlags::CLOEXEC, - None, - ) - .unwrap(); - - let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex") - .unwrap() - .as_str() - .split_at(1) - .0 - .parse::<u32>() - .unwrap(); - assert_eq!(Ok(loopback_index), name_to_index(fd.as_fd(), "lo")); - } - - #[test] - #[cfg(feature = "alloc")] - fn test_index_to_name() { - let fd = crate::net::socket_with( - AddressFamily::INET, - SocketType::DGRAM, - SocketFlags::CLOEXEC, - None, - ) - .unwrap(); - - let loopback_index = std::fs::read_to_string("/sys/class/net/lo/ifindex") - .unwrap() - .as_str() - .split_at(1) - .0 - .parse::<u32>() - .unwrap(); - assert_eq!( - Ok("lo".to_owned()), - index_to_name(fd.as_fd(), loopback_index) - ); - } -} diff --git a/vendor/rustix/src/net/send_recv/mod.rs b/vendor/rustix/src/net/send_recv/mod.rs deleted file mode 100644 index 0aac6d2e..00000000 --- a/vendor/rustix/src/net/send_recv/mod.rs +++ /dev/null @@ -1,192 +0,0 @@ -//! `recv`, `send`, and variants. - -#![allow(unsafe_code)] - -use crate::buffer::Buffer; -use crate::net::addr::SocketAddrArg; -use crate::net::SocketAddrAny; -use crate::{backend, io}; -use backend::fd::AsFd; -use core::cmp::min; - -pub use backend::net::send_recv::{RecvFlags, ReturnFlags, SendFlags}; - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -mod msg; - -#[cfg(not(any( - windows, - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -pub use msg::*; - -/// `recv(fd, buf, flags)`—Reads data from a socket. -/// -/// In addition to the `Buffer::Output` return value, this also returns the -/// number of bytes received before any truncation due to the -/// [`RecvFlags::TRUNC`] flag. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recv.html -/// [Linux]: https://man7.org/linux/man-pages/man2/recv.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recv.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2 -/// [NetBSD]: https://man.netbsd.org/recv.2 -/// [OpenBSD]: https://man.openbsd.org/recv.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recv§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/recv -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Receiving-Data.html -#[inline] -#[allow(clippy::type_complexity)] -pub fn recv<Fd: AsFd, Buf: Buffer<u8>>( - fd: Fd, - mut buf: Buf, - flags: RecvFlags, -) -> io::Result<(Buf::Output, usize)> { - let (ptr, len) = buf.parts_mut(); - // SAFETY: `recv` behaves. - let recv_len = unsafe { backend::net::syscalls::recv(fd.as_fd(), (ptr, len), flags)? }; - // If the `TRUNC` flag is set, the returned `length` may be longer than the - // buffer length. - let min_len = min(len, recv_len); - // SAFETY: `recv` behaves. - unsafe { Ok((buf.assume_init(min_len), recv_len)) } -} - -/// `send(fd, buf, flags)`—Writes data to a socket. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/send.html -/// [Linux]: https://man7.org/linux/man-pages/man2/send.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/send.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2 -/// [NetBSD]: https://man.netbsd.org/send.2 -/// [OpenBSD]: https://man.openbsd.org/send.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=send§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/send -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Sending-Data.html -#[inline] -pub fn send<Fd: AsFd>(fd: Fd, buf: &[u8], flags: SendFlags) -> io::Result<usize> { - backend::net::syscalls::send(fd.as_fd(), buf, flags) -} - -/// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and -/// returns the sender address. -/// -/// In addition to the `Buffer::Output` return value, this also returns the -/// number of bytes received before any truncation due to the -/// [`RecvFlags::TRUNC`] flag. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvfrom.html -/// [Linux]: https://man7.org/linux/man-pages/man2/recvfrom.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvfrom.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvfrom&sektion=2 -/// [NetBSD]: https://man.netbsd.org/recvfrom.2 -/// [OpenBSD]: https://man.openbsd.org/recvfrom.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvfrom§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/recvfrom -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Receiving-Datagrams.html -#[inline] -pub fn recvfrom<Fd: AsFd, Buf: Buffer<u8>>( - fd: Fd, - mut buf: Buf, - flags: RecvFlags, -) -> io::Result<(Buf::Output, usize, Option<SocketAddrAny>)> { - let (ptr, len) = buf.parts_mut(); - // SAFETY: `recvfrom` behaves. - let (recv_len, addr) = - unsafe { backend::net::syscalls::recvfrom(fd.as_fd(), (ptr, len), flags)? }; - // If the `TRUNC` flag is set, the returned `length` may be longer than the - // buffer length. - let min_len = min(len, recv_len); - // SAFETY: `recvfrom` behaves. - unsafe { Ok((buf.assume_init(min_len), recv_len, addr)) } -} - -/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific IP -/// address. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendto.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2 -/// [NetBSD]: https://man.netbsd.org/sendto.2 -/// [OpenBSD]: https://man.openbsd.org/sendto.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/sendto -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Sending-Datagrams.html -pub fn sendto<Fd: AsFd>( - fd: Fd, - buf: &[u8], - flags: SendFlags, - addr: &impl SocketAddrArg, -) -> io::Result<usize> { - backend::net::syscalls::sendto(fd.as_fd(), buf, flags, addr) -} diff --git a/vendor/rustix/src/net/send_recv/msg.rs b/vendor/rustix/src/net/send_recv/msg.rs deleted file mode 100644 index 7df60a5e..00000000 --- a/vendor/rustix/src/net/send_recv/msg.rs +++ /dev/null @@ -1,961 +0,0 @@ -//! [`recvmsg`], [`sendmsg`], and related functions. - -#![allow(unsafe_code)] - -#[cfg(target_os = "linux")] -use crate::backend::net::msghdr::noaddr_msghdr; -use crate::backend::{self, c}; -use crate::fd::{AsFd, BorrowedFd, OwnedFd}; -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::addr::SocketAddrArg; -#[cfg(linux_kernel)] -use crate::net::UCred; -use core::iter::FusedIterator; -use core::marker::PhantomData; -use core::mem::{align_of, size_of, size_of_val, take, MaybeUninit}; -#[cfg(linux_kernel)] -use core::ptr::addr_of; -use core::{ptr, slice}; - -use super::{RecvFlags, ReturnFlags, SendFlags, SocketAddrAny}; - -/// Macro for defining the amount of space to allocate in a buffer for use with -/// [`RecvAncillaryBuffer::new`] and [`SendAncillaryBuffer::new`]. -/// -/// # Examples -/// -/// Allocate a buffer for a single file descriptor: -/// ``` -/// # use std::mem::MaybeUninit; -/// # use rustix::cmsg_space; -/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; -/// # let _: &[MaybeUninit<u8>] = space.as_slice(); -/// ``` -/// -/// Allocate a buffer for credentials: -/// ``` -/// # #[cfg(linux_kernel)] -/// # { -/// # use std::mem::MaybeUninit; -/// # use rustix::cmsg_space; -/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; -/// # let _: &[MaybeUninit<u8>] = space.as_slice(); -/// # } -/// ``` -/// -/// Allocate a buffer for two file descriptors and credentials: -/// ``` -/// # #[cfg(linux_kernel)] -/// # { -/// # use std::mem::MaybeUninit; -/// # use rustix::cmsg_space; -/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; -/// # let _: &[MaybeUninit<u8>] = space.as_slice(); -/// # } -/// ``` -#[macro_export] -macro_rules! cmsg_space { - // Base Rules - (ScmRights($len:expr)) => { - $crate::net::__cmsg_space( - $len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(), - ) - }; - (ScmCredentials($len:expr)) => { - $crate::net::__cmsg_space( - $len * ::core::mem::size_of::<$crate::net::UCred>(), - ) - }; - - // Combo Rules - ($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{ - // We only have to add `cmsghdr` alignment once; all other times we can - // use `cmsg_aligned_space`. - let sum = $crate::cmsg_space!($firstid($firstex)); - $( - let sum = sum + $crate::cmsg_aligned_space!($restid($restex)); - )* - sum - }}; -} - -/// Like `cmsg_space`, but doesn't add padding for `cmsghdr` alignment. -#[doc(hidden)] -#[macro_export] -macro_rules! cmsg_aligned_space { - // Base Rules - (ScmRights($len:expr)) => { - $crate::net::__cmsg_aligned_space( - $len * ::core::mem::size_of::<$crate::fd::BorrowedFd<'static>>(), - ) - }; - (ScmCredentials($len:expr)) => { - $crate::net::__cmsg_aligned_space( - $len * ::core::mem::size_of::<$crate::net::UCred>(), - ) - }; - - // Combo Rules - ($firstid:ident($firstex:expr), $($restid:ident($restex:expr)),*) => {{ - let sum = cmsg_aligned_space!($firstid($firstex)); - $( - let sum = sum + cmsg_aligned_space!($restid($restex)); - )* - sum - }}; -} - -/// Helper function for [`cmsg_space`]. -#[doc(hidden)] -pub const fn __cmsg_space(len: usize) -> usize { - // Add `align_of::<c::cmsghdr>()` so that we can align the user-provided - // `&[u8]` to the required alignment boundary. - let len = len + align_of::<c::cmsghdr>(); - - __cmsg_aligned_space(len) -} - -/// Helper function for [`cmsg_aligned_space`]. -#[doc(hidden)] -pub const fn __cmsg_aligned_space(len: usize) -> usize { - // Convert `len` to `u32` for `CMSG_SPACE`. This would be `try_into()` if - // we could call that in a `const fn`. - let converted_len = len as u32; - if converted_len as usize != len { - unreachable!(); // `CMSG_SPACE` size overflow - } - - unsafe { c::CMSG_SPACE(converted_len) as usize } -} - -/// Ancillary message for [`sendmsg`] and [`sendmsg_addr`]. -#[non_exhaustive] -pub enum SendAncillaryMessage<'slice, 'fd> { - /// Send file descriptors. - #[doc(alias = "SCM_RIGHTS")] - ScmRights(&'slice [BorrowedFd<'fd>]), - /// Send process credentials. - #[cfg(linux_kernel)] - #[doc(alias = "SCM_CREDENTIAL")] - ScmCredentials(UCred), -} - -impl SendAncillaryMessage<'_, '_> { - /// Get the maximum size of an ancillary message. - /// - /// This can be used to determine the size of the buffer to allocate for a - /// [`SendAncillaryBuffer::new`] with one message. - pub const fn size(&self) -> usize { - match self { - Self::ScmRights(slice) => cmsg_space!(ScmRights(slice.len())), - #[cfg(linux_kernel)] - Self::ScmCredentials(_) => cmsg_space!(ScmCredentials(1)), - } - } -} - -/// Ancillary message for [`recvmsg`]. -#[non_exhaustive] -pub enum RecvAncillaryMessage<'a> { - /// Received file descriptors. - #[doc(alias = "SCM_RIGHTS")] - ScmRights(AncillaryIter<'a, OwnedFd>), - /// Received process credentials. - #[cfg(linux_kernel)] - #[doc(alias = "SCM_CREDENTIALS")] - ScmCredentials(UCred), -} - -/// Buffer for sending ancillary messages with [`sendmsg`] and -/// [`sendmsg_addr`]. -/// -/// Use the [`push`] function to add messages to send. -/// -/// [`push`]: SendAncillaryBuffer::push -pub struct SendAncillaryBuffer<'buf, 'slice, 'fd> { - /// Raw byte buffer for messages. - buffer: &'buf mut [MaybeUninit<u8>], - - /// The amount of the buffer that is used. - length: usize, - - /// Phantom data for lifetime of `&'slice [BorrowedFd<'fd>]`. - _phantom: PhantomData<&'slice [BorrowedFd<'fd>]>, -} - -impl<'buf> From<&'buf mut [MaybeUninit<u8>]> for SendAncillaryBuffer<'buf, '_, '_> { - fn from(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self::new(buffer) - } -} - -impl Default for SendAncillaryBuffer<'_, '_, '_> { - fn default() -> Self { - Self { - buffer: &mut [], - length: 0, - _phantom: PhantomData, - } - } -} - -impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { - /// Create a new, empty `SendAncillaryBuffer` from a raw byte buffer. - /// - /// The buffer size may be computed with [`cmsg_space`], or it may be - /// zero for an empty buffer, however in that case, consider `default()` - /// instead, or even using [`send`] instead of `sendmsg`. - /// - /// # Examples - /// - /// Allocate a buffer for a single file descriptor: - /// ``` - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; - /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); - /// ``` - /// - /// Allocate a buffer for credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; - /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// Allocate a buffer for two file descriptors and credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; - /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// [`send`]: crate::net::send - #[inline] - pub fn new(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self { - buffer: align_for_cmsghdr(buffer), - length: 0, - _phantom: PhantomData, - } - } - - /// Returns a pointer to the message data. - pub(crate) fn as_control_ptr(&mut self) -> *mut u8 { - // When the length is zero, we may be using a `&[]` address, which may - // be an invalid but non-null pointer, and on some platforms, that - // causes `sendmsg` to fail with `EFAULT` or `EINVAL` - #[cfg(not(linux_kernel))] - if self.length == 0 { - return core::ptr::null_mut(); - } - - self.buffer.as_mut_ptr().cast() - } - - /// Returns the length of the message data. - pub(crate) fn control_len(&self) -> usize { - self.length - } - - /// Delete all messages from the buffer. - pub fn clear(&mut self) { - self.length = 0; - } - - /// Add an ancillary message to the buffer. - /// - /// Returns `true` if the message was added successfully. - pub fn push(&mut self, msg: SendAncillaryMessage<'slice, 'fd>) -> bool { - match msg { - SendAncillaryMessage::ScmRights(fds) => { - let fds_bytes = - unsafe { slice::from_raw_parts(fds.as_ptr().cast::<u8>(), size_of_val(fds)) }; - self.push_ancillary(fds_bytes, c::SOL_SOCKET as _, c::SCM_RIGHTS as _) - } - #[cfg(linux_kernel)] - SendAncillaryMessage::ScmCredentials(ucred) => { - let ucred_bytes = unsafe { - slice::from_raw_parts(addr_of!(ucred).cast::<u8>(), size_of_val(&ucred)) - }; - self.push_ancillary(ucred_bytes, c::SOL_SOCKET as _, c::SCM_CREDENTIALS as _) - } - } - } - - /// Pushes an ancillary message to the buffer. - fn push_ancillary(&mut self, source: &[u8], cmsg_level: c::c_int, cmsg_type: c::c_int) -> bool { - macro_rules! leap { - ($e:expr) => {{ - match ($e) { - Some(x) => x, - None => return false, - } - }}; - } - - // Calculate the length of the message. - let source_len = leap!(u32::try_from(source.len()).ok()); - - // Calculate the new length of the buffer. - let additional_space = unsafe { c::CMSG_SPACE(source_len) }; - let new_length = leap!(self.length.checked_add(additional_space as usize)); - let buffer = leap!(self.buffer.get_mut(..new_length)); - - // Fill the new part of the buffer with zeroes. - buffer[self.length..new_length].fill(MaybeUninit::new(0)); - self.length = new_length; - - // Get the last header in the buffer. - let last_header = leap!(messages::Messages::new(buffer).last()); - - // Set the header fields. - last_header.cmsg_len = unsafe { c::CMSG_LEN(source_len) } as _; - last_header.cmsg_level = cmsg_level; - last_header.cmsg_type = cmsg_type; - - // Get the pointer to the payload and copy the data. - unsafe { - let payload = c::CMSG_DATA(last_header); - ptr::copy_nonoverlapping(source.as_ptr(), payload, source_len as usize); - } - - true - } -} - -impl<'slice, 'fd> Extend<SendAncillaryMessage<'slice, 'fd>> - for SendAncillaryBuffer<'_, 'slice, 'fd> -{ - fn extend<T: IntoIterator<Item = SendAncillaryMessage<'slice, 'fd>>>(&mut self, iter: T) { - // TODO: This could be optimized to add every message in one go. - iter.into_iter().all(|msg| self.push(msg)); - } -} - -/// Buffer for receiving ancillary messages with [`recvmsg`]. -/// -/// Use the [`drain`] function to iterate over the received messages. -/// -/// [`drain`]: RecvAncillaryBuffer::drain -#[derive(Default)] -pub struct RecvAncillaryBuffer<'buf> { - /// Raw byte buffer for messages. - buffer: &'buf mut [MaybeUninit<u8>], - - /// The portion of the buffer we've read from already. - read: usize, - - /// The amount of the buffer that is used. - length: usize, -} - -impl<'buf> From<&'buf mut [MaybeUninit<u8>]> for RecvAncillaryBuffer<'buf> { - fn from(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self::new(buffer) - } -} - -impl<'buf> RecvAncillaryBuffer<'buf> { - /// Create a new, empty `RecvAncillaryBuffer` from a raw byte buffer. - /// - /// The buffer size may be computed with [`cmsg_space`], or it may be - /// zero for an empty buffer, however in that case, consider `default()` - /// instead, or even using [`recv`] instead of `recvmsg`. - /// - /// # Examples - /// - /// Allocate a buffer for a single file descriptor: - /// ``` - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; - /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); - /// ``` - /// - /// Allocate a buffer for credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; - /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// Allocate a buffer for two file descriptors and credentials: - /// ``` - /// # #[cfg(linux_kernel)] - /// # { - /// # use std::mem::MaybeUninit; - /// # use rustix::cmsg_space; - /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; - /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); - /// # } - /// ``` - /// - /// [`recv`]: crate::net::recv - #[inline] - pub fn new(buffer: &'buf mut [MaybeUninit<u8>]) -> Self { - Self { - buffer: align_for_cmsghdr(buffer), - read: 0, - length: 0, - } - } - - /// Returns a pointer to the message data. - pub(crate) fn as_control_ptr(&mut self) -> *mut u8 { - // When the length is zero, we may be using a `&[]` address, which may - // be an invalid but non-null pointer, and on some platforms, that - // causes `sendmsg` to fail with `EFAULT` or `EINVAL` - #[cfg(not(linux_kernel))] - if self.buffer.is_empty() { - return core::ptr::null_mut(); - } - - self.buffer.as_mut_ptr().cast() - } - - /// Returns the length of the message data. - pub(crate) fn control_len(&self) -> usize { - self.buffer.len() - } - - /// Set the length of the message data. - /// - /// # Safety - /// - /// The buffer must be filled with valid message data. - pub(crate) unsafe fn set_control_len(&mut self, len: usize) { - self.length = len; - self.read = 0; - } - - /// Delete all messages from the buffer. - pub(crate) fn clear(&mut self) { - self.drain().for_each(drop); - } - - /// Drain all messages from the buffer. - pub fn drain(&mut self) -> AncillaryDrain<'_> { - AncillaryDrain { - messages: messages::Messages::new(&mut self.buffer[self.read..][..self.length]), - read_and_length: Some((&mut self.read, &mut self.length)), - } - } -} - -impl Drop for RecvAncillaryBuffer<'_> { - fn drop(&mut self) { - self.clear(); - } -} - -/// Return a slice of `buffer` starting at the first `cmsghdr` alignment -/// boundary. -#[inline] -fn align_for_cmsghdr(buffer: &mut [MaybeUninit<u8>]) -> &mut [MaybeUninit<u8>] { - // If the buffer is empty, we won't be writing anything into it, so it - // doesn't need to be aligned. - if buffer.is_empty() { - return buffer; - } - - let align = align_of::<c::cmsghdr>(); - let addr = buffer.as_ptr() as usize; - let adjusted = (addr + (align - 1)) & align.wrapping_neg(); - &mut buffer[adjusted - addr..] -} - -/// An iterator that drains messages from a [`RecvAncillaryBuffer`]. -pub struct AncillaryDrain<'buf> { - /// Inner iterator over messages. - messages: messages::Messages<'buf>, - - /// Increment the number of messages we've read. - /// Decrement the total length. - read_and_length: Option<(&'buf mut usize, &'buf mut usize)>, -} - -impl<'buf> AncillaryDrain<'buf> { - /// Create an iterator for control messages that were received without - /// [`RecvAncillaryBuffer`]. - /// - /// # Safety - /// - /// The buffer must contain valid message data (or be empty). - pub unsafe fn parse(buffer: &'buf mut [u8]) -> Self { - Self { - messages: messages::Messages::new(buffer), - read_and_length: None, - } - } - - fn advance( - read_and_length: &mut Option<(&'buf mut usize, &'buf mut usize)>, - msg: &c::cmsghdr, - ) -> Option<RecvAncillaryMessage<'buf>> { - // Advance the `read` pointer. - if let Some((read, length)) = read_and_length { - let msg_len = msg.cmsg_len as usize; - **read += msg_len; - **length -= msg_len; - } - - Self::cvt_msg(msg) - } - - /// A closure that converts a message into a [`RecvAncillaryMessage`]. - fn cvt_msg(msg: &c::cmsghdr) -> Option<RecvAncillaryMessage<'buf>> { - unsafe { - // Get a pointer to the payload. - let payload = c::CMSG_DATA(msg); - let payload_len = msg.cmsg_len as usize - c::CMSG_LEN(0) as usize; - - // Get a mutable slice of the payload. - let payload: &'buf mut [u8] = slice::from_raw_parts_mut(payload, payload_len); - - // Determine what type it is. - let (level, msg_type) = (msg.cmsg_level, msg.cmsg_type); - match (level as _, msg_type as _) { - (c::SOL_SOCKET, c::SCM_RIGHTS) => { - // Create an iterator that reads out the file descriptors. - let fds = AncillaryIter::new(payload); - - Some(RecvAncillaryMessage::ScmRights(fds)) - } - #[cfg(linux_kernel)] - (c::SOL_SOCKET, c::SCM_CREDENTIALS) => { - if payload_len >= size_of::<UCred>() { - let ucred = payload.as_ptr().cast::<UCred>().read_unaligned(); - Some(RecvAncillaryMessage::ScmCredentials(ucred)) - } else { - None - } - } - _ => None, - } - } - } -} - -impl<'buf> Iterator for AncillaryDrain<'buf> { - type Item = RecvAncillaryMessage<'buf>; - - fn next(&mut self) -> Option<Self::Item> { - self.messages - .find_map(|ev| Self::advance(&mut self.read_and_length, ev)) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - let (_, max) = self.messages.size_hint(); - (0, max) - } - - fn fold<B, F>(mut self, init: B, f: F) -> B - where - Self: Sized, - F: FnMut(B, Self::Item) -> B, - { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .fold(init, f) - } - - fn count(mut self) -> usize { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .count() - } - - fn last(mut self) -> Option<Self::Item> - where - Self: Sized, - { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .last() - } - - fn collect<B: FromIterator<Self::Item>>(mut self) -> B - where - Self: Sized, - { - self.messages - .filter_map(|ev| Self::advance(&mut self.read_and_length, ev)) - .collect() - } -} - -impl FusedIterator for AncillaryDrain<'_> {} - -/// An ABI-compatible wrapper for `mmsghdr`, for sending multiple messages with -/// [sendmmsg]. -#[cfg(target_os = "linux")] -#[repr(transparent)] -pub struct MMsgHdr<'a> { - raw: c::mmsghdr, - _phantom: PhantomData<&'a mut ()>, -} - -#[cfg(target_os = "linux")] -impl<'a> MMsgHdr<'a> { - /// Constructs a new message with no destination address. - pub fn new(iov: &'a [IoSlice<'_>], control: &'a mut SendAncillaryBuffer<'_, '_, '_>) -> Self { - Self::wrap(noaddr_msghdr(iov, control)) - } - - /// Constructs a new message to a specific address. - /// - /// This requires a `SocketAddrAny` instead of using `impl SocketAddrArg`; - /// to obtain a `SocketAddrAny`, use [`SocketAddrArg::as_any`]. - pub fn new_with_addr( - addr: &'a SocketAddrAny, - iov: &'a [IoSlice<'_>], - control: &'a mut SendAncillaryBuffer<'_, '_, '_>, - ) -> Self { - // The reason we use `SocketAddrAny` instead of `SocketAddrArg` here, - // and avoid `use_msghdr`, is that we need a pointer that will remain - // valid for the duration of the `'a` lifetime. `SocketAddrAny` can - // give us a pointer directly, so we use that. - let mut msghdr = noaddr_msghdr(iov, control); - msghdr.msg_name = addr.as_ptr() as _; - msghdr.msg_namelen = bitcast!(addr.addr_len()); - - Self::wrap(msghdr) - } - - fn wrap(msg_hdr: c::msghdr) -> Self { - Self { - raw: c::mmsghdr { - msg_hdr, - msg_len: 0, - }, - _phantom: PhantomData, - } - } - - /// Returns the number of bytes sent. This will return 0 until after a - /// successful call to [sendmmsg]. - pub fn bytes_sent(&self) -> usize { - self.raw.msg_len as usize - } -} - -/// `sendmsg(msghdr)`—Sends a message on a socket. -/// -/// This function is for use on connected sockets, as it doesn't have a way to -/// specify an address. See [`sendmsg_addr`] to send messages on unconnected -/// sockets. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendmsg.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2 -/// [NetBSD]: https://man.netbsd.org/sendmsg.2 -/// [OpenBSD]: https://man.openbsd.org/sendmsg.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg -#[inline] -pub fn sendmsg<Fd: AsFd>( - socket: Fd, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - flags: SendFlags, -) -> io::Result<usize> { - backend::net::syscalls::sendmsg(socket.as_fd(), iov, control, flags) -} - -/// `sendmsg(msghdr)`—Sends a message on a socket to a specific address. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendmsg.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sendmsg.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendmsg.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendmsg&sektion=2 -/// [NetBSD]: https://man.netbsd.org/sendmsg.2 -/// [OpenBSD]: https://man.openbsd.org/sendmsg.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendmsg§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/sendmsg -#[inline] -pub fn sendmsg_addr<Fd: AsFd>( - socket: Fd, - addr: &impl SocketAddrArg, - iov: &[IoSlice<'_>], - control: &mut SendAncillaryBuffer<'_, '_, '_>, - flags: SendFlags, -) -> io::Result<usize> { - backend::net::syscalls::sendmsg_addr(socket.as_fd(), addr, iov, control, flags) -} - -/// `sendmmsg(msghdr)`—Sends multiple messages on a socket. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sendmmsg.2.html -#[inline] -#[cfg(target_os = "linux")] -pub fn sendmmsg<Fd: AsFd>( - socket: Fd, - msgs: &mut [MMsgHdr<'_>], - flags: SendFlags, -) -> io::Result<usize> { - backend::net::syscalls::sendmmsg(socket.as_fd(), msgs, flags) -} - -/// `recvmsg(msghdr)`—Receives a message from a socket. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvmsg.html -/// [Linux]: https://man7.org/linux/man-pages/man2/recvmsg.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvmsg.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvmsg&sektion=2 -/// [NetBSD]: https://man.netbsd.org/recvmsg.2 -/// [OpenBSD]: https://man.openbsd.org/recvmsg.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvmsg§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/recvmsg -#[inline] -pub fn recvmsg<Fd: AsFd>( - socket: Fd, - iov: &mut [IoSliceMut<'_>], - control: &mut RecvAncillaryBuffer<'_>, - flags: RecvFlags, -) -> io::Result<RecvMsg> { - backend::net::syscalls::recvmsg(socket.as_fd(), iov, control, flags) -} - -/// The result of a successful [`recvmsg`] call. -#[derive(Debug, Clone)] -pub struct RecvMsg { - /// The number of bytes received. - /// - /// When `RecvFlags::TRUNC` is in use, this may be greater than the length - /// of the buffer, as it reflects the number of bytes received before - /// truncation into the buffer. - pub bytes: usize, - - /// The flags received. - pub flags: ReturnFlags, - - /// The address of the socket we received from, if any. - pub address: Option<SocketAddrAny>, -} - -/// An iterator over data in an ancillary buffer. -pub struct AncillaryIter<'data, T> { - /// The data we're iterating over. - data: &'data mut [u8], - - /// The raw data we're removing. - _marker: PhantomData<T>, -} - -impl<'data, T> AncillaryIter<'data, T> { - /// Create a new iterator over data in an ancillary buffer. - /// - /// # Safety - /// - /// The buffer must contain valid ancillary data. - unsafe fn new(data: &'data mut [u8]) -> Self { - assert_eq!(data.len() % size_of::<T>(), 0); - - Self { - data, - _marker: PhantomData, - } - } -} - -impl<'data, T> Drop for AncillaryIter<'data, T> { - fn drop(&mut self) { - self.for_each(drop); - } -} - -impl<T> Iterator for AncillaryIter<'_, T> { - type Item = T; - - fn next(&mut self) -> Option<Self::Item> { - // See if there is a next item. - if self.data.len() < size_of::<T>() { - return None; - } - - // Get the next item. - let item = unsafe { self.data.as_ptr().cast::<T>().read_unaligned() }; - - // Move forward. - let data = take(&mut self.data); - self.data = &mut data[size_of::<T>()..]; - - Some(item) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - let len = self.len(); - (len, Some(len)) - } - - fn count(self) -> usize { - self.len() - } - - fn last(mut self) -> Option<Self::Item> { - self.next_back() - } -} - -impl<T> FusedIterator for AncillaryIter<'_, T> {} - -impl<T> ExactSizeIterator for AncillaryIter<'_, T> { - fn len(&self) -> usize { - self.data.len() / size_of::<T>() - } -} - -impl<T> DoubleEndedIterator for AncillaryIter<'_, T> { - fn next_back(&mut self) -> Option<Self::Item> { - // See if there is a next item. - if self.data.len() < size_of::<T>() { - return None; - } - - // Get the next item. - let item = unsafe { - let ptr = self.data.as_ptr().add(self.data.len() - size_of::<T>()); - ptr.cast::<T>().read_unaligned() - }; - - // Move forward. - let len = self.data.len(); - let data = take(&mut self.data); - self.data = &mut data[..len - size_of::<T>()]; - - Some(item) - } -} - -mod messages { - use crate::backend::c; - use crate::backend::net::msghdr; - use core::iter::FusedIterator; - use core::marker::PhantomData; - use core::mem::MaybeUninit; - use core::ptr::NonNull; - - /// An iterator over the messages in an ancillary buffer. - pub(super) struct Messages<'buf> { - /// The message header we're using to iterate over the messages. - msghdr: c::msghdr, - - /// The current pointer to the next message header to return. - /// - /// This has a lifetime of `'buf`. - header: Option<NonNull<c::cmsghdr>>, - - /// Capture the original lifetime of the buffer. - _buffer: PhantomData<&'buf mut [MaybeUninit<u8>]>, - } - - pub(super) trait AllowedMsgBufType {} - impl AllowedMsgBufType for u8 {} - impl AllowedMsgBufType for MaybeUninit<u8> {} - - impl<'buf> Messages<'buf> { - /// Create a new iterator over messages from a byte buffer. - pub(super) fn new(buf: &'buf mut [impl AllowedMsgBufType]) -> Self { - let mut msghdr = msghdr::zero_msghdr(); - msghdr.msg_control = buf.as_mut_ptr().cast(); - msghdr.msg_controllen = buf.len().try_into().expect("buffer too large for msghdr"); - - // Get the first header. - let header = NonNull::new(unsafe { c::CMSG_FIRSTHDR(&msghdr) }); - - Self { - msghdr, - header, - _buffer: PhantomData, - } - } - } - - impl<'a> Iterator for Messages<'a> { - type Item = &'a mut c::cmsghdr; - - #[inline] - fn next(&mut self) -> Option<Self::Item> { - // Get the current header. - let header = self.header?; - - // Get the next header. - self.header = NonNull::new(unsafe { c::CMSG_NXTHDR(&self.msghdr, header.as_ptr()) }); - - // If the headers are equal, we're done. - if Some(header) == self.header { - self.header = None; - } - - // SAFETY: The lifetime of `header` is tied to this. - Some(unsafe { &mut *header.as_ptr() }) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - if self.header.is_some() { - // The remaining buffer *could* be filled with zero-length - // messages. - let max_size = unsafe { c::CMSG_LEN(0) } as usize; - let remaining_count = self.msghdr.msg_controllen as usize / max_size; - (1, Some(remaining_count)) - } else { - (0, Some(0)) - } - } - } - - impl FusedIterator for Messages<'_> {} -} diff --git a/vendor/rustix/src/net/socket.rs b/vendor/rustix/src/net/socket.rs deleted file mode 100644 index fff302ad..00000000 --- a/vendor/rustix/src/net/socket.rs +++ /dev/null @@ -1,461 +0,0 @@ -use crate::fd::OwnedFd; -use crate::net::addr::SocketAddrArg; -use crate::net::SocketAddrAny; -use crate::{backend, io}; -use backend::fd::AsFd; - -pub use crate::net::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; -#[cfg(unix)] -pub use backend::net::addr::SocketAddrUnix; - -/// `socket(domain, type_, protocol)`—Creates a socket. -/// -/// POSIX guarantees that `socket` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// To pass extra flags such as [`SocketFlags::CLOEXEC`] or -/// [`SocketFlags::NONBLOCK`], use [`socket_with`]. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socket.html -/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2 -/// [NetBSD]: https://man.netbsd.org/socket.2 -/// [OpenBSD]: https://man.openbsd.org/socket.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/socket -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Socket.html -#[inline] -pub fn socket( - domain: AddressFamily, - type_: SocketType, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - backend::net::syscalls::socket(domain, type_, protocol) -} - -/// `socket_with(domain, type_ | flags, protocol)`—Creates a socket, with -/// flags. -/// -/// POSIX guarantees that `socket` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// `socket_with` is the same as [`socket`] but adds an additional flags -/// operand. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socket.html -/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2 -/// [NetBSD]: https://man.netbsd.org/socket.2 -/// [OpenBSD]: https://man.openbsd.org/socket.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/socket -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Socket.html -#[doc(alias("socket"))] -#[inline] -pub fn socket_with( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<OwnedFd> { - backend::net::syscalls::socket_with(domain, type_, flags, protocol) -} - -/// `bind(sockfd, addr)`—Binds a socket to an IP address. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/bind.html -/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2 -/// [NetBSD]: https://man.netbsd.org/bind.2 -/// [OpenBSD]: https://man.openbsd.org/bind.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/bind -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Setting-Address.html -pub fn bind<Fd: AsFd>(sockfd: Fd, addr: &impl SocketAddrArg) -> io::Result<()> { - backend::net::syscalls::bind(sockfd.as_fd(), addr) -} - -/// `connect(sockfd, addr)`—Initiates a connection to an IP address. -/// -/// On Windows, a non-blocking socket returns [`Errno::WOULDBLOCK`] if the -/// connection cannot be completed immediately, rather than -/// `Errno::INPROGRESS`. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/connect.html -/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2 -/// [NetBSD]: https://man.netbsd.org/connect.2 -/// [OpenBSD]: https://man.openbsd.org/connect.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/connect -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Connecting.html -/// [`Errno::WOULDBLOCK`]: io::Errno::WOULDBLOCK -pub fn connect<Fd: AsFd>(sockfd: Fd, addr: &impl SocketAddrArg) -> io::Result<()> { - backend::net::syscalls::connect(sockfd.as_fd(), addr) -} - -/// `connect(sockfd, {.sa_family = AF_UNSPEC}, sizeof(struct sockaddr))`— -/// Dissolve the socket's association. -/// -/// On UDP sockets, BSD platforms report [`Errno::AFNOSUPPORT`] or -/// [`Errno::INVAL`] even if the disconnect was successful. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/connect.html -/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2 -/// [NetBSD]: https://man.netbsd.org/connect.2 -/// [OpenBSD]: https://man.openbsd.org/connect.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/connect -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Connecting.html -/// [`Errno::AFNOSUPPORT`]: io::Errno::AFNOSUPPORT -/// [`Errno::INVAL`]: io::Errno::INVAL -#[inline] -#[doc(alias = "connect")] -pub fn connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()> { - backend::net::syscalls::connect_unspec(sockfd.as_fd()) -} - -/// `listen(fd, backlog)`—Enables listening for incoming connections. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#listen -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/listen.html -/// [Linux]: https://man7.org/linux/man-pages/man2/listen.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/listen.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2 -/// [NetBSD]: https://man.netbsd.org/listen.2 -/// [OpenBSD]: https://man.openbsd.org/listen.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=listen§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/listen -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Listening.html -#[inline] -pub fn listen<Fd: AsFd>(sockfd: Fd, backlog: i32) -> io::Result<()> { - backend::net::syscalls::listen(sockfd.as_fd(), backlog) -} - -/// `accept(fd, NULL, NULL)`—Accepts an incoming connection. -/// -/// Use [`acceptfrom`] to retrieve the peer address. -/// -/// POSIX guarantees that `accept` will use the lowest unused file descriptor, -/// however it is not safe in general to rely on this, as file descriptors may -/// be unexpectedly allocated on other threads or in libraries. -/// -/// See [`accept_with`] to pass additional flags. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490. -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/accept.html -/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept.2 -/// [OpenBSD]: https://man.openbsd.org/accept.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Accepting-Connections.html -#[inline] -pub fn accept<Fd: AsFd>(sockfd: Fd) -> io::Result<OwnedFd> { - backend::net::syscalls::accept(sockfd.as_fd()) -} - -/// `accept4(fd, NULL, NULL, flags)`—Accepts an incoming connection, with -/// flags. -/// -/// Use [`acceptfrom_with`] to retrieve the peer address. -/// -/// Even though POSIX guarantees that this will use the lowest unused file -/// descriptor, it is not safe in general to rely on this, as file descriptors -/// may be unexpectedly allocated on other threads or in libraries. -/// -/// `accept_with` is the same as [`accept`] but adds an additional flags -/// operand. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept4.2 -/// [OpenBSD]: https://man.openbsd.org/accept4.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept4 -#[inline] -#[doc(alias = "accept4")] -pub fn accept_with<Fd: AsFd>(sockfd: Fd, flags: SocketFlags) -> io::Result<OwnedFd> { - backend::net::syscalls::accept_with(sockfd.as_fd(), flags) -} - -/// `accept(fd, &addr, &len)`—Accepts an incoming connection and returns the -/// peer address. -/// -/// Use [`accept`] if the peer address isn't needed. -/// -/// See [`acceptfrom_with`] to pass additional flags. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490. -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/accept.html -/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept.2 -/// [OpenBSD]: https://man.openbsd.org/accept.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Accepting-Connections.html -#[inline] -#[doc(alias = "accept")] -pub fn acceptfrom<Fd: AsFd>(sockfd: Fd) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - backend::net::syscalls::acceptfrom(sockfd.as_fd()) -} - -/// `accept4(fd, &addr, &len, flags)`—Accepts an incoming connection and -/// returns the peer address, with flags. -/// -/// Use [`accept_with`] if the peer address isn't needed. -/// -/// `acceptfrom_with` is the same as [`acceptfrom`] but adds an additional -/// flags operand. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2 -/// [NetBSD]: https://man.netbsd.org/accept4.2 -/// [OpenBSD]: https://man.openbsd.org/accept4.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/accept4 -#[inline] -#[doc(alias = "accept4")] -pub fn acceptfrom_with<Fd: AsFd>( - sockfd: Fd, - flags: SocketFlags, -) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> { - backend::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags) -} - -/// `shutdown(fd, how)`—Closes the read and/or write sides of a stream. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#close-and-shutdownget-outta-my-face -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shutdown.html -/// [Linux]: https://man7.org/linux/man-pages/man2/shutdown.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/shutdown.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2 -/// [NetBSD]: https://man.netbsd.org/shutdown.2 -/// [OpenBSD]: https://man.openbsd.org/shutdown.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=shutdown§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/shutdown -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Closing-a-Socket.html -#[inline] -pub fn shutdown<Fd: AsFd>(sockfd: Fd, how: Shutdown) -> io::Result<()> { - backend::net::syscalls::shutdown(sockfd.as_fd(), how) -} - -/// `getsockname(fd, addr, len)`—Returns the address a socket is bound to. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsockname.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getsockname.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockname.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockname&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getsockname.2 -/// [OpenBSD]: https://man.openbsd.org/getsockname.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockname§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getsockname -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Reading-Address.html -#[inline] -pub fn getsockname<Fd: AsFd>(sockfd: Fd) -> io::Result<SocketAddrAny> { - backend::net::syscalls::getsockname(sockfd.as_fd()) -} - -/// `getpeername(fd, addr, len)`—Returns the address a socket is connected -/// to. -/// -/// # References -/// - [Beej's Guide to Network Programming] -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [Winsock] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#getpeernamewho-are-you -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpeername.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpeername.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpeername.2.html -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getpeername -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getpeername.2 -/// [OpenBSD]: https://man.openbsd.org/getpeername.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getpeername§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/getpeername -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Who-is-Connected.html -#[inline] -pub fn getpeername<Fd: AsFd>(sockfd: Fd) -> io::Result<Option<SocketAddrAny>> { - backend::net::syscalls::getpeername(sockfd.as_fd()) -} diff --git a/vendor/rustix/src/net/socket_addr_any.rs b/vendor/rustix/src/net/socket_addr_any.rs deleted file mode 100644 index 7a953044..00000000 --- a/vendor/rustix/src/net/socket_addr_any.rs +++ /dev/null @@ -1,344 +0,0 @@ -//! The [`SocketAddrAny`] type and related utilities. - -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::backend::net::read_sockaddr; -use crate::io::Errno; -use crate::net::addr::{SocketAddrArg, SocketAddrLen, SocketAddrOpaque, SocketAddrStorage}; -#[cfg(unix)] -use crate::net::SocketAddrUnix; -use crate::net::{AddressFamily, SocketAddr, SocketAddrV4, SocketAddrV6}; -use core::fmt; -use core::mem::{size_of, MaybeUninit}; -use core::num::NonZeroU32; - -/// Temporary buffer for creating a `SocketAddrAny` from a syscall that writes -/// to a `sockaddr_t` and `socklen_t` -/// -/// Unlike `SocketAddrAny`, this does not maintain the invariant that `len` -/// bytes are initialized. -pub(crate) struct SocketAddrBuf { - pub(crate) len: c::socklen_t, - pub(crate) storage: MaybeUninit<SocketAddrStorage>, -} - -impl SocketAddrBuf { - #[inline] - pub(crate) const fn new() -> Self { - Self { - len: size_of::<SocketAddrStorage>() as c::socklen_t, - storage: MaybeUninit::<SocketAddrStorage>::uninit(), - } - } - - /// Convert the buffer into [`SocketAddrAny`]. - /// - /// # Safety - /// - /// A valid address must have been written into `self.storage` and its - /// length written into `self.len`. - #[inline] - pub(crate) unsafe fn into_any(self) -> SocketAddrAny { - SocketAddrAny::new(self.storage, bitcast!(self.len)) - } - - /// Convert the buffer into [`Option<SocketAddrAny>`]. - /// - /// This returns `None` if `len` is zero or other platform-specific - /// conditions define the address as empty. - /// - /// # Safety - /// - /// Either valid address must have been written into `self.storage` and its - /// length written into `self.len`, or `self.len` must have been set to 0. - #[inline] - pub(crate) unsafe fn into_any_option(self) -> Option<SocketAddrAny> { - let len = bitcast!(self.len); - if read_sockaddr::sockaddr_nonempty(self.storage.as_ptr().cast(), len) { - Some(SocketAddrAny::new(self.storage, len)) - } else { - None - } - } -} - -/// A type that can hold any kind of socket address, as a safe abstraction for -/// `sockaddr_storage`. -/// -/// Socket addresses can be converted to `SocketAddrAny` via the [`From`] and -/// [`Into`] traits. `SocketAddrAny` can be converted back to a specific socket -/// address type with [`TryFrom`] and [`TryInto`]. These implementations return -/// [`Errno::AFNOSUPPORT`] if the address family does not match the requested -/// type. -#[derive(Clone)] -#[doc(alias = "sockaddr_storage")] -pub struct SocketAddrAny { - // Invariants: - // - `len` is at least `size_of::<backend::c::sa_family_t>()` - // - `len` is at most `size_of::<SocketAddrStorage>()` - // - The first `len` bytes of `storage` are initialized. - pub(crate) len: NonZeroU32, - pub(crate) storage: MaybeUninit<SocketAddrStorage>, -} - -impl SocketAddrAny { - /// Creates a socket address from `storage`, which is initialized for `len` - /// bytes. - /// - /// # Panics - /// - /// if `len` is smaller than the sockaddr header or larger than - /// `SocketAddrStorage`. - /// - /// # Safety - /// - /// - `storage` must contain a valid socket address. - /// - `len` bytes must be initialized. - #[inline] - pub const unsafe fn new(storage: MaybeUninit<SocketAddrStorage>, len: SocketAddrLen) -> Self { - assert!(len as usize >= size_of::<read_sockaddr::sockaddr_header>()); - assert!(len as usize <= size_of::<SocketAddrStorage>()); - let len = NonZeroU32::new_unchecked(len); - Self { storage, len } - } - - /// Creates a socket address from reading from `ptr`, which points at `len` - /// initialized bytes. - /// - /// # Panics - /// - /// if `len` is smaller than the sockaddr header or larger than - /// `SocketAddrStorage`. - /// - /// # Safety - /// - /// - `ptr` must be a pointer to memory containing a valid socket address. - /// - `len` bytes must be initialized. - pub unsafe fn read(ptr: *const SocketAddrStorage, len: SocketAddrLen) -> Self { - assert!(len as usize >= size_of::<read_sockaddr::sockaddr_header>()); - assert!(len as usize <= size_of::<SocketAddrStorage>()); - let mut storage = MaybeUninit::<SocketAddrStorage>::uninit(); - core::ptr::copy_nonoverlapping( - ptr.cast::<u8>(), - storage.as_mut_ptr().cast::<u8>(), - len as usize, - ); - let len = NonZeroU32::new_unchecked(len); - Self { storage, len } - } - - /// Gets the initialized part of the storage as bytes. - #[inline] - fn bytes(&self) -> &[u8] { - let len = self.len.get() as usize; - unsafe { core::slice::from_raw_parts(self.storage.as_ptr().cast(), len) } - } - - /// Gets the address family of this socket address. - #[inline] - pub fn address_family(&self) -> AddressFamily { - // SAFETY: Our invariants maintain that the `sa_family` field is - // initialized. - unsafe { - AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family( - self.storage.as_ptr().cast(), - )) - } - } - - /// Returns a raw pointer to the sockaddr. - #[inline] - pub fn as_ptr(&self) -> *const SocketAddrStorage { - self.storage.as_ptr() - } - - /// Returns a raw mutable pointer to the sockaddr. - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut SocketAddrStorage { - self.storage.as_mut_ptr() - } - - /// Returns the length of the encoded sockaddr. - #[inline] - pub fn addr_len(&self) -> SocketAddrLen { - self.len.get() - } -} - -impl PartialEq<Self> for SocketAddrAny { - fn eq(&self, other: &Self) -> bool { - self.bytes() == other.bytes() - } -} - -impl Eq for SocketAddrAny {} - -// This just forwards to another `partial_cmp`. -#[allow(clippy::non_canonical_partial_ord_impl)] -impl PartialOrd<Self> for SocketAddrAny { - fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { - self.bytes().partial_cmp(other.bytes()) - } -} - -impl Ord for SocketAddrAny { - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.bytes().cmp(other.bytes()) - } -} - -impl core::hash::Hash for SocketAddrAny { - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { - self.bytes().hash(state) - } -} - -impl fmt::Debug for SocketAddrAny { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.address_family() { - AddressFamily::INET => { - if let Ok(addr) = SocketAddrV4::try_from(self.clone()) { - return addr.fmt(f); - } - } - AddressFamily::INET6 => { - if let Ok(addr) = SocketAddrV6::try_from(self.clone()) { - return addr.fmt(f); - } - } - #[cfg(unix)] - AddressFamily::UNIX => { - if let Ok(addr) = SocketAddrUnix::try_from(self.clone()) { - return addr.fmt(f); - } - } - #[cfg(target_os = "linux")] - AddressFamily::XDP => { - if let Ok(addr) = crate::net::xdp::SocketAddrXdp::try_from(self.clone()) { - return addr.fmt(f); - } - } - #[cfg(linux_kernel)] - AddressFamily::NETLINK => { - if let Ok(addr) = crate::net::netlink::SocketAddrNetlink::try_from(self.clone()) { - return addr.fmt(f); - } - } - _ => {} - } - - f.debug_struct("SocketAddrAny") - .field("address_family", &self.address_family()) - .field("namelen", &self.addr_len()) - .finish() - } -} - -// SAFETY: `with_sockaddr` calls `f` with a pointer to its own storage. -unsafe impl SocketAddrArg for SocketAddrAny { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - f(self.as_ptr().cast(), self.addr_len()) - } -} - -impl From<SocketAddr> for SocketAddrAny { - #[inline] - fn from(from: SocketAddr) -> Self { - from.as_any() - } -} - -impl TryFrom<SocketAddrAny> for SocketAddr { - type Error = Errno; - - /// Convert if the address is an IPv4 or IPv6 address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not IPv4 or - /// IPv6. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - match value.address_family() { - AddressFamily::INET => read_sockaddr::read_sockaddr_v4(&value).map(SocketAddr::V4), - AddressFamily::INET6 => read_sockaddr::read_sockaddr_v6(&value).map(SocketAddr::V6), - _ => Err(Errno::AFNOSUPPORT), - } - } -} - -impl From<SocketAddrV4> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrV4) -> Self { - from.as_any() - } -} - -impl TryFrom<SocketAddrAny> for SocketAddrV4 { - type Error = Errno; - - /// Convert if the address is an IPv4 address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not IPv4. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr::read_sockaddr_v4(&value) - } -} - -impl From<SocketAddrV6> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrV6) -> Self { - from.as_any() - } -} - -impl TryFrom<SocketAddrAny> for SocketAddrV6 { - type Error = Errno; - - /// Convert if the address is an IPv6 address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not IPv6. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr::read_sockaddr_v6(&value) - } -} - -#[cfg(unix)] -impl From<SocketAddrUnix> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrUnix) -> Self { - from.as_any() - } -} - -#[cfg(unix)] -impl TryFrom<SocketAddrAny> for SocketAddrUnix { - type Error = Errno; - - /// Convert if the address is a Unix socket address. - /// - /// Returns `Err(Errno::AFNOSUPPORT)` if the address family is not Unix. - #[inline] - fn try_from(value: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr::read_sockaddr_unix(&value) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn any_read() { - let localhost = std::net::Ipv6Addr::LOCALHOST; - let addr = SocketAddrAny::from(SocketAddrV6::new(localhost, 7, 8, 9)); - unsafe { - let same = SocketAddrAny::read(addr.as_ptr(), addr.addr_len()); - assert_eq!(addr, same); - } - } -} diff --git a/vendor/rustix/src/net/socketpair.rs b/vendor/rustix/src/net/socketpair.rs deleted file mode 100644 index 29227f96..00000000 --- a/vendor/rustix/src/net/socketpair.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::fd::OwnedFd; -use crate::net::{AddressFamily, Protocol, SocketFlags, SocketType}; -use crate::{backend, io}; - -/// `socketpair(domain, type_ | accept_flags, protocol)`—Create a pair of -/// sockets that are connected to each other. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socketpair.html -/// [Linux]: https://man7.org/linux/man-pages/man2/socketpair.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socketpair.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socketpair&sektion=2 -/// [NetBSD]: https://man.netbsd.org/socketpair.2 -/// [OpenBSD]: https://man.openbsd.org/socketpair.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socketpair§ion=2 -/// [illumos]: https://illumos.org/man/3SOCKET/socketpair -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Socket-Pairs.html -#[inline] -pub fn socketpair( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Option<Protocol>, -) -> io::Result<(OwnedFd, OwnedFd)> { - backend::net::syscalls::socketpair(domain, type_, flags, protocol) -} diff --git a/vendor/rustix/src/net/sockopt.rs b/vendor/rustix/src/net/sockopt.rs deleted file mode 100644 index ef8176ae..00000000 --- a/vendor/rustix/src/net/sockopt.rs +++ /dev/null @@ -1,1649 +0,0 @@ -//! `getsockopt` and `setsockopt` functions. -//! -//! In the rustix API, there is a separate function for each option, so that it -//! can be given an option-specific type signature. -//! -//! # References for all getter functions: -//! -//! - [POSIX `getsockopt`] -//! - [Linux `getsockopt`] -//! - [Winsock `getsockopt`] -//! - [Apple `getsockopt`] -//! - [FreeBSD `getsockopt`] -//! - [NetBSD `getsockopt`] -//! - [OpenBSD `getsockopt`] -//! - [DragonFly BSD `getsockopt`] -//! - [illumos `getsockopt`] -//! - [glibc `getsockopt`] -//! -//! [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsockopt.html -//! [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html -//! [Winsock `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt -//! [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html -//! [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2 -//! [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2 -//! [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2 -//! [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt§ion=2 -//! [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt -//! [glibc `getsockopt`]: https://sourceware.org/glibc/manual/latest/html_node/Socket-Option-Functions.html -//! -//! # References for all `set_*` functions: -//! -//! - [POSIX `setsockopt`] -//! - [Linux `setsockopt`] -//! - [Winsock `setsockopt`] -//! - [Apple `setsockopt`] -//! - [FreeBSD `setsockopt`] -//! - [NetBSD `setsockopt`] -//! - [OpenBSD `setsockopt`] -//! - [DragonFly BSD `setsockopt`] -//! - [illumos `setsockopt`] -//! - [glibc `setsockopt`] -//! -//! [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setsockopt.html -//! [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html -//! [Winsock `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt -//! [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html -//! [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2 -//! [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2 -//! [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2 -//! [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt§ion=2 -//! [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt -//! [glibc `setsockopt`]: https://sourceware.org/glibc/manual/latest/html_node/Socket-Option-Functions.html -//! -//! # References for `get_socket_*` and `set_socket_*` functions: -//! -//! - [References for all getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `sys/socket.h`] -//! - [Linux `socket`] -//! - [Winsock `SOL_SOCKET` options] -//! - [glibc `SOL_SOCKET` Options] -//! -//! [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html -//! [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html -//! [Winsock `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options -//! [glibc `SOL_SOCKET` options]: https://sourceware.org/glibc/manual/latest/html_node/Socket_002dLevel-Options.html -//! -//! # References for `get_ip_*` and `set_ip_*` functions: -//! -//! - [References for all getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `netinet/in.h`] -//! - [Linux `ip`] -//! - [Winsock `IPPROTO_IP` options] -//! - [Apple `ip`] -//! - [FreeBSD `ip`] -//! - [NetBSD `ip`] -//! - [OpenBSD `ip`] -//! - [DragonFly BSD `ip`] -//! - [illumos `ip`] -//! -//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_in.h.html -//! [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html -//! [Winsock `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options -//! [Apple `ip`]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/ip.4 -//! [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4 -//! [NetBSD `ip`]: https://man.netbsd.org/ip.4 -//! [OpenBSD `ip`]: https://man.openbsd.org/ip.4 -//! [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip§ion=4 -//! [illumos `ip`]: https://illumos.org/man/4P/ip -//! -//! # References for `get_ipv6_*` and `set_ipv6_*` functions: -//! -//! - [References for all getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `netinet/in.h`] -//! - [Linux `ipv6`] -//! - [Winsock `IPPROTO_IPV6` options] -//! - [Apple `ip6`] -//! - [FreeBSD `ip6`] -//! - [NetBSD `ip6`] -//! - [OpenBSD `ip6`] -//! - [DragonFly BSD `ip6`] -//! - [illumos `ip6`] -//! -//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_in.h.html -//! [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html -//! [Winsock `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options -//! [Apple `ip6`]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/ip6.4 -//! [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4 -//! [NetBSD `ip6`]: https://man.netbsd.org/ip6.4 -//! [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4 -//! [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6§ion=4 -//! [illumos `ip6`]: https://illumos.org/man/4P/ip6 -//! -//! # References for `get_tcp_*` and `set_tcp_*` functions: -//! -//! - [References for all getter functions] -//! - [References for all `set_*` functions] -//! - [POSIX `netinet/tcp.h`] -//! - [Linux `tcp`] -//! - [Winsock `IPPROTO_TCP` options] -//! - [Apple `tcp`] -//! - [FreeBSD `tcp`] -//! - [NetBSD `tcp`] -//! - [OpenBSD `tcp`] -//! - [DragonFly BSD `tcp`] -//! - [illumos `tcp`] -//! -//! [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_tcp.h.html -//! [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html -//! [Winsock `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options -//! [Apple `tcp`]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/tcp.4 -//! [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4 -//! [NetBSD `tcp`]: https://man.netbsd.org/tcp.4 -//! [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4 -//! [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp§ion=4 -//! [illumos `tcp`]: https://illumos.org/man/4P/tcp -//! -//! [References for all getter functions]: #references-for-all-getter-functions -//! [References for all `set_*` functions]: #references-for-all-set_-functions - -#![doc(alias = "getsockopt")] -#![doc(alias = "setsockopt")] - -#[cfg(target_os = "linux")] -use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpStatistics, XdpUmemReg}; -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "netbsd", - target_os = "nto", - target_os = "vita", -)))] -use crate::net::AddressFamily; -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -use crate::net::Protocol; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -use crate::net::SocketAddrV4; -#[cfg(linux_kernel)] -use crate::net::SocketAddrV6; -use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; -use crate::{backend, io}; -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -use alloc::string::String; -use backend::c; -use backend::fd::AsFd; -use core::time::Duration; - -/// Timeout identifier for use with [`set_socket_timeout`] and -/// [`socket_timeout`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Timeout { - /// `SO_RCVTIMEO`—Timeout for receiving. - Recv = c::SO_RCVTIMEO as _, - - /// `SO_SNDTIMEO`—Timeout for sending. - Send = c::SO_SNDTIMEO as _, -} - -/// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_TYPE")] -pub fn socket_type<Fd: AsFd>(fd: Fd) -> io::Result<SocketType> { - backend::net::sockopt::socket_type(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`—Set whether local -/// addresses may be reused in `bind`. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_REUSEADDR")] -pub fn set_socket_reuseaddr<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_reuseaddr(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_REUSEADDR")] -pub fn socket_reuseaddr<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_reuseaddr(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_BROADCAST")] -pub fn set_socket_broadcast<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_broadcast(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_BROADCAST")] -pub fn socket_broadcast<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_broadcast(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_LINGER")] -pub fn set_socket_linger<Fd: AsFd>(fd: Fd, value: Option<Duration>) -> io::Result<()> { - backend::net::sockopt::set_socket_linger(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_LINGER)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_LINGER")] -pub fn socket_linger<Fd: AsFd>(fd: Fd) -> io::Result<Option<Duration>> { - backend::net::sockopt::socket_linger(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "SO_PASSCRED")] -pub fn set_socket_passcred<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_passcred(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "SO_PASSCRED")] -pub fn socket_passcred<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_passcred(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, id, value)`—Set the sending or receiving -/// timeout. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_RCVTIMEO")] -#[doc(alias = "SO_SNDTIMEO")] -pub fn set_socket_timeout<Fd: AsFd>( - fd: Fd, - id: Timeout, - value: Option<Duration>, -) -> io::Result<()> { - backend::net::sockopt::set_socket_timeout(fd.as_fd(), id, value) -} - -/// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_RCVTIMEO")] -#[doc(alias = "SO_SNDTIMEO")] -pub fn socket_timeout<Fd: AsFd>(fd: Fd, id: Timeout) -> io::Result<Option<Duration>> { - backend::net::sockopt::socket_timeout(fd.as_fd(), id) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_ERROR)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_ERROR")] -pub fn socket_error<Fd: AsFd>(fd: Fd) -> io::Result<Result<(), io::Errno>> { - backend::net::sockopt::socket_error(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[doc(alias = "SO_NOSIGPIPE")] -#[inline] -pub fn socket_nosigpipe<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_nosigpipe(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(apple, freebsdlike, target_os = "netbsd"))] -#[doc(alias = "SO_NOSIGPIPE")] -#[inline] -pub fn set_socket_nosigpipe<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_nosigpipe(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_KEEPALIVE")] -pub fn set_socket_keepalive<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_keepalive(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_KEEPALIVE")] -pub fn socket_keepalive<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_keepalive(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_RCVBUF")] -pub fn set_socket_recv_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -#[doc(alias = "SO_RCVBUFFORCE")] -pub fn set_socket_recv_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_recv_buffer_size_force(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_RCVBUF")] -pub fn socket_recv_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::net::sockopt::socket_recv_buffer_size(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_SNDBUF")] -pub fn set_socket_send_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_send_buffer_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))] -#[inline] -#[doc(alias = "SO_SNDBUFFORCE")] -pub fn set_socket_send_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> { - backend::net::sockopt::set_socket_send_buffer_size_force(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_SNDBUF")] -pub fn socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::net::sockopt::socket_send_buffer_size(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "netbsd", - target_os = "nto", - target_os = "vita", -)))] -#[inline] -#[doc(alias = "SO_DOMAIN")] -pub fn socket_domain<Fd: AsFd>(fd: Fd) -> io::Result<AddressFamily> { - backend::net::sockopt::socket_domain(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it. -#[inline] -#[doc(alias = "SO_ACCEPTCONN")] -pub fn socket_acceptconn<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_acceptconn(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_OOBINLINE")] -pub fn set_socket_oobinline<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_oobinline(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_OOBINLINE)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "SO_OOBINLINE")] -pub fn socket_oobinline<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_oobinline(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[cfg(not(windows))] -#[inline] -#[doc(alias = "SO_REUSEPORT")] -pub fn set_socket_reuseport<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_reuseport(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(not(any(solarish, windows, target_os = "cygwin")))] -#[inline] -#[doc(alias = "SO_REUSEPORT")] -pub fn socket_reuseport<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_reuseport(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "freebsd")] -#[inline] -#[doc(alias = "SO_REUSEPORT_LB")] -pub fn set_socket_reuseport_lb<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_socket_reuseport_lb(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "freebsd")] -#[inline] -#[doc(alias = "SO_REUSEPORT_LB")] -pub fn socket_reuseport_lb<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::socket_reuseport_lb(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_PROTOCOL)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(any( - linux_kernel, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "openbsd", - target_os = "redox", - target_env = "newlib" -))] -#[inline] -#[doc(alias = "SO_PROTOCOL")] -pub fn socket_protocol<Fd: AsFd>(fd: Fd) -> io::Result<Option<Protocol>> { - backend::net::sockopt::socket_protocol(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_COOKIE)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "linux")] -#[inline] -#[doc(alias = "SO_COOKIE")] -pub fn socket_cookie<Fd: AsFd>(fd: Fd) -> io::Result<u64> { - backend::net::sockopt::socket_cookie(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "linux")] -#[inline] -#[doc(alias = "SO_INCOMING_CPU")] -pub fn socket_incoming_cpu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::socket_incoming_cpu(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[cfg(target_os = "linux")] -#[inline] -#[doc(alias = "SO_INCOMING_CPU")] -pub fn set_socket_incoming_cpu<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_socket_incoming_cpu(fd.as_fd(), value) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions -#[inline] -#[doc(alias = "IP_TTL")] -pub fn set_ip_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ip_ttl(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_TTL)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_TTL")] -pub fn ip_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ip_ttl(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_V6ONLY")] -pub fn set_ipv6_v6only<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_v6only(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_V6ONLY")] -pub fn ipv6_v6only<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_v6only(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MTU)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[doc(alias = "IP_MTU")] -pub fn ip_mtu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ip_mtu(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MTU)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[cfg(any(linux_kernel, target_os = "cygwin"))] -#[doc(alias = "IPV6_MTU")] -pub fn ipv6_mtu<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_mtu(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_IF")] -pub fn set_ip_multicast_if<Fd: AsFd>(fd: Fd, value: &Ipv4Addr) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_if(fd.as_fd(), value) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, multiaddr, address, -/// ifindex)` -/// -/// This is similar to [`set_ip_multicast_if`] but additionally allows an -/// `ifindex` value to be given. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -#[doc(alias = "IP_MULTICAST_IF")] -pub fn set_ip_multicast_if_with_ifindex<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_if_with_ifindex(fd.as_fd(), multiaddr, address, ifindex) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_IF")] -pub fn ip_multicast_if<Fd: AsFd>(fd: Fd) -> io::Result<Ipv4Addr> { - backend::net::sockopt::ip_multicast_if(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_IF")] -pub fn set_ipv6_multicast_if<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_if(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_IF")] -pub fn ipv6_multicast_if<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_multicast_if(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_LOOP")] -pub fn set_ip_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_loop(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_LOOP")] -pub fn ip_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ip_multicast_loop(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_TTL")] -pub fn set_ip_multicast_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ip_multicast_ttl(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_MULTICAST_TTL")] -pub fn ip_multicast_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ip_multicast_ttl(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_LOOP")] -pub fn set_ipv6_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_LOOP")] -pub fn ipv6_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_multicast_loop(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn ipv6_unicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u8> { - backend::net::sockopt::ipv6_unicast_hops(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_UNICAST_HOPS")] -pub fn set_ipv6_unicast_hops<Fd: AsFd>(fd: Fd, value: Option<u8>) -> io::Result<()> { - backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_HOPS")] -pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_MULTICAST_HOPS")] -pub fn ipv6_multicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_multicast_hops(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` -/// -/// This is similar to [`set_ip_add_membership`] but always sets the `ifindex` -/// value to zero. See [`set_ip_add_membership_with_ifindex`] instead to also -/// give the `ifindex` value. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_ADD_MEMBERSHIP")] -pub fn set_ip_add_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, address, -/// ifindex)` -/// -/// This is similar to [`set_ip_add_membership`] but additionally allows an -/// `ifindex` value to be given. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -#[doc(alias = "IP_ADD_MEMBERSHIP")] -pub fn set_ip_add_membership_with_ifindex<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ip_add_membership_with_ifindex( - fd.as_fd(), - multiaddr, - address, - ifindex, - ) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -#[doc(alias = "IP_ADD_SOURCE_MEMBERSHIP")] -pub fn set_ip_add_source_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - backend::net::sockopt::set_ip_add_source_membership( - fd.as_fd(), - multiaddr, - interface, - sourceaddr, - ) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))] -#[inline] -#[doc(alias = "IP_DROP_SOURCE_MEMBERSHIP")] -pub fn set_ip_drop_source_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - sourceaddr: &Ipv4Addr, -) -> io::Result<()> { - backend::net::sockopt::set_ip_drop_source_membership( - fd.as_fd(), - multiaddr, - interface, - sourceaddr, - ) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_JOIN_GROUP")] -#[doc(alias = "IPV6_ADD_MEMBERSHIP")] -pub fn set_ipv6_add_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` -/// -/// This is similar to [`set_ip_drop_membership`] but always sets `ifindex` -/// value to zero. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[inline] -#[doc(alias = "IP_DROP_MEMBERSHIP")] -pub fn set_ip_drop_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, -) -> io::Result<()> { - backend::net::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` -/// -/// This is similar to [`set_ip_drop_membership_with_ifindex`] but additionally -/// allows a `ifindex` value to be given. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - apple, - freebsdlike, - linux_like, - target_os = "fuchsia", - target_os = "openbsd" -))] -#[inline] -#[doc(alias = "IP_DROP_MEMBERSHIP")] -pub fn set_ip_drop_membership_with_ifindex<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv4Addr, - address: &Ipv4Addr, - ifindex: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ip_drop_membership_with_ifindex( - fd.as_fd(), - multiaddr, - address, - ifindex, - ) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[inline] -#[doc(alias = "IPV6_LEAVE_GROUP")] -#[doc(alias = "IPV6_DROP_MEMBERSHIP")] -pub fn set_ipv6_drop_membership<Fd: AsFd>( - fd: Fd, - multiaddr: &Ipv6Addr, - interface: u32, -) -> io::Result<()> { - backend::net::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_TOS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto", - target_env = "newlib" -))] -#[inline] -#[doc(alias = "IP_TOS")] -pub fn set_ip_tos<Fd: AsFd>(fd: Fd, value: u8) -> io::Result<()> { - backend::net::sockopt::set_ip_tos(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_TOS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto", - target_env = "newlib" -))] -#[inline] -#[doc(alias = "IP_TOS")] -pub fn ip_tos<Fd: AsFd>(fd: Fd) -> io::Result<u8> { - backend::net::sockopt::ip_tos(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_RECVTOS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -#[doc(alias = "IP_RECVTOS")] -pub fn set_ip_recvtos<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ip_recvtos(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_RECVTOS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions -#[cfg(any( - apple, - linux_like, - target_os = "cygwin", - target_os = "freebsd", - target_os = "fuchsia", -))] -#[inline] -#[doc(alias = "IP_RECVTOS")] -pub fn ip_recvtos<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ip_recvtos(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -#[doc(alias = "IPV6_RECVTCLASS")] -pub fn set_ipv6_recvtclass<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_recvtclass(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any( - bsd, - linux_like, - target_os = "aix", - target_os = "fuchsia", - target_os = "nto" -))] -#[inline] -#[doc(alias = "IPV6_RECVTCLASS")] -pub fn ipv6_recvtclass<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_recvtclass(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IP, IP_FREEBIND, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "IP_FREEBIND")] -pub fn set_ip_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ip_freebind(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IP, IP_FREEBIND)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "IP_FREEBIND")] -pub fn ip_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ip_freebind(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "IPV6_FREEBIND")] -pub fn set_ipv6_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_ipv6_freebind(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "IPV6_FREEBIND")] -pub fn ipv6_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::ipv6_freebind(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST)` -/// -/// Even though this corresponds to a `SO_*` constant, it is an `IPPROTO_IP` -/// option. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "SO_ORIGINAL_DST")] -pub fn ip_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV4> { - backend::net::sockopt::ip_original_dst(fd.as_fd()) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST)` -/// -/// Even though this corresponds to a `IP6T_*` constant, it is an -/// `IPPROTO_IPV6` option. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(linux_kernel)] -#[inline] -#[doc(alias = "IP6T_SO_ORIGINAL_DST")] -pub fn ipv6_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV6> { - backend::net::sockopt::ipv6_original_dst(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -#[doc(alias = "IPV6_TCLASS")] -pub fn set_ipv6_tclass<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_ipv6_tclass(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" -)))] -#[inline] -#[doc(alias = "IPV6_TCLASS")] -pub fn ipv6_tclass<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::ipv6_tclass(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[inline] -#[doc(alias = "TCP_NODELAY")] -pub fn set_tcp_nodelay<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_nodelay(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[inline] -#[doc(alias = "TCP_NODELAY")] -pub fn tcp_nodelay<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_nodelay(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPCNT")] -pub fn set_tcp_keepcnt<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_tcp_keepcnt(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPCNT")] -pub fn tcp_keepcnt<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::tcp_keepcnt(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)` -/// -/// `TCP_KEEPALIVE` on Apple platforms. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -#[inline] -#[doc(alias = "TCP_KEEPIDLE")] -pub fn set_tcp_keepidle<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> { - backend::net::sockopt::set_tcp_keepidle(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)` -/// -/// `TCP_KEEPALIVE` on Apple platforms. -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))] -#[inline] -#[doc(alias = "TCP_KEEPIDLE")] -pub fn tcp_keepidle<Fd: AsFd>(fd: Fd) -> io::Result<Duration> { - backend::net::sockopt::tcp_keepidle(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPINTVL")] -pub fn set_tcp_keepintvl<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> { - backend::net::sockopt::set_tcp_keepintvl(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(not(any( - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - target_os = "redox" -)))] -#[inline] -#[doc(alias = "TCP_KEEPINTVL")] -pub fn tcp_keepintvl<Fd: AsFd>(fd: Fd) -> io::Result<Duration> { - backend::net::sockopt::tcp_keepintvl(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_USER_TIMEOUT")] -pub fn set_tcp_user_timeout<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_tcp_user_timeout(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_USER_TIMEOUT")] -pub fn tcp_user_timeout<Fd: AsFd>(fd: Fd) -> io::Result<u32> { - backend::net::sockopt::tcp_user_timeout(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_QUICKACK")] -pub fn set_tcp_quickack<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_quickack(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_QUICKACK)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_QUICKACK")] -pub fn tcp_quickack<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_quickack(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -#[doc(alias = "TCP_CONGESTION")] -pub fn set_tcp_congestion<Fd: AsFd>(fd: Fd, value: &str) -> io::Result<()> { - backend::net::sockopt::set_tcp_congestion(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(feature = "alloc")] -#[cfg(any( - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" -))] -#[inline] -#[doc(alias = "TCP_CONGESTION")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn tcp_congestion<Fd: AsFd>(fd: Fd) -> io::Result<String> { - backend::net::sockopt::tcp_congestion(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")] -pub fn set_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_thin_linear_timeouts(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")] -pub fn tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_thin_linear_timeouts(fd.as_fd()) -} - -/// `setsockopt(fd, IPPROTO_TCP, TCP_CORK, value)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_CORK")] -pub fn set_tcp_cork<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> { - backend::net::sockopt::set_tcp_cork(fd.as_fd(), value) -} - -/// `getsockopt(fd, IPPROTO_TCP, TCP_CORK)` -/// -/// See the [module-level documentation] for more. -/// -/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions -#[cfg(any(linux_like, solarish, target_os = "fuchsia"))] -#[inline] -#[doc(alias = "TCP_CORK")] -pub fn tcp_cork<Fd: AsFd>(fd: Fd) -> io::Result<bool> { - backend::net::sockopt::tcp_cork(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_SOCKET, SO_PEERCRED)`—Get credentials of Unix domain -/// socket peer process. -/// -/// # References -/// - [Linux `unix`] -/// -/// [Linux `unix`]: https://man7.org/linux/man-pages/man7/unix.7.html -#[cfg(linux_kernel)] -#[doc(alias = "SO_PEERCRED")] -pub fn socket_peercred<Fd: AsFd>(fd: Fd) -> io::Result<super::UCred> { - backend::net::sockopt::socket_peercred(fd.as_fd()) -} - -/// `setsockopt(fd, SOL_XDP, XDP_UMEM_REG, value)` -/// -/// On kernel versions only supporting v1, the flags are ignored. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-umem-reg-setsockopt -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_UMEM_REG")] -pub fn set_xdp_umem_reg<Fd: AsFd>(fd: Fd, value: XdpUmemReg) -> io::Result<()> { - backend::net::sockopt::set_xdp_umem_reg(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_UMEM_FILL_RING")] -pub fn set_xdp_umem_fill_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_umem_fill_ring_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_UMEM_COMPLETION_RING")] -pub fn set_xdp_umem_completion_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_umem_completion_ring_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_TX_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_TX_RING")] -pub fn set_xdp_tx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_tx_ring_size(fd.as_fd(), value) -} - -/// `setsockopt(fd, SOL_XDP, XDP_RX_RING, value)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_RX_RING")] -pub fn set_xdp_rx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> { - backend::net::sockopt::set_xdp_rx_ring_size(fd.as_fd(), value) -} - -/// `getsockopt(fd, SOL_XDP, XDP_MMAP_OFFSETS)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_MMAP_OFFSETS")] -pub fn xdp_mmap_offsets<Fd: AsFd>(fd: Fd) -> io::Result<XdpMmapOffsets> { - backend::net::sockopt::xdp_mmap_offsets(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_XDP, XDP_STATISTICS)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-statistics-getsockopt -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_STATISTICS")] -pub fn xdp_statistics<Fd: AsFd>(fd: Fd) -> io::Result<XdpStatistics> { - backend::net::sockopt::xdp_statistics(fd.as_fd()) -} - -/// `getsockopt(fd, SOL_XDP, XDP_OPTIONS)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-options-getsockopt -#[cfg(target_os = "linux")] -#[doc(alias = "XDP_OPTIONS")] -pub fn xdp_options<Fd: AsFd>(fd: Fd) -> io::Result<XdpOptionsFlags> { - backend::net::sockopt::xdp_options(fd.as_fd()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - use c::c_int; - - // Backend code needs to cast these to `c_int` so make sure that cast - // isn't lossy. - assert_eq_size!(Timeout, c_int); - } -} diff --git a/vendor/rustix/src/net/types.rs b/vendor/rustix/src/net/types.rs deleted file mode 100644 index 057f944d..00000000 --- a/vendor/rustix/src/net/types.rs +++ /dev/null @@ -1,2132 +0,0 @@ -//! Types and constants for `rustix::net`. - -use crate::backend::c; -use crate::ffi; -use bitflags::bitflags; - -/// A type for holding raw integer socket types. -pub type RawSocketType = u32; - -/// `SOCK_*` constants for use with [`socket`]. -/// -/// [`socket`]: crate::net::socket() -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct SocketType(pub(crate) RawSocketType); - -#[rustfmt::skip] -impl SocketType { - /// `SOCK_STREAM` - pub const STREAM: Self = Self(c::SOCK_STREAM as _); - - /// `SOCK_DGRAM` - pub const DGRAM: Self = Self(c::SOCK_DGRAM as _); - - /// `SOCK_SEQPACKET` - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET as _); - - /// `SOCK_RAW` - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] - pub const RAW: Self = Self(c::SOCK_RAW as _); - - /// `SOCK_RDM` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox" - )))] - pub const RDM: Self = Self(c::SOCK_RDM as _); - - /// Constructs a `SocketType` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawSocketType) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `SocketType`. - #[inline] - pub const fn as_raw(self) -> RawSocketType { - self.0 - } -} - -/// A type for holding raw integer address families. -pub type RawAddressFamily = crate::ffi::c_ushort; - -/// `AF_*` constants for use with [`socket`], [`socket_with`], and -/// [`socketpair`]. -/// -/// [`socket`]: crate::net::socket() -/// [`socket_with`]: crate::net::socket_with -/// [`socketpair`]: crate::net::socketpair() -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct AddressFamily(pub(crate) RawAddressFamily); - -#[rustfmt::skip] -#[allow(non_upper_case_globals)] -impl AddressFamily { - /// `AF_UNSPEC` - pub const UNSPEC: Self = Self(c::AF_UNSPEC as _); - /// `AF_INET` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/ip.7.html - pub const INET: Self = Self(c::AF_INET as _); - /// `AF_INET6` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/ipv6.7.html - pub const INET6: Self = Self(c::AF_INET6 as _); - /// `AF_NETLINK` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/netlink.7.html - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const NETLINK: Self = Self(c::AF_NETLINK as _); - /// `AF_UNIX`, aka `AF_LOCAL` - #[doc(alias = "LOCAL")] - pub const UNIX: Self = Self(c::AF_UNIX as _); - /// `AF_AX25` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const AX25: Self = Self(c::AF_AX25 as _); - /// `AF_IPX` - #[cfg(not(any( - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const IPX: Self = Self(c::AF_IPX as _); - /// `AF_APPLETALK` - #[cfg(not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const APPLETALK: Self = Self(c::AF_APPLETALK as _); - /// `AF_NETROM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const NETROM: Self = Self(c::AF_NETROM as _); - /// `AF_BRIDGE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); - /// `AF_ATMPVC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); - /// `AF_X25` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const X25: Self = Self(c::AF_X25 as _); - /// `AF_ROSE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ROSE: Self = Self(c::AF_ROSE as _); - /// `AF_DECnet` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const DECnet: Self = Self(c::AF_DECnet as _); - /// `AF_NETBEUI` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); - /// `AF_SECURITY` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const SECURITY: Self = Self(c::AF_SECURITY as _); - /// `AF_KEY` - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const KEY: Self = Self(c::AF_KEY as _); - /// `AF_PACKET` - /// - /// # References - /// - [Linux] - /// - /// [Linux]: https://man7.org/linux/man-pages/man7/packet.7.html - #[cfg(not(any( - bsd, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const PACKET: Self = Self(c::AF_PACKET as _); - /// `AF_ASH` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ASH: Self = Self(c::AF_ASH as _); - /// `AF_ECONET` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ECONET: Self = Self(c::AF_ECONET as _); - /// `AF_ATMSVC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); - /// `AF_RDS` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const RDS: Self = Self(c::AF_RDS as _); - /// `AF_SNA` - #[cfg(not(any( - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const SNA: Self = Self(c::AF_SNA as _); - /// `AF_IRDA` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const IRDA: Self = Self(c::AF_IRDA as _); - /// `AF_PPPOX` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const PPPOX: Self = Self(c::AF_PPPOX as _); - /// `AF_WANPIPE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); - /// `AF_LLC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const LLC: Self = Self(c::AF_LLC as _); - /// `AF_CAN` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const CAN: Self = Self(c::AF_CAN as _); - /// `AF_TIPC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const TIPC: Self = Self(c::AF_TIPC as _); - /// `AF_BLUETOOTH` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - )))] - pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); - /// `AF_IUCV` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const IUCV: Self = Self(c::AF_IUCV as _); - /// `AF_RXRPC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const RXRPC: Self = Self(c::AF_RXRPC as _); - /// `AF_ISDN` - #[cfg(not(any( - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - )))] - pub const ISDN: Self = Self(c::AF_ISDN as _); - /// `AF_PHONET` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const PHONET: Self = Self(c::AF_PHONET as _); - /// `AF_IEEE802154` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const IEEE802154: Self = Self(c::AF_IEEE802154 as _); - /// `AF_802` - #[cfg(solarish)] - pub const EIGHT_ZERO_TWO: Self = Self(c::AF_802 as _); - #[cfg(target_os = "fuchsia")] - /// `AF_ALG` - pub const ALG: Self = Self(c::AF_ALG as _); - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "nto"))] - /// `AF_ARP` - pub const ARP: Self = Self(c::AF_ARP as _); - /// `AF_ATM` - #[cfg(freebsdlike)] - pub const ATM: Self = Self(c::AF_ATM as _); - /// `AF_CAIF` - #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia"))] - pub const CAIF: Self = Self(c::AF_CAIF as _); - /// `AF_CCITT` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const CCITT: Self = Self(c::AF_CCITT as _); - /// `AF_CHAOS` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const CHAOS: Self = Self(c::AF_CHAOS as _); - /// `AF_CNT` - #[cfg(any(bsd, target_os = "nto"))] - pub const CNT: Self = Self(c::AF_CNT as _); - /// `AF_COIP` - #[cfg(any(bsd, target_os = "nto"))] - pub const COIP: Self = Self(c::AF_COIP as _); - /// `AF_DATAKIT` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const DATAKIT: Self = Self(c::AF_DATAKIT as _); - /// `AF_DLI` - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - ))] - pub const DLI: Self = Self(c::AF_DLI as _); - /// `AF_E164` - #[cfg(any(bsd, target_os = "nto"))] - pub const E164: Self = Self(c::AF_E164 as _); - /// `AF_ECMA` - #[cfg(any( - apple, - freebsdlike, - solarish, - target_os = "aix", - target_os = "nto", - target_os = "openbsd" - ))] - pub const ECMA: Self = Self(c::AF_ECMA as _); - /// `AF_ENCAP` - #[cfg(target_os = "openbsd")] - pub const ENCAP: Self = Self(c::AF_ENCAP as _); - /// `AF_FILE` - #[cfg(solarish)] - pub const FILE: Self = Self(c::AF_FILE as _); - /// `AF_GOSIP` - #[cfg(solarish)] - pub const GOSIP: Self = Self(c::AF_GOSIP as _); - /// `AF_HYLINK` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const HYLINK: Self = Self(c::AF_HYLINK as _); - /// `AF_IB` - #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))] - pub const IB: Self = Self(c::AF_IB as _); - /// `AF_IMPLINK` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const IMPLINK: Self = Self(c::AF_IMPLINK as _); - /// `AF_IEEE80211` - #[cfg(any(apple, freebsdlike, target_os = "netbsd"))] - pub const IEEE80211: Self = Self(c::AF_IEEE80211 as _); - /// `AF_INET6_SDP` - #[cfg(target_os = "freebsd")] - pub const INET6_SDP: Self = Self(c::AF_INET6_SDP as _); - /// `AF_INET_OFFLOAD` - #[cfg(solarish)] - pub const INET_OFFLOAD: Self = Self(c::AF_INET_OFFLOAD as _); - /// `AF_INET_SDP` - #[cfg(target_os = "freebsd")] - pub const INET_SDP: Self = Self(c::AF_INET_SDP as _); - /// `AF_INTF` - #[cfg(target_os = "aix")] - pub const INTF: Self = Self(c::AF_INTF as _); - /// `AF_ISO` - #[cfg(any(bsd, target_os = "aix", target_os = "nto"))] - pub const ISO: Self = Self(c::AF_ISO as _); - /// `AF_LAT` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const LAT: Self = Self(c::AF_LAT as _); - /// `AF_LINK` - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - ))] - pub const LINK: Self = Self(c::AF_LINK as _); - /// `AF_MPLS` - #[cfg(any( - netbsdlike, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "fuchsia" - ))] - pub const MPLS: Self = Self(c::AF_MPLS as _); - /// `AF_NATM` - #[cfg(any(bsd, target_os = "nto"))] - pub const NATM: Self = Self(c::AF_NATM as _); - /// `AF_NBS` - #[cfg(solarish)] - pub const NBS: Self = Self(c::AF_NBS as _); - /// `AF_NCA` - #[cfg(target_os = "illumos")] - pub const NCA: Self = Self(c::AF_NCA as _); - /// `AF_NDD` - #[cfg(target_os = "aix")] - pub const NDD: Self = Self(c::AF_NDD as _); - /// `AF_NDRV` - #[cfg(apple)] - pub const NDRV: Self = Self(c::AF_NDRV as _); - /// `AF_NETBIOS` - #[cfg(any(apple, freebsdlike))] - pub const NETBIOS: Self = Self(c::AF_NETBIOS as _); - /// `AF_NETGRAPH` - #[cfg(freebsdlike)] - pub const NETGRAPH: Self = Self(c::AF_NETGRAPH as _); - /// `AF_NIT` - #[cfg(solarish)] - pub const NIT: Self = Self(c::AF_NIT as _); - /// `AF_NOTIFY` - #[cfg(target_os = "haiku")] - pub const NOTIFY: Self = Self(c::AF_NOTIFY as _); - /// `AF_NFC` - #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))] - pub const NFC: Self = Self(c::AF_NFC as _); - /// `AF_NS` - #[cfg(any(apple, solarish, netbsdlike, target_os = "aix", target_os = "nto"))] - pub const NS: Self = Self(c::AF_NS as _); - /// `AF_OROUTE` - #[cfg(target_os = "netbsd")] - pub const OROUTE: Self = Self(c::AF_OROUTE as _); - /// `AF_OSI` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const OSI: Self = Self(c::AF_OSI as _); - /// `AF_OSINET` - #[cfg(solarish)] - pub const OSINET: Self = Self(c::AF_OSINET as _); - /// `AF_POLICY` - #[cfg(solarish)] - pub const POLICY: Self = Self(c::AF_POLICY as _); - /// `AF_PPP` - #[cfg(apple)] - pub const PPP: Self = Self(c::AF_PPP as _); - /// `AF_PUP` - #[cfg(any(bsd, solarish, target_os = "aix", target_os = "nto"))] - pub const PUP: Self = Self(c::AF_PUP as _); - /// `AF_RIF` - #[cfg(target_os = "aix")] - pub const RIF: Self = Self(c::AF_RIF as _); - /// `AF_ROUTE` - #[cfg(any( - bsd, - solarish, - target_os = "android", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - target_os = "nto" - ))] - pub const ROUTE: Self = Self(c::AF_ROUTE as _); - /// `AF_SCLUSTER` - #[cfg(target_os = "freebsd")] - pub const SCLUSTER: Self = Self(c::AF_SCLUSTER as _); - /// `AF_SIP` - #[cfg(any(apple, target_os = "freebsd", target_os = "openbsd"))] - pub const SIP: Self = Self(c::AF_SIP as _); - /// `AF_SLOW` - #[cfg(target_os = "freebsd")] - pub const SLOW: Self = Self(c::AF_SLOW as _); - /// `AF_SYS_CONTROL` - #[cfg(apple)] - pub const SYS_CONTROL: Self = Self(c::AF_SYS_CONTROL as _); - /// `AF_SYSTEM` - #[cfg(apple)] - pub const SYSTEM: Self = Self(c::AF_SYSTEM as _); - /// `AF_TRILL` - #[cfg(solarish)] - pub const TRILL: Self = Self(c::AF_TRILL as _); - /// `AF_UTUN` - #[cfg(apple)] - pub const UTUN: Self = Self(c::AF_UTUN as _); - /// `AF_VSOCK` - #[cfg(any(apple, target_os = "emscripten", target_os = "fuchsia"))] - pub const VSOCK: Self = Self(c::AF_VSOCK as _); - /// `AF_XDP` - #[cfg(target_os = "linux")] - pub const XDP: Self = Self(c::AF_XDP as _); - - /// Constructs a `AddressFamily` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawAddressFamily) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `AddressFamily`. - #[inline] - pub const fn as_raw(self) -> RawAddressFamily { - self.0 - } -} - -/// A type for holding raw integer protocols. -pub type RawProtocol = core::num::NonZeroU32; - -const fn new_raw_protocol(u: u32) -> RawProtocol { - match RawProtocol::new(u) { - Some(p) => p, - None => panic!("new_raw_protocol: protocol must be non-zero"), - } -} - -/// `IPPROTO_*` and other constants for use with [`socket`], [`socket_with`], -/// and [`socketpair`] when a nondefault value is desired. -/// -/// See the [`ipproto`], [`sysproto`], and [`netlink`] modules for possible -/// values. -/// -/// For the default values, such as `IPPROTO_IP` or `NETLINK_ROUTE`, pass -/// `None` as the `protocol` argument in these functions. -/// -/// [`socket`]: crate::net::socket() -/// [`socket_with`]: crate::net::socket_with -/// [`socketpair`]: crate::net::socketpair() -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -#[doc(alias = "IPPROTO_IP")] -#[doc(alias = "NETLINK_ROUTE")] -pub struct Protocol(pub(crate) RawProtocol); - -/// `IPPROTO_*` constants. -/// -/// For `IPPROTO_IP`, pass `None` as the `protocol` argument. -pub mod ipproto { - use super::{new_raw_protocol, Protocol}; - use crate::backend::c; - - /// `IPPROTO_ICMP` - pub const ICMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMP as _)); - /// `IPPROTO_IGMP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )))] - pub const IGMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IGMP as _)); - /// `IPPROTO_IPIP` - #[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const IPIP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPIP as _)); - /// `IPPROTO_TCP` - pub const TCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TCP as _)); - /// `IPPROTO_EGP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const EGP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_EGP as _)); - /// `IPPROTO_PUP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )))] - pub const PUP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PUP as _)); - /// `IPPROTO_UDP` - pub const UDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDP as _)); - /// `IPPROTO_IDP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "vita" - )))] - pub const IDP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IDP as _)); - /// `IPPROTO_TP` - #[cfg(not(any( - solarish, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const TP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_TP as _)); - /// `IPPROTO_DCCP` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - )))] - pub const DCCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_DCCP as _)); - /// `IPPROTO_IPV6` - pub const IPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_IPV6 as _)); - /// `IPPROTO_RSVP` - #[cfg(not(any( - solarish, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const RSVP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RSVP as _)); - /// `IPPROTO_GRE` - #[cfg(not(any( - solarish, - windows, - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const GRE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_GRE as _)); - /// `IPPROTO_ESP` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const ESP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ESP as _)); - /// `IPPROTO_AH` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const AH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_AH as _)); - /// `IPPROTO_MTP` - #[cfg(not(any( - solarish, - netbsdlike, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MTP as _)); - /// `IPPROTO_BEETPH` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const BEETPH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_BEETPH as _)); - /// `IPPROTO_ENCAP` - #[cfg(not(any( - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const ENCAP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ENCAP as _)); - /// `IPPROTO_PIM` - #[cfg(not(any( - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - )))] - pub const PIM: Protocol = Protocol(new_raw_protocol(c::IPPROTO_PIM as _)); - /// `IPPROTO_COMP` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const COMP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_COMP as _)); - /// `IPPROTO_SCTP` - #[cfg(not(any( - solarish, - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - )))] - pub const SCTP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_SCTP as _)); - /// `IPPROTO_UDPLITE` - #[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const UDPLITE: Protocol = Protocol(new_raw_protocol(c::IPPROTO_UDPLITE as _)); - /// `IPPROTO_MPLS` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "netbsd", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MPLS: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPLS as _)); - /// `IPPROTO_ETHERNET` - #[cfg(linux_kernel)] - pub const ETHERNET: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ETHERNET as _)); - /// `IPPROTO_RAW` - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))] - pub const RAW: Protocol = Protocol(new_raw_protocol(c::IPPROTO_RAW as _)); - /// `IPPROTO_MPTCP` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "aix", - target_os = "cygwin", - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MPTCP: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MPTCP as _)); - /// `IPPROTO_FRAGMENT` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const FRAGMENT: Protocol = Protocol(new_raw_protocol(c::IPPROTO_FRAGMENT as _)); - /// `IPPROTO_ICMPV6` - pub const ICMPV6: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ICMPV6 as _)); - /// `IPPROTO_MH` - #[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "cygwin", - target_os = "dragonfly", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "redox", - target_os = "vita", - )))] - pub const MH: Protocol = Protocol(new_raw_protocol(c::IPPROTO_MH as _)); - /// `IPPROTO_ROUTING` - #[cfg(not(any( - solarish, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "redox", - target_os = "vita" - )))] - pub const ROUTING: Protocol = Protocol(new_raw_protocol(c::IPPROTO_ROUTING as _)); -} - -/// `SYSPROTO_*` constants. -pub mod sysproto { - #[cfg(apple)] - use { - super::{new_raw_protocol, Protocol}, - crate::backend::c, - }; - - /// `SYSPROTO_EVENT` - #[cfg(apple)] - pub const EVENT: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_EVENT as _)); - - /// `SYSPROTO_CONTROL` - #[cfg(apple)] - pub const CONTROL: Protocol = Protocol(new_raw_protocol(c::SYSPROTO_CONTROL as _)); -} - -/// `NETLINK_*` constants. -/// -/// For `NETLINK_ROUTE`, pass `None` as the `protocol` argument. -pub mod netlink { - #[cfg(linux_kernel)] - use { - super::{new_raw_protocol, Protocol}, - crate::backend::c, - crate::backend::net::read_sockaddr::read_sockaddr_netlink, - crate::net::{ - addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque}, - SocketAddrAny, - }, - core::mem, - }; - - /// `NETLINK_UNUSED` - #[cfg(linux_kernel)] - pub const UNUSED: Protocol = Protocol(new_raw_protocol(c::NETLINK_UNUSED as _)); - /// `NETLINK_USERSOCK` - #[cfg(linux_kernel)] - pub const USERSOCK: Protocol = Protocol(new_raw_protocol(c::NETLINK_USERSOCK as _)); - /// `NETLINK_FIREWALL` - #[cfg(linux_kernel)] - pub const FIREWALL: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIREWALL as _)); - /// `NETLINK_SOCK_DIAG` - #[cfg(linux_kernel)] - pub const SOCK_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_SOCK_DIAG as _)); - /// `NETLINK_NFLOG` - #[cfg(linux_kernel)] - pub const NFLOG: Protocol = Protocol(new_raw_protocol(c::NETLINK_NFLOG as _)); - /// `NETLINK_XFRM` - #[cfg(linux_kernel)] - pub const XFRM: Protocol = Protocol(new_raw_protocol(c::NETLINK_XFRM as _)); - /// `NETLINK_SELINUX` - #[cfg(linux_kernel)] - pub const SELINUX: Protocol = Protocol(new_raw_protocol(c::NETLINK_SELINUX as _)); - /// `NETLINK_ISCSI` - #[cfg(linux_kernel)] - pub const ISCSI: Protocol = Protocol(new_raw_protocol(c::NETLINK_ISCSI as _)); - /// `NETLINK_AUDIT` - #[cfg(linux_kernel)] - pub const AUDIT: Protocol = Protocol(new_raw_protocol(c::NETLINK_AUDIT as _)); - /// `NETLINK_FIB_LOOKUP` - #[cfg(linux_kernel)] - pub const FIB_LOOKUP: Protocol = Protocol(new_raw_protocol(c::NETLINK_FIB_LOOKUP as _)); - /// `NETLINK_CONNECTOR` - #[cfg(linux_kernel)] - pub const CONNECTOR: Protocol = Protocol(new_raw_protocol(c::NETLINK_CONNECTOR as _)); - /// `NETLINK_NETFILTER` - #[cfg(linux_kernel)] - pub const NETFILTER: Protocol = Protocol(new_raw_protocol(c::NETLINK_NETFILTER as _)); - /// `NETLINK_IP6_FW` - #[cfg(linux_kernel)] - pub const IP6_FW: Protocol = Protocol(new_raw_protocol(c::NETLINK_IP6_FW as _)); - /// `NETLINK_DNRTMSG` - #[cfg(linux_kernel)] - pub const DNRTMSG: Protocol = Protocol(new_raw_protocol(c::NETLINK_DNRTMSG as _)); - /// `NETLINK_KOBJECT_UEVENT` - #[cfg(linux_kernel)] - pub const KOBJECT_UEVENT: Protocol = Protocol(new_raw_protocol(c::NETLINK_KOBJECT_UEVENT as _)); - /// `NETLINK_GENERIC` - // This is defined on FreeBSD too, but it has the value 0, so it doesn't - // fit in or `NonZeroU32`. It's unclear whether FreeBSD intends - // `NETLINK_GENERIC` to be the default when Linux has `NETLINK_ROUTE` as - // the default. - #[cfg(linux_kernel)] - pub const GENERIC: Protocol = Protocol(new_raw_protocol(c::NETLINK_GENERIC as _)); - /// `NETLINK_SCSITRANSPORT` - #[cfg(linux_kernel)] - pub const SCSITRANSPORT: Protocol = Protocol(new_raw_protocol(c::NETLINK_SCSITRANSPORT as _)); - /// `NETLINK_ECRYPTFS` - #[cfg(linux_kernel)] - pub const ECRYPTFS: Protocol = Protocol(new_raw_protocol(c::NETLINK_ECRYPTFS as _)); - /// `NETLINK_RDMA` - #[cfg(linux_kernel)] - pub const RDMA: Protocol = Protocol(new_raw_protocol(c::NETLINK_RDMA as _)); - /// `NETLINK_CRYPTO` - #[cfg(linux_kernel)] - pub const CRYPTO: Protocol = Protocol(new_raw_protocol(c::NETLINK_CRYPTO as _)); - /// `NETLINK_INET_DIAG` - #[cfg(linux_kernel)] - pub const INET_DIAG: Protocol = Protocol(new_raw_protocol(c::NETLINK_INET_DIAG as _)); - - /// A Netlink socket address. - /// - /// Used to bind to a Netlink socket. - /// - /// Not ABI compatible with `struct sockaddr_nl` - #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)] - #[cfg(linux_kernel)] - pub struct SocketAddrNetlink { - /// Port ID - pid: u32, - - /// Multicast groups mask - groups: u32, - } - - #[cfg(linux_kernel)] - impl SocketAddrNetlink { - /// Construct a netlink address - #[inline] - pub const fn new(pid: u32, groups: u32) -> Self { - Self { pid, groups } - } - - /// Return port id. - #[inline] - pub const fn pid(&self) -> u32 { - self.pid - } - - /// Set port id. - #[inline] - pub fn set_pid(&mut self, pid: u32) { - self.pid = pid; - } - - /// Return multicast groups mask. - #[inline] - pub const fn groups(&self) -> u32 { - self.groups - } - - /// Set multicast groups mask. - #[inline] - pub fn set_groups(&mut self, groups: u32) { - self.groups = groups; - } - } - - #[cfg(linux_kernel)] - #[allow(unsafe_code)] - // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which - // handles calling `f` with the needed preconditions. - unsafe impl SocketAddrArg for SocketAddrNetlink { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - let mut addr: c::sockaddr_nl = mem::zeroed(); - addr.nl_family = c::AF_NETLINK as _; - addr.nl_pid = self.pid; - addr.nl_groups = self.groups; - call_with_sockaddr(&addr, f) - } - } - - #[cfg(linux_kernel)] - impl From<SocketAddrNetlink> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrNetlink) -> Self { - from.as_any() - } - } - - #[cfg(linux_kernel)] - impl TryFrom<SocketAddrAny> for SocketAddrNetlink { - type Error = crate::io::Errno; - - fn try_from(addr: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr_netlink(&addr) - } - } -} - -/// `ETH_P_*` constants. -// These are translated into 16-bit big-endian form because that's what the -// [`AddressFamily::PACKET`] address family [expects]. -// -// [expects]: https://man7.org/linux/man-pages/man7/packet.7.html -pub mod eth { - #[cfg(linux_kernel)] - use { - super::{new_raw_protocol, Protocol}, - crate::backend::c, - }; - - /// `ETH_P_LOOP` - #[cfg(linux_kernel)] - pub const LOOP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LOOP as u16).to_be() as u32)); - /// `ETH_P_PUP` - #[cfg(linux_kernel)] - pub const PUP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUP as u16).to_be() as u32)); - /// `ETH_P_PUPAT` - #[cfg(linux_kernel)] - pub const PUPAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_PUPAT as u16).to_be() as u32)); - /// `ETH_P_TSN` - #[cfg(linux_kernel)] - pub const TSN: Protocol = Protocol(new_raw_protocol((c::ETH_P_TSN as u16).to_be() as u32)); - /// `ETH_P_ERSPAN2` - #[cfg(linux_kernel)] - pub const ERSPAN2: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ERSPAN2 as u16).to_be() as u32)); - /// `ETH_P_IP` - #[cfg(linux_kernel)] - pub const IP: Protocol = Protocol(new_raw_protocol((c::ETH_P_IP as u16).to_be() as u32)); - /// `ETH_P_X25` - #[cfg(linux_kernel)] - pub const X25: Protocol = Protocol(new_raw_protocol((c::ETH_P_X25 as u16).to_be() as u32)); - /// `ETH_P_ARP` - #[cfg(linux_kernel)] - pub const ARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_ARP as u16).to_be() as u32)); - /// `ETH_P_BPQ` - #[cfg(linux_kernel)] - pub const BPQ: Protocol = Protocol(new_raw_protocol((c::ETH_P_BPQ as u16).to_be() as u32)); - /// `ETH_P_IEEEPUP` - #[cfg(linux_kernel)] - pub const IEEEPUP: Protocol = - Protocol(new_raw_protocol((c::ETH_P_IEEEPUP as u16).to_be() as u32)); - /// `ETH_P_IEEEPUPAT` - #[cfg(linux_kernel)] - pub const IEEEPUPAT: Protocol = - Protocol(new_raw_protocol((c::ETH_P_IEEEPUPAT as u16).to_be() as u32)); - /// `ETH_P_BATMAN` - #[cfg(linux_kernel)] - pub const BATMAN: Protocol = - Protocol(new_raw_protocol((c::ETH_P_BATMAN as u16).to_be() as u32)); - /// `ETH_P_DEC` - #[cfg(linux_kernel)] - pub const DEC: Protocol = Protocol(new_raw_protocol((c::ETH_P_DEC as u16).to_be() as u32)); - /// `ETH_P_DNA_DL` - #[cfg(linux_kernel)] - pub const DNA_DL: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DNA_DL as u16).to_be() as u32)); - /// `ETH_P_DNA_RC` - #[cfg(linux_kernel)] - pub const DNA_RC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DNA_RC as u16).to_be() as u32)); - /// `ETH_P_DNA_RT` - #[cfg(linux_kernel)] - pub const DNA_RT: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DNA_RT as u16).to_be() as u32)); - /// `ETH_P_LAT` - #[cfg(linux_kernel)] - pub const LAT: Protocol = Protocol(new_raw_protocol((c::ETH_P_LAT as u16).to_be() as u32)); - /// `ETH_P_DIAG` - #[cfg(linux_kernel)] - pub const DIAG: Protocol = Protocol(new_raw_protocol((c::ETH_P_DIAG as u16).to_be() as u32)); - /// `ETH_P_CUST` - #[cfg(linux_kernel)] - pub const CUST: Protocol = Protocol(new_raw_protocol((c::ETH_P_CUST as u16).to_be() as u32)); - /// `ETH_P_SCA` - #[cfg(linux_kernel)] - pub const SCA: Protocol = Protocol(new_raw_protocol((c::ETH_P_SCA as u16).to_be() as u32)); - /// `ETH_P_TEB` - #[cfg(linux_kernel)] - pub const TEB: Protocol = Protocol(new_raw_protocol((c::ETH_P_TEB as u16).to_be() as u32)); - /// `ETH_P_RARP` - #[cfg(linux_kernel)] - pub const RARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_RARP as u16).to_be() as u32)); - /// `ETH_P_ATALK` - #[cfg(linux_kernel)] - pub const ATALK: Protocol = Protocol(new_raw_protocol((c::ETH_P_ATALK as u16).to_be() as u32)); - /// `ETH_P_AARP` - #[cfg(linux_kernel)] - pub const AARP: Protocol = Protocol(new_raw_protocol((c::ETH_P_AARP as u16).to_be() as u32)); - /// `ETH_P_8021Q` - #[cfg(linux_kernel)] - pub const P_8021Q: Protocol = - Protocol(new_raw_protocol((c::ETH_P_8021Q as u16).to_be() as u32)); - /// `ETH_P_ERSPAN` - #[cfg(linux_kernel)] - pub const ERSPAN: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ERSPAN as u16).to_be() as u32)); - /// `ETH_P_IPX` - #[cfg(linux_kernel)] - pub const IPX: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPX as u16).to_be() as u32)); - /// `ETH_P_IPV6` - #[cfg(linux_kernel)] - pub const IPV6: Protocol = Protocol(new_raw_protocol((c::ETH_P_IPV6 as u16).to_be() as u32)); - /// `ETH_P_PAUSE` - #[cfg(linux_kernel)] - pub const PAUSE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAUSE as u16).to_be() as u32)); - /// `ETH_P_SLOW` - #[cfg(linux_kernel)] - pub const SLOW: Protocol = Protocol(new_raw_protocol((c::ETH_P_SLOW as u16).to_be() as u32)); - /// `ETH_P_WCCP` - #[cfg(linux_kernel)] - pub const WCCP: Protocol = Protocol(new_raw_protocol((c::ETH_P_WCCP as u16).to_be() as u32)); - /// `ETH_P_MPLS_UC` - #[cfg(linux_kernel)] - pub const MPLS_UC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MPLS_UC as u16).to_be() as u32)); - /// `ETH_P_MPLS_MC` - #[cfg(linux_kernel)] - pub const MPLS_MC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MPLS_MC as u16).to_be() as u32)); - /// `ETH_P_ATMMPOA` - #[cfg(linux_kernel)] - pub const ATMMPOA: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ATMMPOA as u16).to_be() as u32)); - /// `ETH_P_PPP_DISC` - #[cfg(linux_kernel)] - pub const PPP_DISC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPP_DISC as u16).to_be() as u32)); - /// `ETH_P_PPP_SES` - #[cfg(linux_kernel)] - pub const PPP_SES: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPP_SES as u16).to_be() as u32)); - /// `ETH_P_LINK_CTL` - #[cfg(linux_kernel)] - pub const LINK_CTL: Protocol = - Protocol(new_raw_protocol((c::ETH_P_LINK_CTL as u16).to_be() as u32)); - /// `ETH_P_ATMFATE` - #[cfg(linux_kernel)] - pub const ATMFATE: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ATMFATE as u16).to_be() as u32)); - /// `ETH_P_PAE` - #[cfg(linux_kernel)] - pub const PAE: Protocol = Protocol(new_raw_protocol((c::ETH_P_PAE as u16).to_be() as u32)); - /// `ETH_P_PROFINET` - #[cfg(linux_kernel)] - pub const PROFINET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PROFINET as u16).to_be() as u32)); - /// `ETH_P_REALTEK` - #[cfg(linux_kernel)] - pub const REALTEK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_REALTEK as u16).to_be() as u32)); - /// `ETH_P_AOE` - #[cfg(linux_kernel)] - pub const AOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_AOE as u16).to_be() as u32)); - /// `ETH_P_ETHERCAT` - #[cfg(linux_kernel)] - pub const ETHERCAT: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ETHERCAT as u16).to_be() as u32)); - /// `ETH_P_8021AD` - #[cfg(linux_kernel)] - pub const P_8021AD: Protocol = - Protocol(new_raw_protocol((c::ETH_P_8021AD as u16).to_be() as u32)); - /// `ETH_P_802_EX1` - #[cfg(linux_kernel)] - pub const P_802_EX1: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_EX1 as u16).to_be() as u32)); - /// `ETH_P_PREAUTH` - #[cfg(linux_kernel)] - pub const PREAUTH: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PREAUTH as u16).to_be() as u32)); - /// `ETH_P_TIPC` - #[cfg(linux_kernel)] - pub const TIPC: Protocol = Protocol(new_raw_protocol((c::ETH_P_TIPC as u16).to_be() as u32)); - /// `ETH_P_LLDP` - #[cfg(linux_kernel)] - pub const LLDP: Protocol = Protocol(new_raw_protocol((c::ETH_P_LLDP as u16).to_be() as u32)); - /// `ETH_P_MRP` - #[cfg(linux_kernel)] - pub const MRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MRP as u16).to_be() as u32)); - /// `ETH_P_MACSEC` - #[cfg(linux_kernel)] - pub const MACSEC: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MACSEC as u16).to_be() as u32)); - /// `ETH_P_8021AH` - #[cfg(linux_kernel)] - pub const P_8021AH: Protocol = - Protocol(new_raw_protocol((c::ETH_P_8021AH as u16).to_be() as u32)); - /// `ETH_P_MVRP` - #[cfg(linux_kernel)] - pub const MVRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MVRP as u16).to_be() as u32)); - /// `ETH_P_1588` - #[cfg(linux_kernel)] - pub const P_1588: Protocol = Protocol(new_raw_protocol((c::ETH_P_1588 as u16).to_be() as u32)); - /// `ETH_P_NCSI` - #[cfg(linux_kernel)] - pub const NCSI: Protocol = Protocol(new_raw_protocol((c::ETH_P_NCSI as u16).to_be() as u32)); - /// `ETH_P_PRP` - #[cfg(linux_kernel)] - pub const PRP: Protocol = Protocol(new_raw_protocol((c::ETH_P_PRP as u16).to_be() as u32)); - /// `ETH_P_CFM` - #[cfg(linux_kernel)] - pub const CFM: Protocol = Protocol(new_raw_protocol((c::ETH_P_CFM as u16).to_be() as u32)); - /// `ETH_P_FCOE` - #[cfg(linux_kernel)] - pub const FCOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_FCOE as u16).to_be() as u32)); - /// `ETH_P_IBOE` - #[cfg(linux_kernel)] - pub const IBOE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IBOE as u16).to_be() as u32)); - /// `ETH_P_TDLS` - #[cfg(linux_kernel)] - pub const TDLS: Protocol = Protocol(new_raw_protocol((c::ETH_P_TDLS as u16).to_be() as u32)); - /// `ETH_P_FIP` - #[cfg(linux_kernel)] - pub const FIP: Protocol = Protocol(new_raw_protocol((c::ETH_P_FIP as u16).to_be() as u32)); - /// `ETH_P_80221` - #[cfg(linux_kernel)] - pub const P_80221: Protocol = - Protocol(new_raw_protocol((c::ETH_P_80221 as u16).to_be() as u32)); - /// `ETH_P_HSR` - #[cfg(linux_kernel)] - pub const HSR: Protocol = Protocol(new_raw_protocol((c::ETH_P_HSR as u16).to_be() as u32)); - /// `ETH_P_NSH` - #[cfg(linux_kernel)] - pub const NSH: Protocol = Protocol(new_raw_protocol((c::ETH_P_NSH as u16).to_be() as u32)); - /// `ETH_P_LOOPBACK` - #[cfg(linux_kernel)] - pub const LOOPBACK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_LOOPBACK as u16).to_be() as u32)); - /// `ETH_P_QINQ1` - #[cfg(linux_kernel)] - pub const QINQ1: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ1 as u16).to_be() as u32)); - /// `ETH_P_QINQ2` - #[cfg(linux_kernel)] - pub const QINQ2: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ2 as u16).to_be() as u32)); - /// `ETH_P_QINQ3` - #[cfg(linux_kernel)] - pub const QINQ3: Protocol = Protocol(new_raw_protocol((c::ETH_P_QINQ3 as u16).to_be() as u32)); - /// `ETH_P_EDSA` - #[cfg(linux_kernel)] - pub const EDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_EDSA as u16).to_be() as u32)); - /// `ETH_P_DSA_8021Q` - #[cfg(linux_kernel)] - pub const DSA_8021Q: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DSA_8021Q as u16).to_be() as u32)); - /// `ETH_P_DSA_A5PSW` - #[cfg(linux_kernel)] - pub const DSA_A5PSW: Protocol = - Protocol(new_raw_protocol((c::ETH_P_DSA_A5PSW as u16).to_be() as u32)); - /// `ETH_P_IFE` - #[cfg(linux_kernel)] - pub const IFE: Protocol = Protocol(new_raw_protocol((c::ETH_P_IFE as u16).to_be() as u32)); - /// `ETH_P_AF_IUCV` - #[cfg(linux_kernel)] - pub const AF_IUCV: Protocol = - Protocol(new_raw_protocol((c::ETH_P_AF_IUCV as u16).to_be() as u32)); - /// `ETH_P_802_3_MIN` - #[cfg(linux_kernel)] - pub const P_802_3_MIN: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_3_MIN as u16).to_be() as u32)); - /// `ETH_P_802_3` - #[cfg(linux_kernel)] - pub const P_802_3: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_3 as u16).to_be() as u32)); - /// `ETH_P_AX25` - #[cfg(linux_kernel)] - pub const AX25: Protocol = Protocol(new_raw_protocol((c::ETH_P_AX25 as u16).to_be() as u32)); - /// `ETH_P_ALL` - #[cfg(linux_kernel)] - pub const ALL: Protocol = Protocol(new_raw_protocol((c::ETH_P_ALL as u16).to_be() as u32)); - /// `ETH_P_802_2` - #[cfg(linux_kernel)] - pub const P_802_2: Protocol = - Protocol(new_raw_protocol((c::ETH_P_802_2 as u16).to_be() as u32)); - /// `ETH_P_SNAP` - #[cfg(linux_kernel)] - pub const SNAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_SNAP as u16).to_be() as u32)); - /// `ETH_P_DDCMP` - #[cfg(linux_kernel)] - pub const DDCMP: Protocol = Protocol(new_raw_protocol((c::ETH_P_DDCMP as u16).to_be() as u32)); - /// `ETH_P_WAN_PPP` - #[cfg(linux_kernel)] - pub const WAN_PPP: Protocol = - Protocol(new_raw_protocol((c::ETH_P_WAN_PPP as u16).to_be() as u32)); - /// `ETH_P_PPP_MP` - #[cfg(linux_kernel)] - pub const PPP_MP: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPP_MP as u16).to_be() as u32)); - /// `ETH_P_LOCALTALK` - #[cfg(linux_kernel)] - pub const LOCALTALK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_LOCALTALK as u16).to_be() as u32)); - /// `ETH_P_CAN` - #[cfg(linux_kernel)] - pub const CAN: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAN as u16).to_be() as u32)); - /// `ETH_P_CANFD` - #[cfg(linux_kernel)] - pub const CANFD: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANFD as u16).to_be() as u32)); - /// `ETH_P_CANXL` - #[cfg(linux_kernel)] - pub const CANXL: Protocol = Protocol(new_raw_protocol((c::ETH_P_CANXL as u16).to_be() as u32)); - /// `ETH_P_PPPTALK` - #[cfg(linux_kernel)] - pub const PPPTALK: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PPPTALK as u16).to_be() as u32)); - /// `ETH_P_TR_802_2` - #[cfg(linux_kernel)] - pub const TR_802_2: Protocol = - Protocol(new_raw_protocol((c::ETH_P_TR_802_2 as u16).to_be() as u32)); - /// `ETH_P_MOBITEX` - #[cfg(linux_kernel)] - pub const MOBITEX: Protocol = - Protocol(new_raw_protocol((c::ETH_P_MOBITEX as u16).to_be() as u32)); - /// `ETH_P_CONTROL` - #[cfg(linux_kernel)] - pub const CONTROL: Protocol = - Protocol(new_raw_protocol((c::ETH_P_CONTROL as u16).to_be() as u32)); - /// `ETH_P_IRDA` - #[cfg(linux_kernel)] - pub const IRDA: Protocol = Protocol(new_raw_protocol((c::ETH_P_IRDA as u16).to_be() as u32)); - /// `ETH_P_ECONET` - #[cfg(linux_kernel)] - pub const ECONET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ECONET as u16).to_be() as u32)); - /// `ETH_P_HDLC` - #[cfg(linux_kernel)] - pub const HDLC: Protocol = Protocol(new_raw_protocol((c::ETH_P_HDLC as u16).to_be() as u32)); - /// `ETH_P_ARCNET` - #[cfg(linux_kernel)] - pub const ARCNET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_ARCNET as u16).to_be() as u32)); - /// `ETH_P_DSA` - #[cfg(linux_kernel)] - pub const DSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_DSA as u16).to_be() as u32)); - /// `ETH_P_TRAILER` - #[cfg(linux_kernel)] - pub const TRAILER: Protocol = - Protocol(new_raw_protocol((c::ETH_P_TRAILER as u16).to_be() as u32)); - /// `ETH_P_PHONET` - #[cfg(linux_kernel)] - pub const PHONET: Protocol = - Protocol(new_raw_protocol((c::ETH_P_PHONET as u16).to_be() as u32)); - /// `ETH_P_IEEE802154` - #[cfg(linux_kernel)] - pub const IEEE802154: Protocol = - Protocol(new_raw_protocol((c::ETH_P_IEEE802154 as u16).to_be() as u32)); - /// `ETH_P_CAIF` - #[cfg(linux_kernel)] - pub const CAIF: Protocol = Protocol(new_raw_protocol((c::ETH_P_CAIF as u16).to_be() as u32)); - /// `ETH_P_XDSA` - #[cfg(linux_kernel)] - pub const XDSA: Protocol = Protocol(new_raw_protocol((c::ETH_P_XDSA as u16).to_be() as u32)); - /// `ETH_P_MAP` - #[cfg(linux_kernel)] - pub const MAP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MAP as u16).to_be() as u32)); - /// `ETH_P_MCTP` - #[cfg(linux_kernel)] - pub const MCTP: Protocol = Protocol(new_raw_protocol((c::ETH_P_MCTP as u16).to_be() as u32)); -} - -#[rustfmt::skip] -impl Protocol { - /// Constructs a `Protocol` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawProtocol) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `Protocol`. - #[inline] - pub const fn as_raw(self) -> RawProtocol { - self.0 - } -} - -/// `SHUT_*` constants for use with [`shutdown`]. -/// -/// [`shutdown`]: crate::net::shutdown -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Shutdown { - /// `SHUT_RD`—Disable further read operations. - Read = c::SHUT_RD as _, - /// `SHUT_WR`—Disable further write operations. - Write = c::SHUT_WR as _, - /// `SHUT_RDWR`—Disable further read and write operations. - Both = c::SHUT_RDWR as _, -} - -bitflags! { - /// `SOCK_*` constants for use with [`socket_with`], [`accept_with`] and - /// [`acceptfrom_with`]. - /// - /// [`socket_with`]: crate::net::socket_with - /// [`accept_with`]: crate::net::accept_with - /// [`acceptfrom_with`]: crate::net::acceptfrom_with - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SocketFlags: ffi::c_uint { - /// `SOCK_NONBLOCK` - #[cfg(not(any( - apple, - windows, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto", - target_os = "vita", - )))] - const NONBLOCK = bitcast!(c::SOCK_NONBLOCK); - - /// `SOCK_CLOEXEC` - #[cfg(not(any(apple, windows, target_os = "aix", target_os = "haiku")))] - const CLOEXEC = bitcast!(c::SOCK_CLOEXEC); - - // This deliberately lacks a `const _ = !0`, so that users can use - // `from_bits_truncate` to extract the `SocketFlags` from a flags - // value that also includes a `SocketType`. - } -} - -/// `AF_XDP` related types and constants. -#[cfg(target_os = "linux")] -pub mod xdp { - use crate::backend::net::read_sockaddr::read_sockaddr_xdp; - use crate::fd::{AsRawFd, BorrowedFd}; - use crate::net::addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque}; - use crate::net::SocketAddrAny; - - use super::{bitflags, c}; - - bitflags! { - /// `XDP_OPTIONS_*` constants returned by [`get_xdp_options`]. - /// - /// [`get_xdp_options`]: crate::net::sockopt::get_xdp_options - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpOptionsFlags: u32 { - /// `XDP_OPTIONS_ZEROCOPY` - const XDP_OPTIONS_ZEROCOPY = bitcast!(c::XDP_OPTIONS_ZEROCOPY); - } - } - - // Constant needs to be cast because bindgen does generate a `u32` but the - // struct expects a `u16`. - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n15> - bitflags! { - /// `XDP_*` constants for use in [`SocketAddrXdp`]. - #[repr(transparent)] - #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)] - pub struct SocketAddrXdpFlags: u16 { - /// `XDP_SHARED_UMEM` - const XDP_SHARED_UMEM = bitcast!(c::XDP_SHARED_UMEM as u16); - /// `XDP_COPY` - const XDP_COPY = bitcast!(c::XDP_COPY as u16); - /// `XDP_COPY` - const XDP_ZEROCOPY = bitcast!(c::XDP_ZEROCOPY as u16); - /// `XDP_USE_NEED_WAKEUP` - const XDP_USE_NEED_WAKEUP = bitcast!(c::XDP_USE_NEED_WAKEUP as u16); - // requires kernel 6.6 - /// `XDP_USE_SG` - const XDP_USE_SG = bitcast!(c::XDP_USE_SG as u16); - } - } - - bitflags! { - /// `XDP_RING_*` constants for use in fill and/or Tx ring. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpRingFlags: u32 { - /// `XDP_RING_NEED_WAKEUP` - const XDP_RING_NEED_WAKEUP = bitcast!(c::XDP_RING_NEED_WAKEUP); - } - } - - bitflags! { - /// `XDP_UMEM_*` constants for use in [`XdpUmemReg`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpUmemRegFlags: u32 { - /// `XDP_UMEM_UNALIGNED_CHUNK_FLAG` - const XDP_UMEM_UNALIGNED_CHUNK_FLAG = bitcast!(c::XDP_UMEM_UNALIGNED_CHUNK_FLAG); - } - } - - /// A XDP socket address. - /// - /// Used to bind to XDP socket. - /// - /// Not ABI compatible with `struct sockaddr_xdp`. - /// - /// To add a shared UMEM file descriptor, use - /// [`SocketAddrXdpWithSharedUmem`]. - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n48> - #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)] - pub struct SocketAddrXdp { - /// Flags. - sxdp_flags: SocketAddrXdpFlags, - /// Interface index. - sxdp_ifindex: u32, - /// Queue ID. - sxdp_queue_id: u32, - } - - impl SocketAddrXdp { - /// Construct a new XDP address. - #[inline] - pub const fn new(flags: SocketAddrXdpFlags, interface_index: u32, queue_id: u32) -> Self { - Self { - sxdp_flags: flags, - sxdp_ifindex: interface_index, - sxdp_queue_id: queue_id, - } - } - - /// Return flags. - #[inline] - pub fn flags(&self) -> SocketAddrXdpFlags { - self.sxdp_flags - } - - /// Set flags. - #[inline] - pub fn set_flags(&mut self, flags: SocketAddrXdpFlags) { - self.sxdp_flags = flags; - } - - /// Return interface index. - #[inline] - pub fn interface_index(&self) -> u32 { - self.sxdp_ifindex - } - - /// Set interface index. - #[inline] - pub fn set_interface_index(&mut self, interface_index: u32) { - self.sxdp_ifindex = interface_index; - } - - /// Return queue ID. - #[inline] - pub fn queue_id(&self) -> u32 { - self.sxdp_queue_id - } - - /// Set queue ID. - #[inline] - pub fn set_queue_id(&mut self, queue_id: u32) { - self.sxdp_queue_id = queue_id; - } - } - - #[allow(unsafe_code)] - // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which - // handles calling `f` with the needed preconditions. - unsafe impl SocketAddrArg for SocketAddrXdp { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - let addr = c::sockaddr_xdp { - sxdp_family: c::AF_XDP as _, - sxdp_flags: self.flags().bits(), - sxdp_ifindex: self.interface_index(), - sxdp_queue_id: self.queue_id(), - sxdp_shared_umem_fd: !0, - }; - - call_with_sockaddr(&addr, f) - } - } - - impl From<SocketAddrXdp> for SocketAddrAny { - #[inline] - fn from(from: SocketAddrXdp) -> Self { - from.as_any() - } - } - - impl TryFrom<SocketAddrAny> for SocketAddrXdp { - type Error = crate::io::Errno; - - fn try_from(addr: SocketAddrAny) -> Result<Self, Self::Error> { - read_sockaddr_xdp(&addr) - } - } - - /// An XDP socket address with a shared UMEM file descriptor. - /// - /// This implements `SocketAddrArg` so that it can be passed to [`bind`]. - /// - /// [`bind`]: crate::net::bind - #[derive(Debug)] - pub struct SocketAddrXdpWithSharedUmem<'a> { - /// XDP address. - pub addr: SocketAddrXdp, - /// Shared UMEM file descriptor. - pub shared_umem_fd: BorrowedFd<'a>, - } - - #[allow(unsafe_code)] - // SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which - // handles calling `f` with the needed preconditions. - unsafe impl<'a> SocketAddrArg for SocketAddrXdpWithSharedUmem<'a> { - unsafe fn with_sockaddr<R>( - &self, - f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R, - ) -> R { - let addr = c::sockaddr_xdp { - sxdp_family: c::AF_XDP as _, - sxdp_flags: self.addr.flags().bits(), - sxdp_ifindex: self.addr.interface_index(), - sxdp_queue_id: self.addr.queue_id(), - sxdp_shared_umem_fd: self.shared_umem_fd.as_raw_fd() as u32, - }; - - call_with_sockaddr(&addr, f) - } - } - - /// XDP ring offset. - /// - /// Used to mmap rings from kernel. - /// - /// Not ABI compatible with `struct xdp_ring_offset`. - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n59> - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpRingOffset { - /// Producer offset. - pub producer: u64, - /// Consumer offset. - pub consumer: u64, - /// Descriptors offset. - pub desc: u64, - /// Flags offset. - /// - /// Is `None` if the kernel version (<5.4) does not yet support flags. - pub flags: Option<u64>, - } - - /// XDP mmap offsets. - /// - /// Not ABI compatible with `struct xdp_mmap_offsets` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n66> - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpMmapOffsets { - /// Rx ring offsets. - pub rx: XdpRingOffset, - /// Tx ring offsets. - pub tx: XdpRingOffset, - /// Fill ring offsets. - pub fr: XdpRingOffset, - /// Completion ring offsets. - pub cr: XdpRingOffset, - } - - /// XDP umem registration. - /// - /// `struct xdp_umem_reg` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n79> - #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpUmemReg { - /// Start address of UMEM. - pub addr: u64, - /// Umem length in bytes. - pub len: u64, - /// Chunk size in bytes. - pub chunk_size: u32, - /// Headroom in bytes. - pub headroom: u32, - /// Flags. - /// - /// Requires kernel version 5.4. - pub flags: XdpUmemRegFlags, - /// `AF_XDP` TX metadata length - /// - /// Requires kernel version 6.8. - pub tx_metadata_len: u32, - } - - /// XDP statistics. - /// - /// Not ABI compatible with `struct xdp_statistics` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n92> - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpStatistics { - /// Rx dropped. - pub rx_dropped: u64, - /// Rx invalid descriptors. - pub rx_invalid_descs: u64, - /// Tx invalid descriptors. - pub tx_invalid_descs: u64, - /// Rx ring full. - /// - /// Is `None` if the kernel version (<5.9) does not yet support flags. - pub rx_ring_full: Option<u64>, - /// Rx fill ring empty descriptors. - /// - /// Is `None` if the kernel version (<5.9) does not yet support flags. - pub rx_fill_ring_empty_descs: Option<u64>, - /// Tx ring empty descriptors. - /// - /// Is `None` if the kernel version (<5.9) does not yet support flags. - pub tx_ring_empty_descs: Option<u64>, - } - - /// XDP options. - /// - /// Requires kernel version 5.3. - /// `struct xdp_options` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n101> - #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpOptions { - /// Flags. - pub flags: XdpOptionsFlags, - } - - /// XDP rx/tx frame descriptor. - /// - /// `struct xdp_desc` - // <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n154> - #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpDesc { - /// Offset from the start of the UMEM. - pub addr: u64, - /// Length of packet in bytes. - pub len: u32, - /// Options. - pub options: XdpDescOptions, - } - - #[cfg(target_os = "linux")] - bitflags! { - /// `XDP_*` constants for use in [`XdpDesc`]. - /// - /// Requires kernel version 6.6. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct XdpDescOptions: u32 { - /// `XDP_PKT_CONTD` - const XDP_PKT_CONTD = bitcast!(c::XDP_PKT_CONTD); - } - } - - /// Offset for mmapping rx ring. - pub const XDP_PGOFF_RX_RING: u64 = c::XDP_PGOFF_RX_RING as u64; - /// Offset for mmapping tx ring. - pub const XDP_PGOFF_TX_RING: u64 = c::XDP_PGOFF_TX_RING as u64; - /// Offset for mmapping fill ring. - pub const XDP_UMEM_PGOFF_FILL_RING: u64 = c::XDP_UMEM_PGOFF_FILL_RING; - /// Offset for mmapping completion ring. - pub const XDP_UMEM_PGOFF_COMPLETION_RING: u64 = c::XDP_UMEM_PGOFF_COMPLETION_RING; - - /// Offset used to shift the [`XdpDesc`] addr to the right to extract the - /// address offset in unaligned mode. - pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: u64 = c::XSK_UNALIGNED_BUF_OFFSET_SHIFT as u64; - /// Mask used to binary `and` the [`XdpDesc`] addr to extract the address - /// without the offset carried in the upper 16 bits of the address in - /// unaligned mode. - pub const XSK_UNALIGNED_BUF_ADDR_MASK: u64 = c::XSK_UNALIGNED_BUF_ADDR_MASK; -} - -/// UNIX credentials of socket peer, for use with [`get_socket_peercred`] -/// [`SendAncillaryMessage::ScmCredentials`] and -/// [`RecvAncillaryMessage::ScmCredentials`]. -/// -/// [`get_socket_peercred`]: crate::net::sockopt::socket_peercred -/// [`SendAncillaryMessage::ScmCredentials`]: crate::net::SendAncillaryMessage::ScmCredentials -/// [`RecvAncillaryMessage::ScmCredentials`]: crate::net::RecvAncillaryMessage::ScmCredentials -#[cfg(linux_kernel)] -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(C)] -pub struct UCred { - /// Process ID of peer - pub pid: crate::pid::Pid, - /// User ID of peer - pub uid: crate::ugid::Uid, - /// Group ID of peer - pub gid: crate::ugid::Gid, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - #[cfg(target_os = "linux")] - use crate::backend::c; - use crate::ffi::c_int; - use crate::net::addr::SocketAddrStorage; - use core::mem::transmute; - - // Backend code needs to cast these to `c_int` so make sure that cast isn't - // lossy. - assert_eq_size!(RawProtocol, c_int); - assert_eq_size!(Protocol, c_int); - assert_eq_size!(Option<RawProtocol>, c_int); - assert_eq_size!(Option<Protocol>, c_int); - assert_eq_size!(RawSocketType, c_int); - assert_eq_size!(SocketType, c_int); - assert_eq_size!(SocketFlags, c_int); - assert_eq_size!(SocketAddrStorage, c::sockaddr_storage); - - // Rustix doesn't depend on `Option<Protocol>` matching the ABI of a raw - // integer for correctness, but it should work nonetheless. - #[allow(unsafe_code)] - unsafe { - let t: Option<Protocol> = None; - assert_eq!(0_u32, transmute::<Option<Protocol>, u32>(t)); - - let t: Option<Protocol> = Some(Protocol::from_raw(RawProtocol::new(4567).unwrap())); - assert_eq!(4567_u32, transmute::<Option<Protocol>, u32>(t)); - } - - #[cfg(linux_kernel)] - assert_eq_size!(UCred, libc::ucred); - - #[cfg(target_os = "linux")] - assert_eq_size!(super::xdp::XdpUmemReg, c::xdp_umem_reg); - #[cfg(target_os = "linux")] - assert_eq_size!(super::xdp::XdpOptions, c::xdp_options); - #[cfg(target_os = "linux")] - assert_eq_size!(super::xdp::XdpDesc, c::xdp_desc); - } -} diff --git a/vendor/rustix/src/net/wsa.rs b/vendor/rustix/src/net/wsa.rs deleted file mode 100644 index 0ad4db5e..00000000 --- a/vendor/rustix/src/net/wsa.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::io; -use core::mem::MaybeUninit; -use windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAGetLastError, WSAStartup, WSADATA}; - -/// `WSAStartup()`—Initialize process-wide Windows support for sockets. -/// -/// On Windows, it's necessary to initialize the sockets subsystem before -/// using sockets APIs. The function performs the necessary initialization. -/// -/// # References -/// - [Winsock] -/// -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup -pub fn wsa_startup() -> io::Result<WSADATA> { - // Request version 2.2, which has been the latest version since far older - // versions of Windows than we support here. For more information about - // the version, see [here]. - // - // [here]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup#remarks - let version = 0x202; - let mut data = MaybeUninit::uninit(); - unsafe { - let ret = WSAStartup(version, data.as_mut_ptr()); - if ret == 0 { - Ok(data.assume_init()) - } else { - Err(io::Errno::from_raw_os_error(WSAGetLastError())) - } - } -} - -/// `WSACleanup()`—Clean up process-wide Windows support for sockets. -/// -/// In a program where `init` is called, if sockets are no longer necessary, -/// this function releases associated resources. -/// -/// # References -/// - [Winsock] -/// -/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacleanup -pub fn wsa_cleanup() -> io::Result<()> { - unsafe { - if WSACleanup() == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(WSAGetLastError())) - } - } -} diff --git a/vendor/rustix/src/not_implemented.rs b/vendor/rustix/src/not_implemented.rs deleted file mode 100644 index e8b162a8..00000000 --- a/vendor/rustix/src/not_implemented.rs +++ /dev/null @@ -1,348 +0,0 @@ -//! Documentation about unimplemented functions. -//! -//! This module contains documentation for several functions that rustix does -//! not implement, either because they are out of scope, or because they are -//! could probably be implemented but are not yet. - -macro_rules! not_implemented { - ($func:ident) => { - /// See the [module comment](self). - pub fn $func() { - unimplemented!() - } - }; -} - -/// Memory-allocation functions are out of scope for rustix. -/// -/// It is possible to implement `malloc`, `free`, and similar functions in -/// Rust, however rustix itself is focused on syscall-like functions. This -/// module contains an incomplete list of such functions. -/// -/// There are several allocator implementations for Rust; one of them is -/// [dlmalloc]. For a rustix-based implementation, see [rustix-dlmalloc]. -/// Another allocator implementation is [talc]. -/// -/// [dlmalloc]: https://crates.io/crates/dlmalloc -/// [talc]: https://crates.io/crates/talc -/// [rustix-dlmalloc]: https://crates.io/crates/rustix-dlmalloc -pub mod memory_allocation { - not_implemented!(malloc); - not_implemented!(realloc); - not_implemented!(calloc); - not_implemented!(free); - not_implemented!(posix_memalign); - not_implemented!(aligned_alloc); - not_implemented!(malloc_usable_size); -} - -/// Functions which need access to libc internals are out of scope for rustix. -/// -/// Most Rust programs have a libc present, and when a libc is present, it -/// expects to be the only thing in the process that can do certain operations. -/// For example, there can be only one `atexit` list in a process, only one -/// `pthread_atfork` list in a process, only one implementation of pthreads in -/// a process, and so on, and libc expects to own the one of each of those -/// things. And libc implementations may expect to be involved in signal -/// handling. So, these functions are believed to be out of scope for rustix. -/// This module contains an incomplete list of such functions. -/// -/// It would be possible to make a rust library which provides safe or -/// ergonomic wrappers around these libc functions, however that is out of -/// scope for rustix itself. -/// -/// If you would like to write a Rust program which does not use a libc, and -/// which does provide APIs for some of these functions, [Eyra] and [origin] -/// are two libraries which may be useful, and which provide public interfaces -/// for some of this functionality. -/// -/// If you are otherwise writing Rust code which you know will not share a -/// process with a libc, perhaps because you are writing a libc or similar -/// yourself, rustix's codebase does include experimental implementations of -/// the primitives needed to implement most of these functions. -/// -/// [Eyra]: https://github.com/sunfishcode/eyra?tab=readme-ov-file#eyra -/// [origin]: https://github.com/sunfishcode/origin?tab=readme-ov-file#origin -pub mod libc_internals { - not_implemented!(exit); - not_implemented!(fork); - not_implemented!(clone); - not_implemented!(clone3); - not_implemented!(brk); - not_implemented!(sigaction); - not_implemented!(sigaltstack); - not_implemented!(sigprocmask); - not_implemented!(sigwait); - not_implemented!(sigwaitinfo); - not_implemented!(sigtimedwait); - not_implemented!(set_thread_area); - not_implemented!(set_tid_address); - not_implemented!(tkill); - not_implemented!(sched_setscheduler); - not_implemented!(rseq); - not_implemented!(setuid); - not_implemented!(setgid); - not_implemented!(seteuid); - not_implemented!(setegid); - not_implemented!(setreuid); - not_implemented!(setregid); - not_implemented!(setresuid); - not_implemented!(setresgid); - not_implemented!(setgroups); - - not_implemented!(pthread_atfork); - not_implemented!(pthread_attr_destroy); - not_implemented!(pthread_attr_getaffinity_np); - not_implemented!(pthread_attr_getdetachstate); - not_implemented!(pthread_attr_getguardsize); - not_implemented!(pthread_attr_getinheritsched); - not_implemented!(pthread_attr_getschedparam); - not_implemented!(pthread_attr_getschedpolicy); - not_implemented!(pthread_attr_getscope); - not_implemented!(pthread_attr_getsigmask_np); - not_implemented!(pthread_attr_getstack); - not_implemented!(pthread_attr_getstackaddr); - not_implemented!(pthread_attr_getstacksize); - not_implemented!(pthread_attr_init); - not_implemented!(pthread_attr_setaffinity_np); - not_implemented!(pthread_attr_setdetachstate); - not_implemented!(pthread_attr_setguardsize); - not_implemented!(pthread_attr_setinheritsched); - not_implemented!(pthread_attr_setschedparam); - not_implemented!(pthread_attr_setschedpolicy); - not_implemented!(pthread_attr_setscope); - not_implemented!(pthread_attr_setsigmask_np); - not_implemented!(pthread_attr_setstack); - not_implemented!(pthread_attr_setstackaddr); - not_implemented!(pthread_attr_setstacksize); - not_implemented!(pthread_barrierattr_destroy); - not_implemented!(pthread_barrierattr_getpshared); - not_implemented!(pthread_barrierattr_init); - not_implemented!(pthread_barrierattr_setpshared); - not_implemented!(pthread_barrier_destroy); - not_implemented!(pthread_barrier_wait); - not_implemented!(pthread_cancel); - not_implemented!(pthread_cleanup_pop); - not_implemented!(pthread_cleanup_pop_restore_np); - not_implemented!(pthread_cleanup_push); - not_implemented!(pthread_cleanup_push_defer_np); - not_implemented!(pthread_condattr_destroy); - not_implemented!(pthread_condattr_getclock); - not_implemented!(pthread_condattr_getpshared); - not_implemented!(pthread_condattr_init); - not_implemented!(pthread_condattr_setclock); - not_implemented!(pthread_condattr_setpshared); - not_implemented!(pthread_cond_broadcast); - not_implemented!(pthread_cond_destroy); - not_implemented!(pthread_cond_signal); - not_implemented!(pthread_cond_timedwait); - not_implemented!(pthread_create); - not_implemented!(pthread_detach); - not_implemented!(pthread_equal); - not_implemented!(pthread_exit); - not_implemented!(pthread_getaffinity_np); - not_implemented!(pthread_getattr_default_np); - not_implemented!(pthread_getattr_np); - not_implemented!(pthread_getconcurrency); - not_implemented!(pthread_getcpuclockid); - not_implemented!(pthread_getname_np); - not_implemented!(pthread_getschedparam); - not_implemented!(pthread_getspecific); - not_implemented!(pthread_join); - not_implemented!(pthread_key_create); - not_implemented!(pthread_key_delete); - not_implemented!(pthread_kill); - not_implemented!(pthread_kill_other_threads_np); - not_implemented!(pthread_mutexattr_destroy); - not_implemented!(pthread_mutexattr_getprioceiling); - not_implemented!(pthread_mutexattr_getprotocol); - not_implemented!(pthread_mutexattr_getpshared); - not_implemented!(pthread_mutexattr_getrobust); - not_implemented!(pthread_mutexattr_getrobust_np); - not_implemented!(pthread_mutexattr_gettype); - not_implemented!(pthread_mutexattr_init); - not_implemented!(pthread_mutexattr_setprioceiling); - not_implemented!(pthread_mutexattr_setprotocol); - not_implemented!(pthread_mutexattr_setpshared); - not_implemented!(pthread_mutexattr_setrobust); - not_implemented!(pthread_mutexattr_setrobust_np); - not_implemented!(pthread_mutexattr_settype); - not_implemented!(pthread_mutex_consistent); - not_implemented!(pthread_mutex_consistent_np); - not_implemented!(pthread_mutex_destroy); - not_implemented!(pthread_mutex_getprioceiling); - not_implemented!(pthread_mutex_init); - not_implemented!(pthread_mutex_lock); - not_implemented!(pthread_mutex_setprioceiling); - not_implemented!(pthread_mutex_timedlock); - not_implemented!(pthread_mutex_trylock); - not_implemented!(pthread_once); - not_implemented!(pthread_rwlockattr_destroy); - not_implemented!(pthread_rwlockattr_getkind_np); - not_implemented!(pthread_rwlockattr_getpshared); - not_implemented!(pthread_rwlockattr_init); - not_implemented!(pthread_rwlockattr_setkind_np); - not_implemented!(pthread_rwlockattr_setpshared); - not_implemented!(pthread_rwlock_destroy); - not_implemented!(pthread_rwlock_rdlock); - not_implemented!(pthread_rwlock_timedrdlock); - not_implemented!(pthread_rwlock_timedwrlock); - not_implemented!(pthread_rwlock_tryrdlock); - not_implemented!(pthread_rwlock_trywrlock); - not_implemented!(pthread_rwlock_unlock); - not_implemented!(pthread_rwlock_wrlock); - not_implemented!(pthread_self); - not_implemented!(pthread_setaffinity_np); - not_implemented!(pthread_setattr_default_np); - not_implemented!(pthread_setcancelstate); - not_implemented!(pthread_setcanceltype); - not_implemented!(pthread_setconcurrency); - not_implemented!(pthread_setname_np); - not_implemented!(pthread_setschedparam); - not_implemented!(pthread_setschedprio); - not_implemented!(pthread_setspecific); - not_implemented!(pthread_sigmask); - not_implemented!(pthread_sigqueue); - not_implemented!(pthread_spin_destroy); - not_implemented!(pthread_spin_init); - not_implemented!(pthread_spin_lock); - not_implemented!(pthread_spin_trylock); - not_implemented!(pthread_spin_unlock); - not_implemented!(pthread_testcancel); - not_implemented!(pthread_timedjoin_np); - not_implemented!(pthread_tryjoin_np); - not_implemented!(pthread_yield); -} - -/// Functions which provide higher-level functionality are out of scope for -/// rustix. -/// -/// These functions are provided by typical libc implementations, but are -/// higher-level than the simple syscall-like functions that rustix focuses on. -/// They could be implemented as a separate library built on top of rustix, -/// rather than being part of rustix itself. This module contains an incomplete -/// list of such functions. -pub mod higher_level { - not_implemented!(getpwent); - not_implemented!(getpwuid); - not_implemented!(getpwnam); - not_implemented!(getpwuid_r); - not_implemented!(getpwnam_r); - not_implemented!(gethostbyname); - not_implemented!(execv); - not_implemented!(execvp); - not_implemented!(execvpe); - not_implemented!(wordexp); - not_implemented!(localtime); - not_implemented!(localtime_r); - not_implemented!(gmtime); - not_implemented!(gmtime_r); - not_implemented!(ctime); - not_implemented!(ctime_r); - not_implemented!(asctime); - not_implemented!(asctime_r); - not_implemented!(mktime); - not_implemented!(getifaddrs); - - /// See [rustix-openpty](https://crates.io/crates/rustix-openpty). - pub fn closefrom() { - unimplemented!() - } - /// See [rustix-openpty](https://crates.io/crates/rustix-openpty). - pub fn login_tty() { - unimplemented!() - } - /// See [rustix-openpty](https://crates.io/crates/rustix-openpty). - pub fn openpty() { - unimplemented!() - } - - /// See [`std::io::IsTerminal`]. - /// - /// For Rust < 1.70, see [is-terminal]. For a rustix-based implementation, - /// see [rustix-is-terminal]. - /// - /// [`std::io::IsTerminal`]: std::io::IsTerminal - /// [is-terminal]: https://crates.io/crates/is-terminal - /// [rustix-is-terminal]: https://crates.io/crates/rustix-is-terminal - pub fn isatty() { - unimplemented!() - } -} - -/// Functions which don't seem possible to even call from Rust with current -/// language features, even with `unsafe`. -pub mod impossible { - not_implemented!(vfork); - not_implemented!(sigreturn); - not_implemented!(setjmp); - not_implemented!(longjmp); - not_implemented!(sigsetjmp); - not_implemented!(siglongjmp); -} - -/// These functions are not yet implemented in rustix, but probably could be. -/// -/// These are functions that users have asked about, and which probably are in -/// scope for rustix, but are not yet implemented. This module contains an -/// incomplete list of such functions. -pub mod yet { - not_implemented!(tgkill); - not_implemented!(raise); - not_implemented!(sysctl); - not_implemented!(mq_open); - not_implemented!(mq_send); - not_implemented!(mq_unlink); - not_implemented!(recvmmsg); - not_implemented!(cachestat); - not_implemented!(fanotify_init); - not_implemented!(fanotify_mark); - not_implemented!(getifaddrs); - not_implemented!(signalfd); - not_implemented!(mount_setattr); - not_implemented!(extattr_delete_fd); - not_implemented!(extattr_delete_link); - not_implemented!(extattr_get_fd); - not_implemented!(extattr_get_link); - not_implemented!(extattr_list_fd); - not_implemented!(extattr_list_link); - not_implemented!(extattr_set_fd); - not_implemented!(extattr_set_link); - not_implemented!(get_mempolicy); - not_implemented!(mbind); - not_implemented!(set_mempolicy); - not_implemented!(migrate_pages); - not_implemented!(move_pages); - not_implemented!(fchmodat2); - not_implemented!(shmat); - not_implemented!(shmdt); - not_implemented!(shmget); - not_implemented!(shmctl); -} - -/// These functions are not quite yet finished in rustix. -/// -/// Rustix's codebase includes experimental implementations of these functions, -/// however they are not yet publicly exposed because their API might need more -/// work and/or they don't yet have a libc backend implementation yet. -/// -/// See [#1314] for more information, and please leave comments if there are -/// specific functions you're interested in. -/// -/// [#1314]: https://github.com/bytecodealliance/rustix/issues/1314 -pub mod quite_yet { - not_implemented!(_exit); - not_implemented!(_Exit); - not_implemented!(exit_group); - not_implemented!(sigpending); - not_implemented!(sigsuspend); - not_implemented!(execveat); - not_implemented!(execve); - - /// For now, use `rustix::process::uname().nodename()` instead. - /// - /// See also the [module comment](self). - pub fn gethostname() { - unimplemented!() - } -} diff --git a/vendor/rustix/src/param/auxv.rs b/vendor/rustix/src/param/auxv.rs deleted file mode 100644 index 2e502fdb..00000000 --- a/vendor/rustix/src/param/auxv.rs +++ /dev/null @@ -1,110 +0,0 @@ -use crate::backend; -#[cfg(any( - linux_raw, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) -))] -use crate::ffi::CStr; - -/// `sysconf(_SC_PAGESIZE)`—Returns the process' page size. -/// -/// Also known as `getpagesize`. -/// -/// # References -/// - [POSIX] -/// - [Linux `sysconf`] -/// - [Linux `getpagesize`] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sysconf.html -/// [Linux `sysconf`]: https://man7.org/linux/man-pages/man3/sysconf.3.html -/// [Linux `getpagesize`]: https://man7.org/linux/man-pages/man2/getpagesize.2.html -#[inline] -#[doc(alias = "PAGESIZE")] -#[doc(alias = "PAGE_SIZE")] -#[doc(alias = "_SC_PAGESIZE")] -#[doc(alias = "_SC_PAGE_SIZE")] -#[doc(alias = "getpagesize")] -pub fn page_size() -> usize { - backend::param::auxv::page_size() -} - -/// `sysconf(_SC_CLK_TCK)`—Returns the process' clock ticks per second. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sysconf.html -/// [Linux]: https://man7.org/linux/man-pages/man3/sysconf.3.html -#[cfg(not(any(target_os = "horizon", target_os = "vita", target_os = "wasi")))] -#[inline] -#[doc(alias = "_SC_CLK_TCK")] -pub fn clock_ticks_per_second() -> u64 { - backend::param::auxv::clock_ticks_per_second() -} - -/// `(getauxval(AT_HWCAP), getauxval(AT_HWCAP2)`—Returns the Linux "hwcap" -/// data. -/// -/// Return the Linux `AT_HWCAP` and `AT_HWCAP2` values passed to the -/// current process. Returns 0 for each value if it is not available. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[cfg(any( - linux_raw, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) -))] -#[inline] -pub fn linux_hwcap() -> (usize, usize) { - backend::param::auxv::linux_hwcap() -} - -/// `getauxval(AT_MINSIGSTKSZ)`—Returns the Linux "minsigstksz" data. -/// -/// Return the Linux `AT_MINSIGSTKSZ` value passed to the current process. -/// Returns 0 if it is not available. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[cfg(any( - linux_raw, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) -))] -#[inline] -pub fn linux_minsigstksz() -> usize { - backend::param::auxv::linux_minsigstksz() -} - -/// `getauxval(AT_EXECFN)`—Returns the Linux "execfn" string. -/// -/// Return the string that Linux has recorded as the filesystem path to the -/// executable. Returns an empty string if the string is not available. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[cfg(any( - linux_raw, - any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ) -))] -#[inline] -pub fn linux_execfn() -> &'static CStr { - backend::param::auxv::linux_execfn() -} diff --git a/vendor/rustix/src/param/init.rs b/vendor/rustix/src/param/init.rs deleted file mode 100644 index 88b35f2a..00000000 --- a/vendor/rustix/src/param/init.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! rustix's `init` function. -//! -//! # Safety -//! -//! When "use-explicitly-provided-auxv" is enabled, the `init` function must be -//! called before any other function in this module. It is unsafe because it -//! operates on raw pointers. -#![allow(unsafe_code)] - -use crate::backend; - -/// Initialize process-wide state. -/// -/// # Safety -/// -/// This must be passed a pointer to the original environment variable block -/// set up by the OS at process startup, and it must be called before any other -/// rustix functions are called. -#[inline] -#[doc(hidden)] -pub unsafe fn init(envp: *mut *mut u8) { - backend::param::auxv::init(envp) -} diff --git a/vendor/rustix/src/param/mod.rs b/vendor/rustix/src/param/mod.rs deleted file mode 100644 index f0de9d41..00000000 --- a/vendor/rustix/src/param/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! Process parameters. -//! -//! These values correspond to `sysconf` in POSIX, and the auxv array in Linux. -//! Despite the POSIX name “sysconf”, these aren't *system* configuration -//! parameters; they're *process* configuration parameters, as they may differ -//! between different processes on the same system. - -mod auxv; -#[cfg(all(feature = "use-explicitly-provided-auxv", not(libc)))] -mod init; - -pub use auxv::*; -#[cfg(all(feature = "use-explicitly-provided-auxv", not(libc)))] -pub use init::init; diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs deleted file mode 100644 index 9edeb57f..00000000 --- a/vendor/rustix/src/path/arg.rs +++ /dev/null @@ -1,1097 +0,0 @@ -//! Convenient and efficient string argument passing. -//! -//! This module defines the `Arg` trait and implements it for several common -//! string types. This allows users to pass any of these string types directly -//! to rustix APIs with string arguments, and it allows rustix to implement -//! NUL-termination without the need for copying or dynamic allocation where -//! possible. - -use crate::ffi::CStr; -use crate::io; -use crate::path::{DecInt, SMALL_PATH_BUFFER_SIZE}; -#[cfg(feature = "alloc")] -use alloc::borrow::ToOwned as _; -use core::mem::MaybeUninit; -use core::{ptr, slice, str}; -#[cfg(feature = "std")] -use std::ffi::{OsStr, OsString}; -#[cfg(all(feature = "std", target_os = "hermit"))] -use std::os::hermit::ext::ffi::{OsStrExt, OsStringExt}; -#[cfg(all(feature = "std", unix))] -use std::os::unix::ffi::{OsStrExt as _, OsStringExt as _}; -#[cfg(all(feature = "std", target_os = "vxworks"))] -use std::os::vxworks::ext::ffi::{OsStrExt, OsStringExt}; -#[cfg(all( - feature = "std", - target_os = "wasi", - any(not(target_env = "p2"), wasip2) -))] -use std::os::wasi::ffi::{OsStrExt, OsStringExt}; -#[cfg(feature = "std")] -use std::path::{Component, Components, Iter, Path, PathBuf}; -#[cfg(feature = "alloc")] -use {crate::ffi::CString, alloc::borrow::Cow}; -#[cfg(feature = "alloc")] -use {alloc::string::String, alloc::vec::Vec}; - -/// A trait for passing path arguments. -/// -/// This is similar to [`AsRef`]`<`[`Path`]`>`, but is implemented for more -/// kinds of strings and can convert into more kinds of strings. -/// -/// # Examples -/// -/// ``` -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// use rustix::ffi::CStr; -/// use rustix::io; -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// use rustix::path::Arg; -/// -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// pub fn touch<P: Arg>(path: P) -> io::Result<()> { -/// let path = path.into_c_str()?; -/// _touch(&path) -/// } -/// -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// fn _touch(path: &CStr) -> io::Result<()> { -/// // implementation goes here -/// Ok(()) -/// } -/// ``` -/// -/// Users can then call `touch("foo")`, `touch(cstr!("foo"))`, -/// `touch(Path::new("foo"))`, or many other things. -/// -/// [`AsRef`]: std::convert::AsRef -pub trait Arg { - /// Returns a view of this string as a string slice. - fn as_str(&self) -> io::Result<&str>; - - /// Returns a potentially-lossy rendering of this string as a - /// `Cow<'_, str>`. - #[cfg(feature = "alloc")] - fn to_string_lossy(&self) -> Cow<'_, str>; - - /// Returns a view of this string as a maybe-owned [`CStr`]. - #[cfg(feature = "alloc")] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>>; - - /// Consumes `self` and returns a view of this string as a maybe-owned - /// [`CStr`]. - #[cfg(feature = "alloc")] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b; - - /// Runs a closure with `self` passed in as a `&CStr`. - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>; -} - -/// Runs a closure on `arg` where `A` is mapped to a `&CStr` -pub fn option_into_with_c_str<T, F, A>(arg: Option<A>, f: F) -> io::Result<T> -where - A: Arg + Sized, - F: FnOnce(Option<&CStr>) -> io::Result<T>, -{ - if let Some(arg) = arg { - arg.into_with_c_str(|p| f(Some(p))) - } else { - f(None) - } -} - -impl Arg for &str { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for &String { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(String::as_str(self)).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - self.as_str().into_c_str() - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for String { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_str()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for &OsStr { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - OsStr::to_string_lossy(self) - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for &OsString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - OsString::as_os_str(self).to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(OsString::as_os_str(self).as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - self.as_os_str().into_c_str() - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for OsString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for &Path { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Path::to_string_lossy(self) - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for &PathBuf { - #[inline] - fn as_str(&self) -> io::Result<&str> { - PathBuf::as_path(self) - .as_os_str() - .to_str() - .ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_path().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(PathBuf::as_path(self).as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - self.as_path().into_c_str() - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for PathBuf { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.into_os_string().into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f( - &CString::new(self.into_os_string().into_vec()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - ) - } -} - -impl Arg for &CStr { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - CStr::to_string_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(self) - } -} - -#[cfg(feature = "alloc")] -impl Arg for &CString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - unimplemented!() - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - unimplemented!() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(self) - } -} - -#[cfg(feature = "alloc")] -impl Arg for CString { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().map_err(|_utf8_err| io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - CStr::to_string_lossy(self) - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned(self)) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&self) - } -} - -#[cfg(feature = "alloc")] -impl<'a> Arg for Cow<'a, str> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_ref()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - match self { - Cow::Owned(s) => CString::new(s), - Cow::Borrowed(s) => CString::new(s), - } - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl<'a> Arg for Cow<'a, OsStr> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - (**self).to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - (**self).to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - match self { - Cow::Owned(os) => CString::new(os.into_vec()), - Cow::Borrowed(os) => CString::new(os.as_bytes()), - } - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_bytes(), f) - } -} - -#[cfg(feature = "alloc")] -impl<'a> Arg for Cow<'a, CStr> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.to_str().map_err(|_utf8_err| io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - let borrow: &CStr = core::borrow::Borrow::borrow(self); - borrow.to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self)) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(self) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&self) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl<'a> Arg for Component<'a> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_os_str().to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_os_str().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl<'a> Arg for Components<'a> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_path().to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_path().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_path().as_os_str().as_bytes(), f) - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl<'a> Arg for Iter<'a> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - self.as_path().to_str().ok_or(io::Errno::INVAL) - } - - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_path().to_string_lossy() - } - - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_path().as_os_str().as_bytes()) - .map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self.as_path().as_os_str().as_bytes(), f) - } -} - -impl Arg for &[u8] { - #[inline] - fn as_str(&self) -> io::Result<&str> { - str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self, f) - } -} - -#[cfg(feature = "alloc")] -impl Arg for &Vec<u8> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - with_c_str(self, f) - } -} - -#[cfg(feature = "alloc")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl Arg for Vec<u8> { - #[inline] - fn as_str(&self) -> io::Result<&str> { - str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - String::from_utf8_lossy(self) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Owned( - CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned( - CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?, - )) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?) - } -} - -impl Arg for DecInt { - #[inline] - fn as_str(&self) -> io::Result<&str> { - Ok(self.as_str()) - } - - #[cfg(feature = "alloc")] - #[inline] - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self.as_str()) - } - - #[cfg(feature = "alloc")] - #[inline] - fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { - Ok(Cow::Borrowed(self.as_c_str())) - } - - #[cfg(feature = "alloc")] - #[inline] - fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> - where - Self: 'b, - { - Ok(Cow::Owned(self.as_c_str().to_owned())) - } - - #[inline] - fn into_with_c_str<T, F>(self, f: F) -> io::Result<T> - where - Self: Sized, - F: FnOnce(&CStr) -> io::Result<T>, - { - f(self.as_c_str()) - } -} - -/// Runs a closure with `bytes` passed in as a `&CStr`. -#[allow(unsafe_code, clippy::int_plus_one)] -#[inline] -fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T> -where - F: FnOnce(&CStr) -> io::Result<T>, -{ - // Most paths are less than `SMALL_PATH_BUFFER_SIZE` long. The rest can go - // through the dynamic allocation path. If you're opening many files in a - // directory with a long path, consider opening the directory and using - // `openat` to open the files under it, which will avoid this, and is often - // faster in the OS as well. - - // Test with `>=` so that we have room for the trailing NUL. - if bytes.len() >= SMALL_PATH_BUFFER_SIZE { - return with_c_str_slow_path(bytes, f); - } - - // Taken from - // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs> - let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit(); - let buf_ptr = buf.as_mut_ptr().cast::<u8>(); - - // This helps test our safety condition below. - debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE); - - // SAFETY: `bytes.len() < SMALL_PATH_BUFFER_SIZE` which means we have space - // for `bytes.len() + 1` `u8`s: - unsafe { - ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); - buf_ptr.add(bytes.len()).write(b'\0'); - } - - // SAFETY: We just wrote the bytes above and they will remain valid for the - // duration of `f` because `buf` doesn't get dropped until the end of the - // function. - match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { - Ok(s) => f(s), - Err(_) => Err(io::Errno::INVAL), - } -} - -/// The slow path which handles any length. In theory OS's only support up to -/// `PATH_MAX`, but we let the OS enforce that. -#[allow(unsafe_code, clippy::int_plus_one)] -#[cold] -fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T> -where - F: FnOnce(&CStr) -> io::Result<T>, -{ - #[cfg(feature = "alloc")] - { - f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?) - } - - #[cfg(not(feature = "alloc"))] - { - #[cfg(all( - libc, - not(any( - target_os = "espidf", - target_os = "horizon", - target_os = "hurd", - target_os = "vita", - target_os = "wasi" - )) - ))] - const LARGE_PATH_BUFFER_SIZE: usize = libc::PATH_MAX as usize; - #[cfg(linux_raw)] - const LARGE_PATH_BUFFER_SIZE: usize = linux_raw_sys::general::PATH_MAX as usize; - #[cfg(any( - target_os = "espidf", - target_os = "horizon", - target_os = "hurd", - target_os = "vita", - target_os = "wasi" - ))] - const LARGE_PATH_BUFFER_SIZE: usize = 4096 as usize; // TODO: upstream this - - // Taken from - // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs> - let mut buf = MaybeUninit::<[u8; LARGE_PATH_BUFFER_SIZE]>::uninit(); - let buf_ptr = buf.as_mut_ptr().cast::<u8>(); - - // This helps test our safety condition below. - if bytes.len() + 1 > LARGE_PATH_BUFFER_SIZE { - return Err(io::Errno::NAMETOOLONG); - } - - // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have - // space for `bytes.len() + 1` `u8`s: - unsafe { - ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); - buf_ptr.add(bytes.len()).write(b'\0'); - } - - // SAFETY: We just wrote the bytes above and they will remain valid for - // the duration of `f` because `buf` doesn't get dropped until the end - // of the function. - match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) - { - Ok(s) => f(s), - Err(_) => Err(io::Errno::INVAL), - } - } -} diff --git a/vendor/rustix/src/path/dec_int.rs b/vendor/rustix/src/path/dec_int.rs deleted file mode 100644 index 5b6e2f81..00000000 --- a/vendor/rustix/src/path/dec_int.rs +++ /dev/null @@ -1,261 +0,0 @@ -//! Efficient decimal integer formatting. -//! -//! # Safety -//! -//! This uses `CStr::from_bytes_with_nul_unchecked` and -//! `str::from_utf8_unchecked`on the buffer that it filled itself. -#![allow(unsafe_code)] - -use crate::backend::fd::{AsFd, AsRawFd as _}; -use crate::ffi::CStr; -use core::fmt; -use core::hint::unreachable_unchecked; -use core::mem::{self, MaybeUninit}; -use core::num::{NonZeroU8, NonZeroUsize}; -#[cfg(all(feature = "std", unix))] -use std::os::unix::ffi::OsStrExt; -#[cfg(all( - feature = "std", - target_os = "wasi", - any(not(target_env = "p2"), wasip2) -))] -use std::os::wasi::ffi::OsStrExt; -#[cfg(feature = "std")] -use {std::ffi::OsStr, std::path::Path}; - -/// Format an integer into a decimal `Path` component, without constructing a -/// temporary `PathBuf` or `String`. -/// -/// This is used for opening paths such as `/proc/self/fd/<fd>` on Linux. -/// -/// # Examples -/// -/// ``` -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// use rustix::path::DecInt; -/// -/// # #[cfg(any(feature = "fs", feature = "net"))] -/// assert_eq!( -/// format!("hello {}", DecInt::new(9876).as_ref().display()), -/// "hello 9876" -/// ); -/// ``` -#[derive(Clone)] -pub struct DecInt { - buf: [MaybeUninit<u8>; BUF_LEN], - len: NonZeroU8, -} - -/// Enough to hold an {u,i}64 and NUL terminator. -const BUF_LEN: usize = U64_MAX_STR_LEN + 1; - -/// Maximum length of a formatted [`u64`]. -const U64_MAX_STR_LEN: usize = "18446744073709551615".len(); - -/// Maximum length of a formatted [`i64`]. -#[allow(dead_code)] -const I64_MAX_STR_LEN: usize = "-9223372036854775808".len(); - -const _: () = assert!(U64_MAX_STR_LEN == I64_MAX_STR_LEN); - -mod private { - pub trait Sealed: Copy { - type Unsigned: super::Integer; - - fn as_unsigned(self) -> (bool, Self::Unsigned); - fn eq_zero(self) -> bool; - fn div_mod_10(&mut self) -> u8; - } - - macro_rules! impl_unsigned { - ($($ty:ty)+) => { $( - impl Sealed for $ty { - type Unsigned = $ty; - - #[inline] - fn as_unsigned(self) -> (bool, $ty) { - (false, self) - } - - #[inline] - fn eq_zero(self) -> bool { - self == 0 - } - - #[inline] - fn div_mod_10(&mut self) -> u8 { - let result = (*self % 10) as u8; - *self /= 10; - result - } - } - )+ } - } - - macro_rules! impl_signed { - ($($signed:ty : $unsigned:ty)+) => { $( - impl Sealed for $signed { - type Unsigned = $unsigned; - - #[inline] - fn as_unsigned(self) -> (bool, $unsigned) { - if self >= 0 { - (false, self as $unsigned) - } else { - (true, !(self as $unsigned) + 1) - } - } - - #[inline] - fn eq_zero(self) -> bool { - unimplemented!() - } - - #[inline] - fn div_mod_10(&mut self) -> u8 { - unimplemented!() - } - } - )+ } - } - - impl_unsigned!(u8 u16 u32 u64); - impl_signed!(i8:u8 i16:u16 i32:u32 i64:u64); - - #[cfg(any( - target_pointer_width = "16", - target_pointer_width = "32", - target_pointer_width = "64" - ))] - const _: () = { - impl_unsigned!(usize); - impl_signed!(isize:usize); - }; -} - -/// An integer that can be used by [`DecInt::new`]. -pub trait Integer: private::Sealed {} - -impl Integer for i8 {} -impl Integer for i16 {} -impl Integer for i32 {} -impl Integer for i64 {} -impl Integer for u8 {} -impl Integer for u16 {} -impl Integer for u32 {} -impl Integer for u64 {} - -#[cfg(any( - target_pointer_width = "16", - target_pointer_width = "32", - target_pointer_width = "64" -))] -const _: () = { - impl Integer for isize {} - impl Integer for usize {} -}; - -impl DecInt { - /// Construct a new path component from an integer. - pub fn new<Int: Integer>(i: Int) -> Self { - use private::Sealed as _; - - let (is_neg, mut i) = i.as_unsigned(); - let mut len = 1; - let mut buf = [MaybeUninit::uninit(); BUF_LEN]; - buf[BUF_LEN - 1] = MaybeUninit::new(b'\0'); - - // We use `loop { …; if cond { break } }` instead of - // `while !cond { … }` so the loop is entered at least once. This way - // `0` does not need a special handling. - loop { - len += 1; - if len > BUF_LEN { - // SAFETY: A stringified `i64`/`u64` cannot be longer than - // `U64_MAX_STR_LEN` bytes. - unsafe { unreachable_unchecked() }; - } - buf[BUF_LEN - len] = MaybeUninit::new(b'0' + i.div_mod_10()); - if i.eq_zero() { - break; - } - } - - if is_neg { - len += 1; - if len > BUF_LEN { - // SAFETY: A stringified `i64`/`u64` cannot be longer than - // `U64_MAX_STR_LEN` bytes. - unsafe { unreachable_unchecked() }; - } - buf[BUF_LEN - len] = MaybeUninit::new(b'-'); - } - - Self { - buf, - len: NonZeroU8::new(len as u8).unwrap(), - } - } - - /// Construct a new path component from a file descriptor. - #[inline] - pub fn from_fd<Fd: AsFd>(fd: Fd) -> Self { - Self::new(fd.as_fd().as_raw_fd()) - } - - /// Return the raw byte buffer as a `&str`. - #[inline] - pub fn as_str(&self) -> &str { - // SAFETY: `DecInt` always holds a formatted decimal number, so it's - // always valid UTF-8. - unsafe { core::str::from_utf8_unchecked(self.as_bytes()) } - } - - /// Return the raw byte buffer as a `&CStr`. - #[inline] - pub fn as_c_str(&self) -> &CStr { - let bytes_with_nul = self.as_bytes_with_nul(); - debug_assert!(CStr::from_bytes_with_nul(bytes_with_nul).is_ok()); - - // SAFETY: `self.buf` holds a single decimal ASCII representation and - // at least one extra NUL byte. - unsafe { CStr::from_bytes_with_nul_unchecked(bytes_with_nul) } - } - - /// Return the raw byte buffer including the NUL byte. - #[inline] - pub fn as_bytes_with_nul(&self) -> &[u8] { - let len = NonZeroUsize::from(self.len).get(); - if len > BUF_LEN { - // SAFETY: A stringified `i64`/`u64` cannot be longer than - // `U64_MAX_STR_LEN` bytes. - unsafe { unreachable_unchecked() }; - } - let init = &self.buf[(self.buf.len() - len)..]; - // SAFETY: We're guaranteed to have initialized `len + 1` bytes. - unsafe { mem::transmute::<&[MaybeUninit<u8>], &[u8]>(init) } - } - - /// Return the raw byte buffer. - #[inline] - pub fn as_bytes(&self) -> &[u8] { - let bytes = self.as_bytes_with_nul(); - &bytes[..bytes.len() - 1] - } -} - -#[cfg(feature = "std")] -#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))] -impl AsRef<Path> for DecInt { - #[inline] - fn as_ref(&self) -> &Path { - let as_os_str: &OsStr = OsStrExt::from_bytes(self.as_bytes()); - Path::new(as_os_str) - } -} - -impl fmt::Debug for DecInt { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_str().fmt(f) - } -} diff --git a/vendor/rustix/src/path/mod.rs b/vendor/rustix/src/path/mod.rs deleted file mode 100644 index 627716d8..00000000 --- a/vendor/rustix/src/path/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Filesystem path operations. - -mod arg; -mod dec_int; - -pub use arg::{option_into_with_c_str, Arg}; -pub use dec_int::{DecInt, Integer}; - -pub(crate) const SMALL_PATH_BUFFER_SIZE: usize = 256; diff --git a/vendor/rustix/src/pid.rs b/vendor/rustix/src/pid.rs deleted file mode 100644 index aa61892f..00000000 --- a/vendor/rustix/src/pid.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! The `Pid` type. - -#![allow(unsafe_code)] - -use core::num::NonZeroI32; - -/// A process identifier as a raw integer. -pub type RawPid = i32; - -/// `pid_t`—A non-zero Unix process ID. -/// -/// This is a pid, and not a pidfd. It is not a file descriptor, and the -/// process it refers to could disappear at any time and be replaced by -/// another, unrelated, process. -/// -/// On Linux, `Pid` values are also used to identify threads. -#[repr(transparent)] -#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] -pub struct Pid(NonZeroI32); - -impl Pid { - /// A `Pid` corresponding to the init process (pid 1). - pub const INIT: Self = Self(match NonZeroI32::new(1) { - Some(n) => n, - None => panic!("unreachable"), - }); - - /// Converts a `RawPid` into a `Pid`. - /// - /// Returns `Some` for positive values, and `None` for zero values. - /// - /// This is safe because a `Pid` is a number without any guarantees for the - /// kernel. Non-child `Pid`s are always racy for any syscalls, but can only - /// cause logic errors. If you want race-free access to or control of - /// non-child processes, please consider other mechanisms like [pidfd] on - /// Linux. - /// - /// Passing a negative number doesn't invoke undefined behavior, but it - /// may cause unexpected behavior. - /// - /// [pidfd]: https://man7.org/linux/man-pages/man2/pidfd_open.2.html - #[inline] - pub const fn from_raw(raw: RawPid) -> Option<Self> { - debug_assert!(raw >= 0); - match NonZeroI32::new(raw) { - Some(non_zero) => Some(Self(non_zero)), - None => None, - } - } - - /// Converts a known positive `RawPid` into a `Pid`. - /// - /// Passing a negative number doesn't invoke undefined behavior, but it - /// may cause unexpected behavior. - /// - /// # Safety - /// - /// The caller must guarantee `raw` is non-zero. - #[inline] - pub const unsafe fn from_raw_unchecked(raw: RawPid) -> Self { - debug_assert!(raw > 0); - Self(NonZeroI32::new_unchecked(raw)) - } - - /// Creates a `Pid` holding the ID of the given child process. - #[cfg(feature = "std")] - #[inline] - pub fn from_child(child: &std::process::Child) -> Self { - let id = child.id(); - // SAFETY: We know the returned ID is valid because it came directly - // from an OS API. - unsafe { Self::from_raw_unchecked(id as i32) } - } - - /// Converts a `Pid` into a `NonZeroI32`. - #[inline] - pub const fn as_raw_nonzero(self) -> NonZeroI32 { - self.0 - } - - /// Converts an `Option<Pid>` into a `RawPid`. - #[inline] - pub const fn as_raw(pid: Option<Self>) -> RawPid { - match pid { - Some(pid) => pid.0.get(), - None => 0, - } - } - - /// Test whether this pid represents the init process ([`Pid::INIT`]). - #[inline] - pub const fn is_init(self) -> bool { - self.0.get() == Self::INIT.0.get() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - use core::mem::transmute; - - assert_eq_size!(RawPid, NonZeroI32); - assert_eq_size!(RawPid, Pid); - assert_eq_size!(RawPid, Option<Pid>); - - // Rustix doesn't depend on `Option<Pid>` matching the ABI of a raw integer - // for correctness, but it should work nonetheless. - const_assert_eq!(0 as RawPid, unsafe { - transmute::<Option<Pid>, RawPid>(None) - }); - const_assert_eq!(4567 as RawPid, unsafe { - transmute::<Option<Pid>, RawPid>(Some(Pid::from_raw_unchecked(4567))) - }); - } - - #[test] - fn test_ctors() { - use std::num::NonZeroI32; - assert!(Pid::from_raw(0).is_none()); - assert_eq!( - Pid::from_raw(77).unwrap().as_raw_nonzero(), - NonZeroI32::new(77).unwrap() - ); - assert_eq!(Pid::as_raw(Pid::from_raw(77)), 77); - } - - #[test] - fn test_specials() { - assert!(Pid::from_raw(1).unwrap().is_init()); - assert_eq!(Pid::from_raw(1).unwrap(), Pid::INIT); - } -} diff --git a/vendor/rustix/src/pipe.rs b/vendor/rustix/src/pipe.rs deleted file mode 100644 index 267c99d5..00000000 --- a/vendor/rustix/src/pipe.rs +++ /dev/null @@ -1,222 +0,0 @@ -//! `pipe` and related APIs. - -#![allow(unsafe_code)] - -use crate::fd::OwnedFd; -use crate::{backend, io}; -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -use backend::c; -#[cfg(linux_kernel)] -use backend::fd::AsFd; - -#[cfg(not(apple))] -pub use backend::pipe::types::PipeFlags; - -#[cfg(linux_kernel)] -pub use backend::pipe::types::{IoSliceRaw, SpliceFlags}; - -/// `PIPE_BUF`—The maximum length at which writes to a pipe are atomic. -/// -/// # References -/// - [Linux] -/// - [POSIX] -/// -/// [Linux]: https://man7.org/linux/man-pages/man7/pipe.7.html -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/write.html -#[cfg(not(any( - solarish, - windows, - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -pub const PIPE_BUF: usize = c::PIPE_BUF; - -/// `pipe()`—Creates a pipe. -/// -/// This function creates a pipe and returns two file descriptors, for the -/// reading and writing ends of the pipe, respectively. -/// -/// See [`pipe_with`] to pass additional flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/pipe.html -/// [Linux]: https://man7.org/linux/man-pages/man2/pipe.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pipe.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pipe&sektion=2 -/// [NetBSD]: https://man.netbsd.org/pipe.2 -/// [OpenBSD]: https://man.openbsd.org/pipe.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pipe§ion=2 -/// [illumos]: https://illumos.org/man/2/pipe -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Pipe.html -#[inline] -pub fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { - backend::pipe::syscalls::pipe() -} - -/// `pipe2(flags)`—Creates a pipe, with flags. -/// -/// `pipe_with` is the same as [`pipe`] but adds an additional flags operand. -/// -/// This function creates a pipe and returns two file descriptors, for the -/// reading and writing ends of the pipe, respectively. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pipe2.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pipe2&sektion=2 -/// [NetBSD]: https://man.netbsd.org/pipe2.2 -/// [OpenBSD]: https://man.openbsd.org/pipe2.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pipe2§ion=2 -/// [illumos]: https://illumos.org/man/2/pipe2 -#[cfg(not(any( - apple, - target_os = "aix", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "nto" -)))] -#[inline] -#[doc(alias = "pipe2")] -pub fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { - backend::pipe::syscalls::pipe_with(flags) -} - -/// `splice(fd_in, off_in, fd_out, off_out, len, flags)`—Transfer data -/// between a file and a pipe. -/// -/// This function transfers up to `len` bytes of data from the file descriptor -/// `fd_in` to the file descriptor `fd_out`, where one of the file descriptors -/// must refer to a pipe. -/// -/// `off_*` must be `None` if the corresponding fd refers to a pipe. Otherwise -/// its value points to the starting offset to the file, from which the data is -/// read/written. On success, the number of bytes read/written is added to the -/// offset. -/// -/// Passing `None` causes the read/write to start from the file offset, and the -/// file offset is adjusted appropriately. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/splice.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn splice<FdIn: AsFd, FdOut: AsFd>( - fd_in: FdIn, - off_in: Option<&mut u64>, - fd_out: FdOut, - off_out: Option<&mut u64>, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - backend::pipe::syscalls::splice(fd_in.as_fd(), off_in, fd_out.as_fd(), off_out, len, flags) -} - -/// `vmsplice(fd, bufs, flags)`—Transfer data between memory and a pipe. -/// -/// If `fd` is the write end of the pipe, the function maps the memory pointer -/// at by `bufs` to the pipe. -/// -/// If `fd` is the read end of the pipe, the function writes data from the pipe -/// to said memory. -/// -/// # Safety -/// -/// If the memory must not be mutated (such as when `bufs` were originally -/// immutable slices), it is up to the caller to ensure that the write end of -/// the pipe is placed in `fd`. -/// -/// Additionally if `SpliceFlags::GIFT` is set, the caller must also ensure -/// that the contents of `bufs` in never modified following the call, and that -/// all of the pointers in `bufs` are page aligned, and the lengths are -/// multiples of a page size in bytes. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/vmsplice.2.html -#[cfg(linux_kernel)] -#[inline] -pub unsafe fn vmsplice<PipeFd: AsFd>( - fd: PipeFd, - bufs: &[IoSliceRaw<'_>], - flags: SpliceFlags, -) -> io::Result<usize> { - backend::pipe::syscalls::vmsplice(fd.as_fd(), bufs, flags) -} - -/// `tee(fd_in, fd_out, len, flags)`—Copy data between pipes without -/// consuming it. -/// -/// This reads up to `len` bytes from `in_fd` without consuming them, and -/// writes them to `out_fd`. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/tee.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn tee<FdIn: AsFd, FdOut: AsFd>( - fd_in: FdIn, - fd_out: FdOut, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - backend::pipe::syscalls::tee(fd_in.as_fd(), fd_out.as_fd(), len, flags) -} - -/// `fnctl(fd, F_GETPIPE_SZ)`—Return the buffer capacity of a pipe. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn fcntl_getpipe_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> { - backend::pipe::syscalls::fcntl_getpipe_size(fd.as_fd()) -} - -/// `fnctl(fd, F_SETPIPE_SZ)`—Set the buffer capacity of a pipe. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn fcntl_setpipe_size<Fd: AsFd>(fd: Fd, size: usize) -> io::Result<usize> { - backend::pipe::syscalls::fcntl_setpipe_size(fd.as_fd(), size) -} diff --git a/vendor/rustix/src/prctl.rs b/vendor/rustix/src/prctl.rs deleted file mode 100644 index 1a31a8cc..00000000 --- a/vendor/rustix/src/prctl.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Helper functions for `prctl` syscalls. - -#![allow(unsafe_code)] - -use crate::backend::prctl::syscalls; -use crate::ffi::{c_int, c_void}; -use crate::io; -use crate::utils::as_mut_ptr; -use bitflags::bitflags; -use core::mem::MaybeUninit; -use core::ptr::null_mut; - -bitflags! { - /// `PR_PAC_AP*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PointerAuthenticationKeys: u32 { - /// `PR_PAC_APIAKEY`—Instruction authentication key `A`. - const INSTRUCTION_AUTHENTICATION_KEY_A = linux_raw_sys::prctl::PR_PAC_APIAKEY; - /// `PR_PAC_APIBKEY`—Instruction authentication key `B`. - const INSTRUCTION_AUTHENTICATION_KEY_B = linux_raw_sys::prctl::PR_PAC_APIBKEY; - /// `PR_PAC_APDAKEY`—Data authentication key `A`. - const DATA_AUTHENTICATION_KEY_A = linux_raw_sys::prctl::PR_PAC_APDAKEY; - /// `PR_PAC_APDBKEY`—Data authentication key `B`. - const DATA_AUTHENTICATION_KEY_B = linux_raw_sys::prctl::PR_PAC_APDBKEY; - /// `PR_PAC_APGAKEY`—Generic authentication `A` key. - const GENERIC_AUTHENTICATION_KEY_A = linux_raw_sys::prctl::PR_PAC_APGAKEY; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[inline] -pub(crate) unsafe fn prctl_1arg(option: c_int) -> io::Result<c_int> { - const NULL: *mut c_void = null_mut(); - syscalls::prctl(option, NULL, NULL, NULL, NULL) -} - -#[inline] -pub(crate) unsafe fn prctl_2args(option: c_int, arg2: *mut c_void) -> io::Result<c_int> { - const NULL: *mut c_void = null_mut(); - syscalls::prctl(option, arg2, NULL, NULL, NULL) -} - -#[inline] -pub(crate) unsafe fn prctl_3args( - option: c_int, - arg2: *mut c_void, - arg3: *mut c_void, -) -> io::Result<c_int> { - syscalls::prctl(option, arg2, arg3, null_mut(), null_mut()) -} - -#[inline] -pub(crate) unsafe fn prctl_get_at_arg2_optional<P>(option: i32) -> io::Result<P> { - let mut value: MaybeUninit<P> = MaybeUninit::uninit(); - prctl_2args(option, value.as_mut_ptr().cast())?; - Ok(value.assume_init()) -} - -#[inline] -pub(crate) unsafe fn prctl_get_at_arg2<P, T>(option: i32) -> io::Result<T> -where - P: Default, - T: TryFrom<P, Error = io::Errno>, -{ - let mut value: P = Default::default(); - prctl_2args(option, as_mut_ptr(&mut value).cast())?; - TryFrom::try_from(value) -} diff --git a/vendor/rustix/src/process/chdir.rs b/vendor/rustix/src/process/chdir.rs deleted file mode 100644 index 8c373979..00000000 --- a/vendor/rustix/src/process/chdir.rs +++ /dev/null @@ -1,98 +0,0 @@ -#[cfg(not(target_os = "fuchsia"))] -use crate::backend::fd::AsFd; -#[cfg(feature = "fs")] -use crate::path; -#[cfg(any(feature = "fs", not(target_os = "fuchsia")))] -use crate::{backend, io}; -#[cfg(all(feature = "alloc", feature = "fs"))] -use { - crate::ffi::{CStr, CString}, - crate::path::SMALL_PATH_BUFFER_SIZE, - alloc::vec::Vec, -}; - -/// `chdir(path)`—Change the current working directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chdir.html -/// [Linux]: https://man7.org/linux/man-pages/man2/chdir.2.html -#[inline] -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -pub fn chdir<P: path::Arg>(path: P) -> io::Result<()> { - path.into_with_c_str(backend::process::syscalls::chdir) -} - -/// `fchdir(fd)`—Change the current working directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchdir.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fchdir.2.html -#[cfg(not(target_os = "fuchsia"))] -#[inline] -pub fn fchdir<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::process::syscalls::fchdir(fd.as_fd()) -} - -/// `getcwd`—Return the current working directory. -/// -/// If `reuse` already has available capacity, reuse it if possible. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getcwd.html -/// [Linux]: https://man7.org/linux/man-pages/man3/getcwd.3.html -#[cfg(all(feature = "alloc", feature = "fs"))] -#[cfg(not(target_os = "wasi"))] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -#[inline] -pub fn getcwd<B: Into<Vec<u8>>>(reuse: B) -> io::Result<CString> { - _getcwd(reuse.into()) -} - -#[cfg(all(feature = "alloc", feature = "fs"))] -#[allow(unsafe_code)] -fn _getcwd(mut buffer: Vec<u8>) -> io::Result<CString> { - buffer.clear(); - buffer.reserve(SMALL_PATH_BUFFER_SIZE); - - loop { - match backend::process::syscalls::getcwd(buffer.spare_capacity_mut()) { - Err(io::Errno::RANGE) => { - // Use `Vec` reallocation strategy to grow capacity - // exponentially. - buffer.reserve(buffer.capacity() + 1); - } - Ok(_) => { - // SAFETY: - // - “These functions return a null-terminated string” - // - [POSIX definition 3.375: String]: “A contiguous sequence - // of bytes terminated by and including the first null byte.” - // - // Thus, there will be a single NUL byte at the end of the - // string. - // - // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_375 - unsafe { - buffer.set_len( - CStr::from_ptr(buffer.as_ptr().cast()) - .to_bytes_with_nul() - .len(), - ); - - return Ok(CString::from_vec_with_nul_unchecked(buffer)); - } - } - Err(errno) => return Err(errno), - } - } -} diff --git a/vendor/rustix/src/process/chroot.rs b/vendor/rustix/src/process/chroot.rs deleted file mode 100644 index 7c2476db..00000000 --- a/vendor/rustix/src/process/chroot.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -use crate::{backend, io, path}; - -/// `chroot(path)`—Change the process root directory. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/chroot.2.html -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[inline] -pub fn chroot<P: path::Arg>(path: P) -> io::Result<()> { - path.into_with_c_str(backend::process::syscalls::chroot) -} diff --git a/vendor/rustix/src/process/exit.rs b/vendor/rustix/src/process/exit.rs deleted file mode 100644 index e882da14..00000000 --- a/vendor/rustix/src/process/exit.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::backend; - -/// `EXIT_SUCCESS` for use with [`exit`]. -/// -/// [`exit`]: std::process::exit -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html -/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_SUCCESS: i32 = backend::c::EXIT_SUCCESS; - -/// `EXIT_FAILURE` for use with [`exit`]. -/// -/// [`exit`]: std::process::exit -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html -/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_FAILURE: i32 = backend::c::EXIT_FAILURE; - -/// The exit status used by a process terminated with a [`Signal::ABORT`] -/// signal. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://tldp.org/LDP/abs/html/exitcodes.html -/// [`Signal::ABORT`]: crate::process::Signal::ABORT -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub const EXIT_SIGNALED_SIGABRT: i32 = backend::c::EXIT_SIGNALED_SIGABRT; diff --git a/vendor/rustix/src/process/fcntl_getlk.rs b/vendor/rustix/src/process/fcntl_getlk.rs deleted file mode 100644 index 0dbdb945..00000000 --- a/vendor/rustix/src/process/fcntl_getlk.rs +++ /dev/null @@ -1,23 +0,0 @@ -use super::Flock; -use crate::fd::AsFd; -use crate::{backend, io}; - -/// `fcntl(fd, F_GETLK)`—Get the first lock that blocks the lock description -/// pointed to by the argument `lock`. If no such lock is found, then `None` is -/// returned. -/// -/// If `lock.typ` is set to `FlockType::Unlocked`, the returned value/error is -/// not explicitly defined, as per POSIX, and will depend on the underlying -/// platform implementation. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[inline] -#[doc(alias = "F_GETLK")] -pub fn fcntl_getlk<Fd: AsFd>(fd: Fd, lock: &Flock) -> io::Result<Option<Flock>> { - backend::process::syscalls::fcntl_getlk(fd.as_fd(), lock) -} diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs deleted file mode 100644 index 2e9a228f..00000000 --- a/vendor/rustix/src/process/id.rs +++ /dev/null @@ -1,260 +0,0 @@ -//! Unix user, group, and process identifiers. -//! -//! # Safety -//! -//! The `Uid`, `Gid`, and `Pid` types can be constructed from raw integers, -//! which is marked unsafe because actual OS's assign special meaning to some -//! integer values. -#![allow(unsafe_code)] - -use crate::{backend, io}; -#[cfg(feature = "alloc")] -use alloc::vec::Vec; - -pub use crate::pid::{Pid, RawPid}; -pub use crate::ugid::{Gid, RawGid, RawUid, Uid}; - -/// `getuid()`—Returns the process' real user ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getuid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getuid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getuid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getuid -/// [NetBSD]: https://man.netbsd.org/getuid.2 -#[inline] -#[must_use] -pub fn getuid() -> Uid { - backend::ugid::syscalls::getuid() -} - -/// `geteuid()`—Returns the process' effective user ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/geteuid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/geteuid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=geteuid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/geteuid -/// [NetBSD]: https://man.netbsd.org/geteuid.2 -#[inline] -#[must_use] -pub fn geteuid() -> Uid { - backend::ugid::syscalls::geteuid() -} - -/// `getgid()`—Returns the process' real group ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getgid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getgid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getgid -/// [NetBSD]: https://man.netbsd.org/getgid.2 -#[inline] -#[must_use] -pub fn getgid() -> Gid { - backend::ugid::syscalls::getgid() -} - -/// `getegid()`—Returns the process' effective group ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getegid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getegid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getegid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getegid -/// [NetBSD]: https://man.netbsd.org/getegid.2 -#[inline] -#[must_use] -pub fn getegid() -> Gid { - backend::ugid::syscalls::getegid() -} - -/// `getpid()`—Returns the process' ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getpid -/// [NetBSD]: https://man.netbsd.org/getpid.2 -#[inline] -#[must_use] -pub fn getpid() -> Pid { - backend::pid::syscalls::getpid() -} - -/// `getppid()`—Returns the parent process' ID. -/// -/// This will return `None` if the current process has no parent (or no parent -/// accessible in the current PID namespace), such as if the current process is -/// the init process ([`Pid::INIT`]). -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getppid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getppid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getppid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getppid -/// [NetBSD]: https://man.netbsd.org/getppid.2 -#[inline] -#[must_use] -pub fn getppid() -> Option<Pid> { - backend::process::syscalls::getppid() -} - -/// `getpgid(pid)`—Returns the process group ID of the given process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpgid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpgid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getpgid -/// [NetBSD]: https://man.netbsd.org/getpgid.2 -#[inline] -pub fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { - backend::process::syscalls::getpgid(pid) -} - -/// `setpgid(pid, pgid)`—Sets the process group ID of the given process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpgid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setpgid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/setpgid -/// [NetBSD]: https://man.netbsd.org/setpgid.2 -#[inline] -pub fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { - backend::process::syscalls::setpgid(pid, pgid) -} - -/// `getpgrp()`—Returns the process' group ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpgrp.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpgrp.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpgrp&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getpgrp -/// [NetBSD]: https://man.netbsd.org/getpgrp.2 -#[inline] -#[must_use] -pub fn getpgrp() -> Pid { - backend::process::syscalls::getpgrp() -} - -/// `getsid(pid)`—Get the session ID of the given process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getsid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getsid -/// [NetBSD]: https://man.netbsd.org/getsid.2 -#[cfg(not(target_os = "redox"))] -#[inline] -pub fn getsid(pid: Option<Pid>) -> io::Result<Pid> { - backend::process::syscalls::getsid(pid) -} - -/// `setsid()`—Create a new session. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setsid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/setsid -/// [NetBSD]: https://man.netbsd.org/setsid.2 -#[inline] -pub fn setsid() -> io::Result<Pid> { - backend::process::syscalls::setsid() -} - -/// `getgroups()`—Return a list of the current user's groups. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getgroups.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getgroups.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getgroups&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getgroups.2 -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn getgroups() -> io::Result<Vec<Gid>> { - // This code would benefit from having a better way to read into - // uninitialized memory, but that requires `unsafe`. - let mut buffer = Vec::with_capacity(0); - let ngroups = backend::process::syscalls::getgroups(&mut buffer)?; - buffer.resize(ngroups, Gid::ROOT); - backend::process::syscalls::getgroups(&mut buffer)?; - Ok(buffer) -} diff --git a/vendor/rustix/src/process/ioctl.rs b/vendor/rustix/src/process/ioctl.rs deleted file mode 100644 index 5362504f..00000000 --- a/vendor/rustix/src/process/ioctl.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! Process-oriented `ioctl`s. -//! -//! # Safety -//! -//! This module invokes `ioctl`s. - -#![allow(unsafe_code)] - -use crate::{backend, io, ioctl}; -use backend::c; -use backend::fd::AsFd; - -/// `ioctl(fd, TIOCSCTTY, 0)`—Sets the controlling terminal for the process. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=tty&sektion=4 -/// [NetBSD]: https://man.netbsd.org/tty.4 -/// [OpenBSD]: https://man.openbsd.org/tty.4 -#[cfg(not(any( - windows, - target_os = "aix", - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -#[inline] -#[doc(alias = "TIOCSCTTY")] -pub fn ioctl_tiocsctty<Fd: AsFd>(fd: Fd) -> io::Result<()> { - unsafe { ioctl::ioctl(fd, Tiocsctty) } -} - -#[cfg(not(any( - windows, - target_os = "aix", - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -struct Tiocsctty; - -#[cfg(not(any( - windows, - target_os = "aix", - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -unsafe impl ioctl::Ioctl for Tiocsctty { - type Output = (); - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> ioctl::Opcode { - c::TIOCSCTTY as ioctl::Opcode - } - - fn as_ptr(&mut self) -> *mut c::c_void { - crate::utils::as_ptr(&0_u32) as *mut c::c_void - } - - unsafe fn output_from_ptr( - _: ioctl::IoctlOutput, - _: *mut c::c_void, - ) -> io::Result<Self::Output> { - Ok(()) - } -} diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs deleted file mode 100644 index 8299b8ee..00000000 --- a/vendor/rustix/src/process/kill.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::process::Pid; -use crate::{backend, io}; - -pub use crate::signal::Signal; - -/// `kill(pid, sig)`—Sends a signal to a process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - backend::process::syscalls::kill_process(pid, sig) -} - -/// `kill(-pid, sig)`—Sends a signal to all processes in a process group. -/// -/// If `pid` is [`Pid::INIT`], this sends a signal to all processes the current -/// process has permission to send signals to, except process `Pid::INIT`, -/// possibly other system-specific processes, and on some systems, the current -/// process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - backend::process::syscalls::kill_process_group(pid, sig) -} - -/// `kill(0, sig)`—Sends a signal to all processes in the current process -/// group. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn kill_current_process_group(sig: Signal) -> io::Result<()> { - backend::process::syscalls::kill_current_process_group(sig) -} - -/// `kill(pid, 0)`—Check validity of pid and permissions to send signals to -/// the process, without actually sending any signals. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn test_kill_process(pid: Pid) -> io::Result<()> { - backend::process::syscalls::test_kill_process(pid) -} - -/// `kill(-pid, 0)`—Check validity of pid and permissions to send signals to -/// all processes in the process group, without actually sending any signals. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn test_kill_process_group(pid: Pid) -> io::Result<()> { - backend::process::syscalls::test_kill_process_group(pid) -} - -/// `kill(0, 0)`—Check validity of pid and permissions to send signals to the -/// all processes in the current process group, without actually sending any -/// signals. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn test_kill_current_process_group() -> io::Result<()> { - backend::process::syscalls::test_kill_current_process_group() -} diff --git a/vendor/rustix/src/process/mod.rs b/vendor/rustix/src/process/mod.rs deleted file mode 100644 index 7509b060..00000000 --- a/vendor/rustix/src/process/mod.rs +++ /dev/null @@ -1,114 +0,0 @@ -//! Process-associated operations. - -#[cfg(not(target_os = "wasi"))] -mod chdir; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -mod chroot; -mod exit; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod fcntl_getlk; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. -mod id; -#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "vita")))] -mod ioctl; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -mod kill; -#[cfg(target_os = "linux")] -mod pidfd; -#[cfg(target_os = "linux")] -mod pidfd_getfd; -#[cfg(target_os = "linux")] -mod pivot_root; -#[cfg(linux_kernel)] -mod prctl; -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -// WASI doesn't have [gs]etpriority. -mod priority; -#[cfg(freebsdlike)] -mod procctl; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod rlimit; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod types; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have umask. -mod umask; -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -mod wait; - -#[cfg(not(target_os = "wasi"))] -pub use chdir::*; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -pub use chroot::*; -pub use exit::*; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use fcntl_getlk::*; -#[cfg(not(target_os = "wasi"))] -pub use id::*; -#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "vita")))] -pub use ioctl::*; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub use kill::*; -#[cfg(target_os = "linux")] -pub use pidfd::*; -#[cfg(target_os = "linux")] -pub use pidfd_getfd::*; -#[cfg(target_os = "linux")] -pub use pivot_root::*; -#[cfg(linux_kernel)] -pub use prctl::*; -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -pub use priority::*; -#[cfg(freebsdlike)] -pub use procctl::*; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use rlimit::*; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use types::*; -#[cfg(not(target_os = "wasi"))] -pub use umask::*; -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -pub use wait::*; diff --git a/vendor/rustix/src/process/pidfd.rs b/vendor/rustix/src/process/pidfd.rs deleted file mode 100644 index f812a9f6..00000000 --- a/vendor/rustix/src/process/pidfd.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::fd::OwnedFd; -use crate::process::{Pid, Signal}; -use crate::{backend, ffi, io}; -use backend::fd::AsFd; - -bitflags::bitflags! { - /// `PIDFD_*` flags for use with [`pidfd_open`]. - /// - /// [`pidfd_open`]: crate::process::pidfd_open - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PidfdFlags: ffi::c_uint { - /// `PIDFD_NONBLOCK` - const NONBLOCK = backend::c::PIDFD_NONBLOCK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `syscall(SYS_pidfd_open, pid, flags)`—Creates a file descriptor for a -/// process. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pidfd_open.2.html -#[inline] -pub fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { - backend::process::syscalls::pidfd_open(pid, flags) -} - -/// `syscall(SYS_pidfd_send_signal, pidfd, sig, NULL, 0)`—Send a signal to a -/// process specified by a file descriptor. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pidfd_send_signal.2.html -#[inline] -pub fn pidfd_send_signal<Fd: AsFd>(pidfd: Fd, sig: Signal) -> io::Result<()> { - backend::process::syscalls::pidfd_send_signal(pidfd.as_fd(), sig) -} diff --git a/vendor/rustix/src/process/pidfd_getfd.rs b/vendor/rustix/src/process/pidfd_getfd.rs deleted file mode 100644 index 1be215e0..00000000 --- a/vendor/rustix/src/process/pidfd_getfd.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! The [`pidfd_getfd`] function and supporting types. - -#![allow(unsafe_code)] -use crate::fd::OwnedFd; -use crate::{backend, ffi, io}; -use backend::fd::{AsFd, RawFd}; - -/// Raw file descriptor in another process. -/// -/// A distinct type alias is used here to inform the user that normal file -/// descriptors from the calling process should not be used. The provided file -/// descriptor is used by the kernel as the index into the file descriptor -/// table of an entirely different process. -pub type ForeignRawFd = RawFd; - -bitflags::bitflags! { - /// All flags are reserved for future use. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PidfdGetfdFlags: ffi::c_uint { - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `syscall(SYS_pidfd_getfd, pidfd, flags)`—Obtain a duplicate of another -/// process' file descriptor. -/// -/// # References -/// - [Linux] -/// -/// # Warning -/// -/// This function is generally safe for the calling process, but it can impact -/// the target process in unexpected ways. If you want to ensure that Rust I/O -/// safety assumptions continue to hold in the target process, then the target -/// process must have communicated the file description number to the calling -/// process from a value of a type that implements `AsRawFd`, and the target -/// process must not drop that value until after the calling process has -/// returned from `pidfd_getfd`. -/// -/// When `pidfd_getfd` is used to debug the target, or the target is not a Rust -/// application, or `pidfd_getfd` is used in any other way, then extra care -/// should be taken to avoid unexpected behaviour or crashes. -/// -/// For further details, see the references above. -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pidfd_getfd.2.html -#[inline] -pub fn pidfd_getfd<Fd: AsFd>( - pidfd: Fd, - targetfd: ForeignRawFd, - flags: PidfdGetfdFlags, -) -> io::Result<OwnedFd> { - backend::process::syscalls::pidfd_getfd(pidfd.as_fd(), targetfd, flags) -} diff --git a/vendor/rustix/src/process/pivot_root.rs b/vendor/rustix/src/process/pivot_root.rs deleted file mode 100644 index 91672774..00000000 --- a/vendor/rustix/src/process/pivot_root.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -use crate::{backend, io, path}; - -/// `pivot_root(new_root, put_old)`—Change the root mount. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pivot_root.2.html -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[inline] -pub fn pivot_root<P: path::Arg, Q: path::Arg>(new_root: P, put_old: Q) -> io::Result<()> { - new_root.into_with_c_str(|new_root| { - put_old.into_with_c_str(|put_old| backend::process::syscalls::pivot_root(new_root, put_old)) - }) -} diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs deleted file mode 100644 index 8b08409c..00000000 --- a/vendor/rustix/src/process/prctl.rs +++ /dev/null @@ -1,1165 +0,0 @@ -//! Bindings for the Linux `prctl` system call. -//! -//! There are similarities (but also differences) with FreeBSD's `procctl` -//! system call, whose interface is located in the `procctl.rs` file. - -#![allow(unsafe_code)] - -use core::mem::size_of; -use core::num::NonZeroI32; -use core::ptr::{null, null_mut, NonNull}; - -use bitflags::bitflags; - -use crate::backend::prctl::syscalls; -use crate::fd::{AsRawFd as _, BorrowedFd, RawFd}; -use crate::ffi::{c_int, c_uint, c_void, CStr}; -use crate::io; -use crate::prctl::*; -use crate::process::{Pid, RawPid}; -use crate::signal::Signal; -use crate::utils::{as_mut_ptr, as_ptr}; - -// -// PR_GET_PDEATHSIG/PR_SET_PDEATHSIG -// - -const PR_GET_PDEATHSIG: c_int = 2; - -/// Get the current value of the parent process death signal. -/// -/// # References -/// - [Linux: `prctl(PR_GET_PDEATHSIG,…)`] -/// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,…)`] -/// -/// [Linux: `prctl(PR_GET_PDEATHSIG,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -#[doc(alias = "PR_GET_PDEATHSIG")] -pub fn parent_process_death_signal() -> io::Result<Option<Signal>> { - let raw = unsafe { prctl_get_at_arg2_optional::<c_int>(PR_GET_PDEATHSIG)? }; - if let Some(non_zero) = NonZeroI32::new(raw) { - // SAFETY: The only way to get a libc-reserved signal number in - // here would be to do something equivalent to - // `set_parent_process_death_signal`, but that would have required - // using a `Signal` with a libc-reserved value. - Ok(Some(unsafe { - Signal::from_raw_nonzero_unchecked(non_zero) - })) - } else { - Ok(None) - } -} - -const PR_SET_PDEATHSIG: c_int = 1; - -/// Set the parent-death signal of the calling process. -/// -/// # References -/// - [Linux: `prctl(PR_SET_PDEATHSIG,…)`] -/// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,…)`] -/// -/// [Linux: `prctl(PR_SET_PDEATHSIG,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -#[doc(alias = "PR_SET_PDEATHSIG")] -pub fn set_parent_process_death_signal(signal: Option<Signal>) -> io::Result<()> { - let signal = signal.map_or(0_usize, |signal| signal.as_raw() as usize); - unsafe { prctl_2args(PR_SET_PDEATHSIG, signal as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_DUMPABLE/PR_SET_DUMPABLE -// - -const PR_GET_DUMPABLE: c_int = 3; - -const SUID_DUMP_DISABLE: i32 = 0; -const SUID_DUMP_USER: i32 = 1; -const SUID_DUMP_ROOT: i32 = 2; - -/// `SUID_DUMP_*` values for use with [`dumpable_behavior`] and -/// [`set_dumpable_behavior`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum DumpableBehavior { - /// Not dumpable. - #[doc(alias = "SUID_DUMP_DISABLE")] - NotDumpable = SUID_DUMP_DISABLE, - /// Dumpable. - #[doc(alias = "SUID_DUMP_USER")] - Dumpable = SUID_DUMP_USER, - /// Dumpable but only readable by root. - #[doc(alias = "SUID_DUMP_ROOT")] - DumpableReadableOnlyByRoot = SUID_DUMP_ROOT, -} - -impl TryFrom<i32> for DumpableBehavior { - type Error = io::Errno; - - fn try_from(value: i32) -> Result<Self, Self::Error> { - match value { - SUID_DUMP_DISABLE => Ok(Self::NotDumpable), - SUID_DUMP_USER => Ok(Self::Dumpable), - SUID_DUMP_ROOT => Ok(Self::DumpableReadableOnlyByRoot), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the current state of the calling process' `dumpable` attribute. -/// -/// # References -/// - [`prctl(PR_GET_DUMPABLE,…)`] -/// -/// [`prctl(PR_GET_DUMPABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_DUMPABLE")] -pub fn dumpable_behavior() -> io::Result<DumpableBehavior> { - unsafe { prctl_1arg(PR_GET_DUMPABLE) }.and_then(TryInto::try_into) -} - -const PR_SET_DUMPABLE: c_int = 4; - -/// Set the state of the `dumpable` attribute. -/// -/// This attribute determines whether the process can be traced and whether -/// core dumps are produced for the calling process upon delivery of a signal -/// whose default behavior is to produce a core dump. -/// -/// A similar function with the same name is available on FreeBSD (as part of -/// the `procctl` interface), but it has an extra argument which allows to -/// select a process other then the current process. -/// -/// # References -/// - [`prctl(PR_SET_DUMPABLE,…)`] -/// -/// [`prctl(PR_SET_DUMPABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_DUMPABLE")] -pub fn set_dumpable_behavior(config: DumpableBehavior) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_DUMPABLE, config as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_UNALIGN/PR_SET_UNALIGN -// - -const PR_GET_UNALIGN: c_int = 5; - -bitflags! { - /// `PR_UNALIGN_*` flags for use with [`unaligned_access_control`] and - /// [`set_unaligned_access_control`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UnalignedAccessControl: u32 { - /// Silently fix up unaligned user accesses. - #[doc(alias = "NOPRINT")] - #[doc(alias = "PR_UNALIGN_NOPRINT")] - const NO_PRINT = 1; - /// Generate a [`Signal::Bus`] signal on unaligned user access. - #[doc(alias = "PR_UNALIGN_SIGBUS")] - const SIGBUS = 2; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Get unaligned access control bits. -/// -/// # References -/// - [`prctl(PR_GET_UNALIGN,…)`] -/// -/// [`prctl(PR_GET_UNALIGN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_UNALIGN")] -pub fn unaligned_access_control() -> io::Result<UnalignedAccessControl> { - let r = unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_UNALIGN)? }; - UnalignedAccessControl::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_SET_UNALIGN: c_int = 6; - -/// Set unaligned access control bits. -/// -/// # References -/// - [`prctl(PR_SET_UNALIGN,…)`] -/// -/// [`prctl(PR_SET_UNALIGN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_UNALIGN")] -pub fn set_unaligned_access_control(config: UnalignedAccessControl) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_UNALIGN, config.bits() as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_FPEMU/PR_SET_FPEMU -// - -const PR_GET_FPEMU: c_int = 9; - -bitflags! { - /// `PR_FPEMU_*` flags for use with [`floating_point_emulation_control`] - /// and [`set_floating_point_emulation_control`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FloatingPointEmulationControl: u32 { - /// Silently emulate floating point operations accesses. - #[doc(alias = "PR_UNALIGN_NOPRINT")] - const NO_PRINT = 1; - /// Don't emulate floating point operations, send a [`Signal::Fpe`] - /// signal instead. - #[doc(alias = "PR_UNALIGN_SIGFPE")] - const SIGFPE = 2; - } -} - -/// Get floating point emulation control bits. -/// -/// # References -/// - [`prctl(PR_GET_FPEMU,…)`] -/// -/// [`prctl(PR_GET_FPEMU,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_FPEMU")] -pub fn floating_point_emulation_control() -> io::Result<FloatingPointEmulationControl> { - let r = unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_FPEMU)? }; - FloatingPointEmulationControl::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_SET_FPEMU: c_int = 10; - -/// Set floating point emulation control bits. -/// -/// # References -/// - [`prctl(PR_SET_FPEMU,…)`] -/// -/// [`prctl(PR_SET_FPEMU,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_FPEMU")] -pub fn set_floating_point_emulation_control( - config: FloatingPointEmulationControl, -) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_FPEMU, config.bits() as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_FPEXC/PR_SET_FPEXC -// - -const PR_GET_FPEXC: c_int = 11; - -bitflags! { - /// Zero means floating point exceptions are disabled. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FloatingPointExceptionMode: u32 { - /// Async non-recoverable exception mode. - const NONRECOV = 1; - /// Async recoverable exception mode. - const ASYNC = 2; - /// Precise exception mode. - const PRECISE = 3; - - /// Use FPEXC for floating point exception enables. - const SW_ENABLE = 0x80; - /// Floating point divide by zero. - const DIV = 0x01_0000; - /// Floating point overflow. - const OVF = 0x02_0000; - /// Floating point underflow. - const UND = 0x04_0000; - /// Floating point inexact result. - const RES = 0x08_0000; - /// Floating point invalid operation. - const INV = 0x10_0000; - } -} - -/// Get floating point exception mode. -/// -/// # References -/// - [`prctl(PR_GET_FPEXC,…)`] -/// -/// [`prctl(PR_GET_FPEXC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_FPEXEC")] -pub fn floating_point_exception_mode() -> io::Result<Option<FloatingPointExceptionMode>> { - unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_FPEXC) } - .map(FloatingPointExceptionMode::from_bits) -} - -const PR_SET_FPEXC: c_int = 12; - -/// Set floating point exception mode. -/// -/// # References -/// - [`prctl(PR_SET_FPEXC,…)`] -/// -/// [`prctl(PR_SET_FPEXC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_FPEXEC")] -pub fn set_floating_point_exception_mode( - config: Option<FloatingPointExceptionMode>, -) -> io::Result<()> { - let config = config.as_ref().map_or(0, FloatingPointExceptionMode::bits); - unsafe { prctl_2args(PR_SET_FPEXC, config as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_TIMING/PR_SET_TIMING -// - -const PR_GET_TIMING: c_int = 13; - -const PR_TIMING_STATISTICAL: i32 = 0; -const PR_TIMING_TIMESTAMP: i32 = 1; - -/// `PR_TIMING_*` values for use with [`timing_method`] and -/// [`set_timing_method`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum TimingMethod { - /// Normal, traditional, statistical process timing. - Statistical = PR_TIMING_STATISTICAL, - /// Accurate timestamp based process timing. - TimeStamp = PR_TIMING_TIMESTAMP, -} - -impl TryFrom<i32> for TimingMethod { - type Error = io::Errno; - - fn try_from(value: i32) -> Result<Self, Self::Error> { - match value { - PR_TIMING_STATISTICAL => Ok(Self::Statistical), - PR_TIMING_TIMESTAMP => Ok(Self::TimeStamp), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get which process timing method is currently in use. -/// -/// # References -/// - [`prctl(PR_GET_TIMING,…)`] -/// -/// [`prctl(PR_GET_TIMING,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_TIMING")] -pub fn timing_method() -> io::Result<TimingMethod> { - unsafe { prctl_1arg(PR_GET_TIMING) }.and_then(TryInto::try_into) -} - -const PR_SET_TIMING: c_int = 14; - -/// Set whether to use (normal, traditional) statistical process timing or -/// accurate timestamp-based process timing. -/// -/// # References -/// - [`prctl(PR_SET_TIMING,…)`] -/// -/// [`prctl(PR_SET_TIMING,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_TIMING")] -pub fn set_timing_method(method: TimingMethod) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_TIMING, method as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_ENDIAN/PR_SET_ENDIAN -// - -const PR_GET_ENDIAN: c_int = 19; - -const PR_ENDIAN_BIG: u32 = 0; -const PR_ENDIAN_LITTLE: u32 = 1; -const PR_ENDIAN_PPC_LITTLE: u32 = 2; - -/// `PR_ENDIAN_*` values for use with [`endian_mode`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum EndianMode { - /// Big endian mode. - Big = PR_ENDIAN_BIG, - /// True little endian mode. - Little = PR_ENDIAN_LITTLE, - /// `PowerPC` pseudo little endian. - PowerPCLittle = PR_ENDIAN_PPC_LITTLE, -} - -impl TryFrom<u32> for EndianMode { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_ENDIAN_BIG => Ok(Self::Big), - PR_ENDIAN_LITTLE => Ok(Self::Little), - PR_ENDIAN_PPC_LITTLE => Ok(Self::PowerPCLittle), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the endianness of the calling process. -/// -/// # References -/// - [`prctl(PR_GET_ENDIAN,…)`] -/// -/// [`prctl(PR_GET_ENDIAN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_ENDIAN")] -pub fn endian_mode() -> io::Result<EndianMode> { - unsafe { prctl_get_at_arg2::<c_uint, _>(PR_GET_ENDIAN) } -} - -const PR_SET_ENDIAN: c_int = 20; - -/// Set the endianness of the calling process. -/// -/// # References -/// - [`prctl(PR_SET_ENDIAN,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_ENDIAN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_ENDIAN")] -pub unsafe fn set_endian_mode(mode: EndianMode) -> io::Result<()> { - prctl_2args(PR_SET_ENDIAN, mode as usize as *mut _).map(|_r| ()) -} - -// -// PR_GET_TSC/PR_SET_TSC -// - -const PR_GET_TSC: c_int = 25; - -const PR_TSC_ENABLE: u32 = 1; -const PR_TSC_SIGSEGV: u32 = 2; - -/// `PR_TSC_*` values for use with [`time_stamp_counter_readability`] and -/// [`set_time_stamp_counter_readability`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum TimeStampCounterReadability { - /// Allow the use of the timestamp counter. - Readable = PR_TSC_ENABLE, - /// Throw a [`Signal::SEGV`] signal instead of reading the TSC. - RaiseSIGSEGV = PR_TSC_SIGSEGV, -} - -impl TryFrom<u32> for TimeStampCounterReadability { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_TSC_ENABLE => Ok(Self::Readable), - PR_TSC_SIGSEGV => Ok(Self::RaiseSIGSEGV), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the state of the flag determining if the timestamp counter can be read. -/// -/// # References -/// - [`prctl(PR_GET_TSC,…)`] -/// -/// [`prctl(PR_GET_TSC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_TSC")] -pub fn time_stamp_counter_readability() -> io::Result<TimeStampCounterReadability> { - unsafe { prctl_get_at_arg2::<c_uint, _>(PR_GET_TSC) } -} - -const PR_SET_TSC: c_int = 26; - -/// Set the state of the flag determining if the timestamp counter can be read -/// by the process. -/// -/// # References -/// - [`prctl(PR_SET_TSC,…)`] -/// -/// [`prctl(PR_SET_TSC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_TSC")] -pub fn set_time_stamp_counter_readability( - readability: TimeStampCounterReadability, -) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_TSC, readability as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_TASK_PERF_EVENTS_DISABLE/PR_TASK_PERF_EVENTS_ENABLE -// - -const PR_TASK_PERF_EVENTS_DISABLE: c_int = 31; -const PR_TASK_PERF_EVENTS_ENABLE: c_int = 32; - -/// Enable or disable all performance counters attached to the calling process. -/// -/// # References -/// - [`prctl(PR_TASK_PERF_EVENTS_ENABLE,…)`] -/// - [`prctl(PR_TASK_PERF_EVENTS_DISABLE,…)`] -/// -/// [`prctl(PR_TASK_PERF_EVENTS_ENABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [`prctl(PR_TASK_PERF_EVENTS_DISABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_TASK_PERF_EVENTS_ENABLE")] -#[doc(alias = "PR_TASK_PERF_EVENTS_DISABLE")] -pub fn configure_performance_counters(enable: bool) -> io::Result<()> { - let option = if enable { - PR_TASK_PERF_EVENTS_ENABLE - } else { - PR_TASK_PERF_EVENTS_DISABLE - }; - - unsafe { prctl_1arg(option) }.map(|_r| ()) -} - -// -// PR_MCE_KILL_GET/PR_MCE_KILL -// - -const PR_MCE_KILL_GET: c_int = 34; - -const PR_MCE_KILL_LATE: u32 = 0; -const PR_MCE_KILL_EARLY: u32 = 1; -const PR_MCE_KILL_DEFAULT: u32 = 2; - -/// `PR_MCE_KILL_*` values for use with -/// [`machine_check_memory_corruption_kill_policy`] and -/// [`set_machine_check_memory_corruption_kill_policy`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum MachineCheckMemoryCorruptionKillPolicy { - /// Late kill policy. - #[doc(alias = "PR_MCE_KILL_LATE")] - Late = PR_MCE_KILL_LATE, - /// Early kill policy. - #[doc(alias = "PR_MCE_KILL_EARLY")] - Early = PR_MCE_KILL_EARLY, - /// System-wide default policy. - #[doc(alias = "PR_MCE_KILL_DEFAULT")] - Default = PR_MCE_KILL_DEFAULT, -} - -impl TryFrom<u32> for MachineCheckMemoryCorruptionKillPolicy { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_MCE_KILL_LATE => Ok(Self::Late), - PR_MCE_KILL_EARLY => Ok(Self::Early), - PR_MCE_KILL_DEFAULT => Ok(Self::Default), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the current per-process machine check kill policy. -/// -/// # References -/// - [`prctl(PR_MCE_KILL_GET,…)`] -/// -/// [`prctl(PR_MCE_KILL_GET,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_MCE_KILL_GET")] -pub fn machine_check_memory_corruption_kill_policy( -) -> io::Result<MachineCheckMemoryCorruptionKillPolicy> { - let r = unsafe { prctl_1arg(PR_MCE_KILL_GET)? } as c_uint; - MachineCheckMemoryCorruptionKillPolicy::try_from(r) -} - -const PR_MCE_KILL: c_int = 33; - -const PR_MCE_KILL_CLEAR: usize = 0; -const PR_MCE_KILL_SET: usize = 1; - -/// Set the machine check memory corruption kill policy for the calling thread. -/// -/// # References -/// - [`prctl(PR_MCE_KILL,…)`] -/// -/// [`prctl(PR_MCE_KILL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_MCE_KILL")] -pub fn set_machine_check_memory_corruption_kill_policy( - policy: Option<MachineCheckMemoryCorruptionKillPolicy>, -) -> io::Result<()> { - let (sub_operation, policy) = if let Some(policy) = policy { - (PR_MCE_KILL_SET, policy as usize as *mut _) - } else { - (PR_MCE_KILL_CLEAR, null_mut()) - }; - - unsafe { prctl_3args(PR_MCE_KILL, sub_operation as *mut _, policy) }.map(|_r| ()) -} - -// -// PR_SET_MM -// - -const PR_SET_MM: c_int = 35; - -const PR_SET_MM_START_CODE: u32 = 1; -const PR_SET_MM_END_CODE: u32 = 2; -const PR_SET_MM_START_DATA: u32 = 3; -const PR_SET_MM_END_DATA: u32 = 4; -const PR_SET_MM_START_STACK: u32 = 5; -const PR_SET_MM_START_BRK: u32 = 6; -const PR_SET_MM_BRK: u32 = 7; -const PR_SET_MM_ARG_START: u32 = 8; -const PR_SET_MM_ARG_END: u32 = 9; -const PR_SET_MM_ENV_START: u32 = 10; -const PR_SET_MM_ENV_END: u32 = 11; -const PR_SET_MM_AUXV: usize = 12; -const PR_SET_MM_EXE_FILE: usize = 13; -const PR_SET_MM_MAP: usize = 14; -const PR_SET_MM_MAP_SIZE: usize = 15; - -/// `PR_SET_MM_*` values for use with [`set_virtual_memory_map_address`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum VirtualMemoryMapAddress { - /// Set the address above which the program text can run. - CodeStart = PR_SET_MM_START_CODE, - /// Set the address below which the program text can run. - CodeEnd = PR_SET_MM_END_CODE, - /// Set the address above which initialized and uninitialized (bss) data - /// are placed. - DataStart = PR_SET_MM_START_DATA, - /// Set the address below which initialized and uninitialized (bss) data - /// are placed. - DataEnd = PR_SET_MM_END_DATA, - /// Set the start address of the stack. - StackStart = PR_SET_MM_START_STACK, - /// Set the address above which the program heap can be expanded with `brk` - /// call. - BrkStart = PR_SET_MM_START_BRK, - /// Set the current `brk` value. - BrkCurrent = PR_SET_MM_BRK, - /// Set the address above which the program command line is placed. - ArgStart = PR_SET_MM_ARG_START, - /// Set the address below which the program command line is placed. - ArgEnd = PR_SET_MM_ARG_END, - /// Set the address above which the program environment is placed. - EnvironmentStart = PR_SET_MM_ENV_START, - /// Set the address below which the program environment is placed. - EnvironmentEnd = PR_SET_MM_ENV_END, -} - -/// Modify certain kernel memory map descriptor addresses of the calling -/// process. -/// -/// # References -/// - [`prctl(PR_SET_MM,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_MM,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -pub unsafe fn set_virtual_memory_map_address( - option: VirtualMemoryMapAddress, - address: Option<NonNull<c_void>>, -) -> io::Result<()> { - let address = address.map_or_else(null_mut, NonNull::as_ptr); - prctl_3args(PR_SET_MM, option as usize as *mut _, address).map(|_r| ()) -} - -/// Supersede the `/proc/pid/exe` symbolic link with a new one pointing to a -/// new executable file. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,…)`] -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_EXE_FILE")] -pub fn set_executable_file(fd: BorrowedFd<'_>) -> io::Result<()> { - let fd = usize::try_from(fd.as_raw_fd()).map_err(|_r| io::Errno::RANGE)?; - unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_EXE_FILE as *mut _, fd as *mut _) }.map(|_r| ()) -} - -/// Set a new auxiliary vector. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_AUXV,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_AUXV,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_AUXV")] -pub unsafe fn set_auxiliary_vector(auxv: &[*const c_void]) -> io::Result<()> { - syscalls::prctl( - PR_SET_MM, - PR_SET_MM_AUXV as *mut _, - auxv.as_ptr() as *mut _, - auxv.len() as *mut _, - null_mut(), - ) - .map(|_r| ()) -} - -/// Get the size of the [`PrctlMmMap`] the kernel expects. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,…)`] -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_MAP_SIZE")] -pub fn virtual_memory_map_config_struct_size() -> io::Result<usize> { - let mut value: c_uint = 0; - let value_ptr = as_mut_ptr(&mut value); - unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_MAP_SIZE as *mut _, value_ptr.cast())? }; - Ok(value as usize) -} - -/// This structure provides new memory descriptor map which mostly modifies -/// `/proc/pid/stat[m]` output for a task. -/// This mostly done in a sake of checkpoint/restore functionality. -#[repr(C)] -#[derive(Debug, Clone)] -pub struct PrctlMmMap { - /// Code section start address. - pub start_code: u64, - /// Code section end address. - pub end_code: u64, - /// Data section start address. - pub start_data: u64, - /// Data section end address. - pub end_data: u64, - /// `brk` start address. - pub start_brk: u64, - /// `brk` current address. - pub brk: u64, - /// Stack start address. - pub start_stack: u64, - /// Program command line start address. - pub arg_start: u64, - /// Program command line end address. - pub arg_end: u64, - /// Program environment start address. - pub env_start: u64, - /// Program environment end address. - pub env_end: u64, - /// Auxiliary vector start address. - pub auxv: *mut u64, - /// Auxiliary vector size. - pub auxv_size: u32, - /// File descriptor of executable file that was used to create this - /// process. - pub exe_fd: RawFd, -} - -/// Provides one-shot access to all the addresses by passing in a -/// [`PrctlMmMap`]. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_MAP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_MAP")] -pub unsafe fn configure_virtual_memory_map(config: &PrctlMmMap) -> io::Result<()> { - syscalls::prctl( - PR_SET_MM, - PR_SET_MM_MAP as *mut _, - as_ptr(config) as *mut _, - size_of::<PrctlMmMap>() as *mut _, - null_mut(), - ) - .map(|_r| ()) -} - -// -// PR_SET_PTRACER -// - -const PR_SET_PTRACER: c_int = 0x59_61_6d_61; - -const PR_SET_PTRACER_ANY: usize = usize::MAX; - -/// Process ptracer. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PTracer { - /// None. - None, - /// Disable `ptrace` restrictions for the calling process. - Any, - /// Specific process. - ProcessID(Pid), -} - -/// Declare that the ptracer process can `ptrace` the calling process as if it -/// were a direct process ancestor. -/// -/// # References -/// - [`prctl(PR_SET_PTRACER,…)`] -/// -/// [`prctl(PR_SET_PTRACER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_PTRACER")] -pub fn set_ptracer(tracer: PTracer) -> io::Result<()> { - let pid = match tracer { - PTracer::None => null_mut(), - PTracer::Any => PR_SET_PTRACER_ANY as *mut _, - PTracer::ProcessID(pid) => pid.as_raw_nonzero().get() as usize as *mut _, - }; - - unsafe { prctl_2args(PR_SET_PTRACER, pid) }.map(|_r| ()) -} - -// -// PR_GET_CHILD_SUBREAPER/PR_SET_CHILD_SUBREAPER -// - -const PR_GET_CHILD_SUBREAPER: c_int = 37; - -/// Get the `child subreaper` setting of the calling process. -/// -/// # References -/// - [`prctl(PR_GET_CHILD_SUBREAPER,…)`] -/// -/// [`prctl(PR_GET_CHILD_SUBREAPER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_CHILD_SUBREAPER")] -pub fn child_subreaper() -> io::Result<Option<Pid>> { - unsafe { - let r = prctl_get_at_arg2_optional::<c_uint>(PR_GET_CHILD_SUBREAPER)?; - Ok(Pid::from_raw(r as RawPid)) - } -} - -const PR_SET_CHILD_SUBREAPER: c_int = 36; - -/// Set the `child subreaper` attribute of the calling process. -/// -/// # References -/// - [`prctl(PR_SET_CHILD_SUBREAPER,…)`] -/// -/// [`prctl(PR_SET_CHILD_SUBREAPER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_CHILD_SUBREAPER")] -pub fn set_child_subreaper(pid: Option<Pid>) -> io::Result<()> { - let pid = pid.map_or(0_usize, |pid| pid.as_raw_nonzero().get() as usize); - unsafe { prctl_2args(PR_SET_CHILD_SUBREAPER, pid as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_FP_MODE/PR_SET_FP_MODE -// - -const PR_GET_FP_MODE: c_int = 46; - -const PR_FP_MODE_FR: u32 = 1_u32 << 0; -const PR_FP_MODE_FRE: u32 = 1_u32 << 1; - -/// `PR_FP_MODE_*` values for use with [`floating_point_mode`] and -/// [`set_floating_point_mode`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum FloatingPointMode { - /// 64-bit floating point registers. - FloatingPointRegisters = PR_FP_MODE_FR, - /// Enable emulation of 32-bit floating-point mode. - FloatingPointEmulation = PR_FP_MODE_FRE, -} - -impl TryFrom<u32> for FloatingPointMode { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_FP_MODE_FR => Ok(Self::FloatingPointRegisters), - PR_FP_MODE_FRE => Ok(Self::FloatingPointEmulation), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the current floating point mode. -/// -/// # References -/// - [`prctl(PR_GET_FP_MODE,…)`] -/// -/// [`prctl(PR_GET_FP_MODE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_FP_MODE")] -pub fn floating_point_mode() -> io::Result<FloatingPointMode> { - let r = unsafe { prctl_1arg(PR_GET_FP_MODE)? } as c_uint; - FloatingPointMode::try_from(r) -} - -const PR_SET_FP_MODE: c_int = 45; - -/// Allow control of the floating point mode from user space. -/// -/// # References -/// - [`prctl(PR_SET_FP_MODE,…)`] -/// -/// [`prctl(PR_SET_FP_MODE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_FP_MODE")] -pub fn set_floating_point_mode(mode: FloatingPointMode) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_FP_MODE, mode as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_SPECULATION_CTRL/PR_SET_SPECULATION_CTRL -// - -const PR_GET_SPECULATION_CTRL: c_int = 52; - -const PR_SPEC_STORE_BYPASS: u32 = 0; -const PR_SPEC_INDIRECT_BRANCH: u32 = 1; -const PR_SPEC_L1D_FLUSH: u32 = 2; - -/// `PR_SPEC_*` values for use with [`speculative_feature_state`] and -/// [`control_speculative_feature`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum SpeculationFeature { - /// Set the state of the speculative store bypass misfeature. - SpeculativeStoreBypass = PR_SPEC_STORE_BYPASS, - /// Set the state of the indirect branch speculation misfeature. - IndirectBranchSpeculation = PR_SPEC_INDIRECT_BRANCH, - /// Flush L1D Cache on context switch out of the task. - FlushL1DCacheOnContextSwitchOutOfTask = PR_SPEC_L1D_FLUSH, -} - -impl TryFrom<u32> for SpeculationFeature { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_SPEC_STORE_BYPASS => Ok(Self::SpeculativeStoreBypass), - PR_SPEC_INDIRECT_BRANCH => Ok(Self::IndirectBranchSpeculation), - PR_SPEC_L1D_FLUSH => Ok(Self::FlushL1DCacheOnContextSwitchOutOfTask), - _ => Err(io::Errno::RANGE), - } - } -} - -bitflags! { - /// `PR_SPEC_*` flags for use with [`control_speculative_feature`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpeculationFeatureControl: u32 { - /// The speculation feature is enabled, mitigation is disabled. - const ENABLE = 1_u32 << 1; - /// The speculation feature is disabled, mitigation is enabled. - const DISABLE = 1_u32 << 2; - /// The speculation feature is disabled, mitigation is enabled, and it - /// cannot be undone. - const FORCE_DISABLE = 1_u32 << 3; - /// The speculation feature is disabled, mitigation is enabled, and the - /// state will be cleared on `execve`. - const DISABLE_NOEXEC = 1_u32 << 4; - } -} - -bitflags! { - /// Zero means the processors are not vulnerable. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpeculationFeatureState: u32 { - /// Mitigation can be controlled per thread by - /// [`control_speculative_feature`]. - const PRCTL = 1_u32 << 0; - /// The speculation feature is enabled, mitigation is disabled. - const ENABLE = 1_u32 << 1; - /// The speculation feature is disabled, mitigation is enabled. - const DISABLE = 1_u32 << 2; - /// The speculation feature is disabled, mitigation is enabled, and it - /// cannot be undone. - const FORCE_DISABLE = 1_u32 << 3; - /// The speculation feature is disabled, mitigation is enabled, and the - /// state will be cleared on `execve`. - const DISABLE_NOEXEC = 1_u32 << 4; - } -} - -/// Get the state of the speculation misfeature. -/// -/// # References -/// - [`prctl(PR_GET_SPECULATION_CTRL,…)`] -/// -/// [`prctl(PR_GET_SPECULATION_CTRL,…)`]: https://www.kernel.org/doc/html/v6.13/userspace-api/spec_ctrl.html -#[inline] -#[doc(alias = "PR_GET_SPECULATION_CTRL")] -pub fn speculative_feature_state( - feature: SpeculationFeature, -) -> io::Result<Option<SpeculationFeatureState>> { - let r = unsafe { prctl_2args(PR_GET_SPECULATION_CTRL, feature as usize as *mut _)? } as c_uint; - Ok(SpeculationFeatureState::from_bits(r)) -} - -const PR_SET_SPECULATION_CTRL: c_int = 53; - -/// Sets the state of the speculation misfeature. -/// -/// # References -/// - [`prctl(PR_SET_SPECULATION_CTRL,…)`] -/// -/// [`prctl(PR_SET_SPECULATION_CTRL,…)`]: https://www.kernel.org/doc/html/v6.13/userspace-api/spec_ctrl.html -#[inline] -#[doc(alias = "PR_SET_SPECULATION_CTRL")] -pub fn control_speculative_feature( - feature: SpeculationFeature, - config: SpeculationFeatureControl, -) -> io::Result<()> { - let feature = feature as usize as *mut _; - let config = config.bits() as usize as *mut _; - unsafe { prctl_3args(PR_SET_SPECULATION_CTRL, feature, config) }.map(|_r| ()) -} - -// -// PR_GET_IO_FLUSHER/PR_SET_IO_FLUSHER -// - -const PR_GET_IO_FLUSHER: c_int = 58; - -/// Get the `IO_FLUSHER` state of the caller. -/// -/// # References -/// - [`prctl(PR_GET_IO_FLUSHER,…)`] -/// -/// [`prctl(PR_GET_IO_FLUSHER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_IO_FLUSHER")] -pub fn is_io_flusher() -> io::Result<bool> { - unsafe { prctl_1arg(PR_GET_IO_FLUSHER) }.map(|r| r != 0) -} - -const PR_SET_IO_FLUSHER: c_int = 57; - -/// Put the process in the `IO_FLUSHER` state, allowing it to make progress -/// when allocating memory. -/// -/// # References -/// - [`prctl(PR_SET_IO_FLUSHER,…)`] -/// -/// [`prctl(PR_SET_IO_FLUSHER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_IO_FLUSHER")] -pub fn configure_io_flusher_behavior(enable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_IO_FLUSHER, usize::from(enable) as *mut _) }.map(|_r| ()) -} - -// -// PR_PAC_GET_ENABLED_KEYS/PR_PAC_SET_ENABLED_KEYS -// - -const PR_PAC_GET_ENABLED_KEYS: c_int = 61; - -/// Get enabled pointer authentication keys. -/// -/// # References -/// - [`prctl(PR_PAC_GET_ENABLED_KEYS,…)`] -/// -/// [`prctl(PR_PAC_GET_ENABLED_KEYS,…)`]: https://www.kernel.org/doc/html/v6.13/arch/arm64/pointer-authentication.html -#[inline] -#[doc(alias = "PR_PAC_GET_ENABLED_KEYS")] -pub fn enabled_pointer_authentication_keys() -> io::Result<PointerAuthenticationKeys> { - let r = unsafe { prctl_1arg(PR_PAC_GET_ENABLED_KEYS)? } as c_uint; - PointerAuthenticationKeys::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_PAC_SET_ENABLED_KEYS: c_int = 60; - -/// Set enabled pointer authentication keys. -/// -/// # References -/// - [`prctl(PR_PAC_SET_ENABLED_KEYS,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_PAC_SET_ENABLED_KEYS,…)`]: https://www.kernel.org/doc/html/v6.13/arch/arm64/pointer-authentication.html -#[inline] -#[doc(alias = "PR_PAC_SET_ENABLED_KEYS")] -pub unsafe fn configure_pointer_authentication_keys< - Config: Iterator<Item = (PointerAuthenticationKeys, bool)>, ->( - config: Config, -) -> io::Result<()> { - let mut affected_keys: u32 = 0; - let mut enabled_keys: u32 = 0; - - for (key, enable) in config { - let key = key.bits(); - affected_keys |= key; - - if enable { - enabled_keys |= key; - } else { - enabled_keys &= !key; - } - } - - if affected_keys == 0 { - return Ok(()); // Nothing to do. - } - - prctl_3args( - PR_PAC_SET_ENABLED_KEYS, - affected_keys as usize as *mut _, - enabled_keys as usize as *mut _, - ) - .map(|_r| ()) -} - -// -// PR_SET_VMA -// - -const PR_SET_VMA: c_int = 0x53_56_4d_41; - -const PR_SET_VMA_ANON_NAME: usize = 0; - -/// Set the name for a virtual memory region. -/// -/// # References -/// - [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,…)`] -/// -/// [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,…)`]: https://lwn.net/Articles/867818/ -#[inline] -#[doc(alias = "PR_SET_VMA")] -#[doc(alias = "PR_SET_VMA_ANON_NAME")] -pub fn set_virtual_memory_region_name(region: &[u8], name: Option<&CStr>) -> io::Result<()> { - unsafe { - syscalls::prctl( - PR_SET_VMA, - PR_SET_VMA_ANON_NAME as *mut _, - region.as_ptr() as *mut _, - region.len() as *mut _, - name.map_or_else(null, CStr::as_ptr) as *mut _, - ) - .map(|_r| ()) - } -} diff --git a/vendor/rustix/src/process/priority.rs b/vendor/rustix/src/process/priority.rs deleted file mode 100644 index 0051b068..00000000 --- a/vendor/rustix/src/process/priority.rs +++ /dev/null @@ -1,132 +0,0 @@ -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -use crate::process::{Pid, Uid}; -use crate::{backend, io}; - -/// `nice(inc)`—Adjust the scheduling priority of the current process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/nice.html -/// [Linux]: https://man7.org/linux/man-pages/man2/nice.2.html -#[inline] -pub fn nice(inc: i32) -> io::Result<i32> { - backend::process::syscalls::nice(inc) -} - -/// `getpriority(PRIO_USER, uid)`—Get the scheduling priority of the given -/// user. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "getpriority")] -pub fn getpriority_user(uid: Uid) -> io::Result<i32> { - backend::process::syscalls::getpriority_user(uid) -} - -/// `getpriority(PRIO_PGRP, gid)`—Get the scheduling priority of the given -/// process group. -/// -/// A `pgid` of `None` means the process group of the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "getpriority")] -pub fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { - backend::process::syscalls::getpriority_pgrp(pgid) -} - -/// `getpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given -/// process. -/// -/// A `pid` of `None` means the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "getpriority")] -pub fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { - backend::process::syscalls::getpriority_process(pid) -} - -/// `setpriority(PRIO_USER, uid)`—Get the scheduling priority of the given -/// user. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "setpriority")] -pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - backend::process::syscalls::setpriority_user(uid, priority) -} - -/// `setpriority(PRIO_PGRP, pgid)`—Get the scheduling priority of the given -/// process group. -/// -/// A `pgid` of `None` means the process group of the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "setpriority")] -pub fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { - backend::process::syscalls::setpriority_pgrp(pgid, priority) -} - -/// `setpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given -/// process. -/// -/// A `pid` of `None` means the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "setpriority")] -pub fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { - backend::process::syscalls::setpriority_process(pid, priority) -} diff --git a/vendor/rustix/src/process/procctl.rs b/vendor/rustix/src/process/procctl.rs deleted file mode 100644 index 24d55302..00000000 --- a/vendor/rustix/src/process/procctl.rs +++ /dev/null @@ -1,547 +0,0 @@ -//! Bindings for the FreeBSD `procctl` system call. -//! -//! There are similarities (but also differences) with Linux's `prctl` system -//! call, whose interface is located in the `prctl.rs` file. - -#![allow(unsafe_code)] - -#[cfg(feature = "alloc")] -use alloc::{vec, vec::Vec}; -use core::mem::MaybeUninit; -use core::num::NonZeroI32; -use core::ptr; - -use bitflags::bitflags; - -use crate::backend::process::syscalls; -use crate::backend::process::types::RawId; -use crate::ffi::{c_int, c_uint, c_void}; -use crate::io; -use crate::process::{Pid, RawPid}; -use crate::signal::Signal; -use crate::utils::{as_mut_ptr, as_ptr}; - -// -// Helper functions. -// - -/// Subset of `idtype_t` C enum, with only the values allowed by `procctl`. -#[repr(i32)] -pub enum IdType { - /// Process id. - Pid = 0, - /// Process group id. - Pgid = 2, -} - -/// A process selector for use with the `procctl` interface. -/// -/// `None` represents the current process. `Some((IdType::Pid, pid))` -/// represents the process with pid `pid`. `Some((IdType::Pgid, pgid))` -/// represents the control processes belonging to the process group with id -/// `pgid`. -pub type ProcSelector = Option<(IdType, Pid)>; -fn proc_selector_to_raw(selector: ProcSelector) -> (IdType, RawPid) { - match selector { - Some((idtype, id)) => (idtype, id.as_raw_nonzero().get()), - None => (IdType::Pid, 0), - } -} - -#[inline] -pub(crate) unsafe fn procctl( - option: c_int, - process: ProcSelector, - data: *mut c_void, -) -> io::Result<()> { - let (idtype, id) = proc_selector_to_raw(process); - syscalls::procctl(idtype as c_uint, id as RawId, option, data) -} - -#[inline] -pub(crate) unsafe fn procctl_set<P>( - option: c_int, - process: ProcSelector, - data: &P, -) -> io::Result<()> { - procctl(option, process, (as_ptr(data) as *mut P).cast()) -} - -#[inline] -pub(crate) unsafe fn procctl_get_optional<P>( - option: c_int, - process: ProcSelector, -) -> io::Result<P> { - let mut value: MaybeUninit<P> = MaybeUninit::uninit(); - procctl(option, process, value.as_mut_ptr().cast())?; - Ok(value.assume_init()) -} - -// -// PROC_PDEATHSIG_STATUS/PROC_PDEATHSIG_CTL -// - -const PROC_PDEATHSIG_STATUS: c_int = 12; - -/// Get the current value of the parent process death signal. -/// -/// # References -/// - [Linux: `prctl(PR_GET_PDEATHSIG,…)`] -/// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,…)`] -/// -/// [Linux: `prctl(PR_GET_PDEATHSIG,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn parent_process_death_signal() -> io::Result<Option<Signal>> { - let raw = unsafe { procctl_get_optional::<c_int>(PROC_PDEATHSIG_STATUS, None) }?; - if let Some(non_zero) = NonZeroI32::new(raw) { - // SAFETY: The only way to get a libc-reserved signal number in - // here would be to do something equivalent to - // `set_parent_process_death_signal`, but that would have required - // using a `Signal` with a libc-reserved value. - Ok(Some(unsafe { - Signal::from_raw_nonzero_unchecked(non_zero) - })) - } else { - Ok(None) - } -} - -const PROC_PDEATHSIG_CTL: c_int = 11; - -/// Set the parent-death signal of the calling process. -/// -/// # References -/// - [Linux: `prctl(PR_SET_PDEATHSIG,…)`] -/// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,…)`] -/// -/// [Linux: `prctl(PR_SET_PDEATHSIG,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn set_parent_process_death_signal(signal: Option<Signal>) -> io::Result<()> { - let signal = signal.map_or(0, |signal| signal.as_raw()); - unsafe { procctl_set::<c_int>(PROC_PDEATHSIG_CTL, None, &signal) } -} - -// -// PROC_TRACE_CTL -// - -const PROC_TRACE_CTL: c_int = 7; - -const PROC_TRACE_CTL_ENABLE: i32 = 1; -const PROC_TRACE_CTL_DISABLE: i32 = 2; -const PROC_TRACE_CTL_DISABLE_EXEC: i32 = 3; - -/// `PROC_TRACE_CTL_*` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum DumpableBehavior { - /// Not dumpable. - NotDumpable = PROC_TRACE_CTL_DISABLE, - /// Dumpable. - Dumpable = PROC_TRACE_CTL_ENABLE, - /// Not dumpable, and this behaviour is preserved across `execve` calls. - NotDumpableExecPreserved = PROC_TRACE_CTL_DISABLE_EXEC, -} - -/// Set the state of the `dumpable` attribute for the process indicated by -/// `idtype` and `id`. -/// -/// This determines whether the process can be traced and whether core dumps -/// are produced for the process upon delivery of a signal whose default -/// behavior is to produce a core dump. -/// -/// This is similar to `set_dumpable_behavior` on Linux, with the exception -/// that on FreeBSD there is an extra argument `process`. When `process` is set -/// to `None`, the operation is performed for the current process, like on -/// Linux. -/// -/// # References -/// - [FreeBSD `procctl(PROC_TRACE_CTL,…)`] -/// -/// [FreeBSD `procctl(PROC_TRACE_CTL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn set_dumpable_behavior(process: ProcSelector, config: DumpableBehavior) -> io::Result<()> { - unsafe { procctl(PROC_TRACE_CTL, process, config as usize as *mut _) } -} - -// -// PROC_TRACE_STATUS -// - -const PROC_TRACE_STATUS: c_int = 8; - -/// Tracing status as returned by [`trace_status`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum TracingStatus { - /// Tracing is disabled for the process. - NotTraceble, - /// Tracing is not disabled for the process, but not debugger/tracer is - /// attached. - Tracable, - /// The process is being traced by the process whose pid is stored in the - /// first component of this variant. - BeingTraced(Pid), -} - -/// Get the tracing status of the process indicated by `idtype` and `id`. -/// -/// # References -/// - [FreeBSD `procctl(PROC_TRACE_STATUS,…)`] -/// -/// [FreeBSD `procctl(PROC_TRACE_STATUS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn trace_status(process: ProcSelector) -> io::Result<TracingStatus> { - let val = unsafe { procctl_get_optional::<c_int>(PROC_TRACE_STATUS, process) }?; - match val { - -1 => Ok(TracingStatus::NotTraceble), - 0 => Ok(TracingStatus::Tracable), - pid => { - let pid = Pid::from_raw(pid as RawPid).ok_or(io::Errno::RANGE)?; - Ok(TracingStatus::BeingTraced(pid)) - } - } -} - -// -// PROC_REAP_* -// - -const PROC_REAP_ACQUIRE: c_int = 2; -const PROC_REAP_RELEASE: c_int = 3; - -/// Acquire or release the reaper status of the calling process. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_ACQUIRE/RELEASE,…)`] -/// -/// [FreeBSD: `procctl(PROC_REAP_ACQUIRE/RELEASE,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn set_reaper_status(reaper: bool) -> io::Result<()> { - unsafe { - procctl( - if reaper { - PROC_REAP_ACQUIRE - } else { - PROC_REAP_RELEASE - }, - None, - ptr::null_mut(), - ) - } -} - -const PROC_REAP_STATUS: c_int = 4; - -bitflags! { - /// `REAPER_STATUS_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReaperStatusFlags: c_uint { - /// The process has acquired reaper status. - const OWNED = 1; - /// The process is the root of the reaper tree ([`Pid::INIT`]). - const REALINIT = 2; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[repr(C)] -struct procctl_reaper_status { - rs_flags: c_uint, - rs_children: c_uint, - rs_descendants: c_uint, - rs_reaper: RawPid, - rs_pid: RawPid, - rs_pad0: [c_uint; 15], -} - -/// Reaper status as returned by [`get_reaper_status`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct ReaperStatus { - /// The flags. - pub flags: ReaperStatusFlags, - /// The number of children of the reaper among the descendants. - pub children: usize, - /// The total number of descendants of the reaper(s), not counting - /// descendants of the reaper in the subtree. - pub descendants: usize, - /// The pid of the reaper for the specified process id. - pub reaper: Pid, - /// The pid of one reaper child if there are any descendants. - pub pid: Option<Pid>, -} - -/// Get information about the reaper of the specified process (or the process -/// itself if it is a reaper). -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_STATUS,…)`] -/// -/// [FreeBSD: `procctl(PROC_REAP_STATUS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn get_reaper_status(process: ProcSelector) -> io::Result<ReaperStatus> { - let raw = unsafe { procctl_get_optional::<procctl_reaper_status>(PROC_REAP_STATUS, process) }?; - Ok(ReaperStatus { - flags: ReaperStatusFlags::from_bits_retain(raw.rs_flags), - children: raw.rs_children as _, - descendants: raw.rs_descendants as _, - reaper: Pid::from_raw(raw.rs_reaper).ok_or(io::Errno::RANGE)?, - pid: if raw.rs_pid == -1 { - None - } else { - Some(Pid::from_raw(raw.rs_pid).ok_or(io::Errno::RANGE)?) - }, - }) -} - -#[cfg(feature = "alloc")] -const PROC_REAP_GETPIDS: c_int = 5; - -bitflags! { - /// `REAPER_PIDINFO_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PidInfoFlags: c_uint { - /// This structure was filled by the kernel. - const VALID = 1; - /// The pid field identifies a direct child of the reaper. - const CHILD = 2; - /// The reported process is itself a reaper. Descendants of a - /// subordinate reaper are not reported. - const REAPER = 4; - /// The reported process is in the zombie state. - const ZOMBIE = 8; - /// The reported process is stopped by - /// [`Signal::Stop`]/[`Signal::Tstp`]. - const STOPPED = 16; - /// The reported process is in the process of exiting. - const EXITING = 32; - } -} - -#[repr(C)] -#[derive(Default, Clone)] -struct procctl_reaper_pidinfo { - pi_pid: RawPid, - pi_subtree: RawPid, - pi_flags: c_uint, - pi_pad0: [c_uint; 15], -} - -#[repr(C)] -struct procctl_reaper_pids { - rp_count: c_uint, - rp_pad0: [c_uint; 15], - rp_pids: *mut procctl_reaper_pidinfo, -} - -/// A child process of a reaper. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct PidInfo { - /// The flags of the process. - pub flags: PidInfoFlags, - /// The pid of the process. - pub pid: Pid, - /// The pid of the child of the reaper which is the (grand-…)parent of the - /// process. - pub subtree: Pid, -} - -/// Get the list of descendants of the specified reaper process. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_GETPIDS,…)`] -/// -/// [FreeBSD: `procctl(PROC_REAP_GETPIDS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn get_reaper_pids(process: ProcSelector) -> io::Result<Vec<PidInfo>> { - // Sadly no better way to guarantee that we get all the results than to - // allocate ≈8MB of memory… - const PID_MAX: usize = 99999; - let mut pids: Vec<procctl_reaper_pidinfo> = vec![Default::default(); PID_MAX]; - let mut pinfo = procctl_reaper_pids { - rp_count: PID_MAX as _, - rp_pad0: [0; 15], - rp_pids: pids.as_mut_slice().as_mut_ptr(), - }; - unsafe { procctl(PROC_REAP_GETPIDS, process, as_mut_ptr(&mut pinfo).cast())? }; - let mut result = Vec::new(); - for raw in pids.into_iter() { - let flags = PidInfoFlags::from_bits_retain(raw.pi_flags); - if !flags.contains(PidInfoFlags::VALID) { - break; - } - result.push(PidInfo { - flags, - subtree: Pid::from_raw(raw.pi_subtree).ok_or(io::Errno::RANGE)?, - pid: Pid::from_raw(raw.pi_pid).ok_or(io::Errno::RANGE)?, - }); - } - Ok(result) -} - -const PROC_REAP_KILL: c_int = 6; - -bitflags! { - /// `REAPER_KILL_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - struct KillFlags: c_uint { - const CHILDREN = 1; - const SUBTREE = 2; - } -} - -#[repr(C)] -struct procctl_reaper_kill { - rk_sig: c_int, - rk_flags: c_uint, - rk_subtree: RawPid, - rk_killed: c_uint, - rk_fpid: RawPid, - rk_pad0: [c_uint; 15], -} - -/// Reaper status as returned by [`get_reaper_status`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct KillResult { - /// The number of processes that were signalled. - pub killed: usize, - /// The pid of the first process that wasn't successfully signalled. - pub first_failed: Option<Pid>, -} - -/// Deliver a signal to some subset of the descendants of the reaper. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_KILL,…)`] -/// -/// [FreeBSD: `procctl(PROC_REAP_KILL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -pub fn reaper_kill( - process: ProcSelector, - signal: Signal, - direct_children: bool, - subtree: Option<Pid>, -) -> io::Result<KillResult> { - let mut flags = KillFlags::empty(); - flags.set(KillFlags::CHILDREN, direct_children); - flags.set(KillFlags::SUBTREE, subtree.is_some()); - let mut req = procctl_reaper_kill { - rk_sig: signal.as_raw(), - rk_flags: flags.bits(), - rk_subtree: subtree.map(|p| p.as_raw_nonzero().into()).unwrap_or(0), - rk_killed: 0, - rk_fpid: 0, - rk_pad0: [0; 15], - }; - unsafe { procctl(PROC_REAP_KILL, process, as_mut_ptr(&mut req).cast())? }; - Ok(KillResult { - killed: req.rk_killed as _, - first_failed: Pid::from_raw(req.rk_fpid), - }) -} - -// -// PROC_TRAPCAP_STATUS/PROC_TRAPCAP_CTL -// - -const PROC_TRAPCAP_CTL: c_int = 9; - -const PROC_TRAPCAP_CTL_ENABLE: i32 = 1; -const PROC_TRAPCAP_CTL_DISABLE: i32 = 2; - -/// `PROC_TRAPCAP_CTL_*` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum TrapCapBehavior { - /// Disable the [`Signal::Trap`] signal delivery on capability mode access - /// violations. - Disable = PROC_TRAPCAP_CTL_DISABLE, - /// Enable the [`Signal::Trap`] signal delivery on capability mode access - /// violations. - Enable = PROC_TRAPCAP_CTL_ENABLE, -} - -/// Set the current value of the capability mode violation trapping behavior. -/// -/// If this behavior is enabled, the kernel would deliver a [`Signal::Trap`] -/// signal on any return from a system call that would result in a -/// [`io::Errno::NOTCAPABLE`] or [`io::Errno::CAPMODE`] error. -/// -/// This behavior is inherited by the children of the process and is kept -/// across `execve` calls. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_TRAPCAP_CTL,…)`] -/// -/// [FreeBSD: `procctl(PROC_TRAPCAP_CTL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn set_trap_cap_behavior(process: ProcSelector, config: TrapCapBehavior) -> io::Result<()> { - let config = config as c_int; - unsafe { procctl_set::<c_int>(PROC_TRAPCAP_CTL, process, &config) } -} - -const PROC_TRAPCAP_STATUS: c_int = 10; - -/// Get the current value of the capability mode violation trapping behavior. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_TRAPCAP_STATUS,…)`] -/// -/// [FreeBSD: `procctl(PROC_TRAPCAP_STATUS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn trap_cap_behavior(process: ProcSelector) -> io::Result<TrapCapBehavior> { - let val = unsafe { procctl_get_optional::<c_int>(PROC_TRAPCAP_STATUS, process) }?; - match val { - PROC_TRAPCAP_CTL_DISABLE => Ok(TrapCapBehavior::Disable), - PROC_TRAPCAP_CTL_ENABLE => Ok(TrapCapBehavior::Enable), - _ => Err(io::Errno::RANGE), - } -} - -// -// PROC_NO_NEW_PRIVS_STATUS/PROC_NO_NEW_PRIVS_CTL -// - -const PROC_NO_NEW_PRIVS_CTL: c_int = 19; - -const PROC_NO_NEW_PRIVS_ENABLE: c_int = 1; - -/// Enable the `no_new_privs` mode that ignores SUID and SGID bits on `execve` -/// in the specified process and its future descendants. -/// -/// This is similar to `set_no_new_privs` on Linux, with the exception that on -/// FreeBSD there is no argument `no_new_privs` argument as it's only possible -/// to enable this mode and there's no going back. -/// -/// # References -/// - [Linux: `prctl(PR_SET_NO_NEW_PRIVS,…)`] -/// - [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_CTL,…)`] -/// -/// [Linux: `prctl(PR_SET_NO_NEW_PRIVS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_CTL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn set_no_new_privs(process: ProcSelector) -> io::Result<()> { - unsafe { procctl_set::<c_int>(PROC_NO_NEW_PRIVS_CTL, process, &PROC_NO_NEW_PRIVS_ENABLE) } -} - -const PROC_NO_NEW_PRIVS_STATUS: c_int = 20; - -/// Check the `no_new_privs` mode of the specified process. -/// -/// # References -/// - [Linux: `prctl(PR_GET_NO_NEW_PRIVS,…)`] -/// - [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_STATUS,…)`] -/// -/// [Linux: `prctl(PR_GET_NO_NEW_PRIVS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_STATUS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn no_new_privs(process: ProcSelector) -> io::Result<bool> { - unsafe { procctl_get_optional::<c_int>(PROC_NO_NEW_PRIVS_STATUS, process) } - .map(|x| x == PROC_NO_NEW_PRIVS_ENABLE) -} diff --git a/vendor/rustix/src/process/rlimit.rs b/vendor/rustix/src/process/rlimit.rs deleted file mode 100644 index 124ca51a..00000000 --- a/vendor/rustix/src/process/rlimit.rs +++ /dev/null @@ -1,53 +0,0 @@ -#[cfg(linux_kernel)] -use crate::process::Pid; -use crate::{backend, io}; - -pub use backend::process::types::Resource; - -/// `struct rlimit`—Current and maximum values used in [`getrlimit`], -/// [`setrlimit`], and [`prlimit`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Rlimit { - /// Current effective, “soft”, limit. - pub current: Option<u64>, - /// Maximum, “hard”, value that `current` may be dynamically increased to. - pub maximum: Option<u64>, -} - -/// `getrlimit(resource)`—Get a process resource limit value. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrlimit.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getrlimit.2.html -#[inline] -pub fn getrlimit(resource: Resource) -> Rlimit { - backend::process::syscalls::getrlimit(resource) -} - -/// `setrlimit(resource, new)`—Set a process resource limit value. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setrlimit.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setrlimit.2.html -#[inline] -pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { - backend::process::syscalls::setrlimit(resource, new) -} - -/// `prlimit(pid, resource, new)`—Get and set a process resource limit value. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/prlimit.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn prlimit(pid: Option<Pid>, resource: Resource, new: Rlimit) -> io::Result<Rlimit> { - backend::process::syscalls::prlimit(pid, resource, new) -} diff --git a/vendor/rustix/src/process/types.rs b/vendor/rustix/src/process/types.rs deleted file mode 100644 index 0adb47ec..00000000 --- a/vendor/rustix/src/process/types.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! Types for use with [`rustix::process`] functions. -//! -//! [`rustix::process`]: crate::process - -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::pid::Pid; -use core::mem::transmute; - -/// File lock data structure used in [`fcntl_getlk`]. -/// -/// [`fcntl_getlk`]: crate::process::fcntl_getlk() -#[cfg(not(target_os = "horizon"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct Flock { - /// Starting offset for lock - pub start: u64, - /// Number of bytes to lock - pub length: u64, - /// PID of process blocking our lock. If set to `None`, it refers to the - /// current process - pub pid: Option<Pid>, - /// Type of lock - pub typ: FlockType, - /// Offset type of lock - pub offset_type: FlockOffsetType, -} - -#[cfg(not(target_os = "horizon"))] -impl Flock { - pub(crate) const unsafe fn from_raw_unchecked(raw_fl: c::flock) -> Self { - Self { - start: raw_fl.l_start as _, - length: raw_fl.l_len as _, - pid: Pid::from_raw(raw_fl.l_pid), - typ: transmute::<i16, FlockType>(raw_fl.l_type), - offset_type: transmute::<i16, FlockOffsetType>(raw_fl.l_whence), - } - } - - pub(crate) fn as_raw(&self) -> c::flock { - let mut f: c::flock = unsafe { core::mem::zeroed() }; - f.l_start = self.start as _; - f.l_len = self.length as _; - f.l_pid = Pid::as_raw(self.pid); - f.l_type = self.typ as _; - f.l_whence = self.offset_type as _; - f - } -} - -#[cfg(not(target_os = "horizon"))] -impl From<FlockType> for Flock { - fn from(value: FlockType) -> Self { - Self { - start: 0, - length: 0, - pid: None, - typ: value, - offset_type: FlockOffsetType::Set, - } - } -} - -/// `F_*LCK` constants for use with [`fcntl_getlk`]. -/// -/// [`fcntl_getlk`]: crate::process::fcntl_getlk() -#[cfg(not(target_os = "horizon"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(i16)] -pub enum FlockType { - /// `F_RDLCK` - ReadLock = c::F_RDLCK as _, - /// `F_WRLCK` - WriteLock = c::F_WRLCK as _, - /// `F_UNLCK` - Unlocked = c::F_UNLCK as _, -} - -/// `F_SEEK*` constants for use with [`fcntl_getlk`]. -/// -/// [`fcntl_getlk`]: crate::process::fcntl_getlk() -#[cfg(not(target_os = "horizon"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(i16)] -pub enum FlockOffsetType { - /// `F_SEEK_SET` - Set = c::SEEK_SET as _, - /// `F_SEEK_CUR` - Current = c::SEEK_CUR as _, - /// `F_SEEK_END` - End = c::SEEK_END as _, -} diff --git a/vendor/rustix/src/process/umask.rs b/vendor/rustix/src/process/umask.rs deleted file mode 100644 index 16bd550a..00000000 --- a/vendor/rustix/src/process/umask.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Umask support. - -#[cfg(feature = "fs")] -use crate::backend; -#[cfg(feature = "fs")] -use crate::fs::Mode; - -/// `umask(mask)`—Set the process file creation mask. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/umask.html -/// [Linux]: https://man7.org/linux/man-pages/man2/umask.2.html -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[inline] -pub fn umask(mask: Mode) -> Mode { - backend::process::syscalls::umask(mask) -} diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs deleted file mode 100644 index 0e004f3d..00000000 --- a/vendor/rustix/src/process/wait.rs +++ /dev/null @@ -1,493 +0,0 @@ -//! Wait for processes to change state. -//! -//! # Safety -//! -//! This code needs to implement `Send` and `Sync` for `WaitIdStatus` because -//! the linux-raw-sys bindings generate a type that doesn't do so -//! automatically. -#![allow(unsafe_code)] -use crate::process::Pid; -use crate::{backend, io}; -use bitflags::bitflags; -use core::fmt; - -#[cfg(target_os = "linux")] -use crate::fd::BorrowedFd; - -#[cfg(linux_raw)] -use crate::backend::process::wait::SiginfoExt as _; - -bitflags! { - /// Options for modifying the behavior of [`wait`]/[`waitpid`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitOptions: u32 { - /// Return immediately if no child has exited. - const NOHANG = bitcast!(backend::process::wait::WNOHANG); - /// Return if a child has stopped (but not traced via [`ptrace`]). - /// - /// [`ptrace`]: https://man7.org/linux/man-pages/man2/ptrace.2.html - #[cfg(not(target_os = "horizon"))] - const UNTRACED = bitcast!(backend::process::wait::WUNTRACED); - /// Return if a stopped child has been resumed by delivery of - /// [`Signal::Cont`]. - /// - /// [`Signal::Cont`]: crate::process::Signal::Cont - #[cfg(not(target_os = "horizon"))] - const CONTINUED = bitcast!(backend::process::wait::WCONTINUED); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -bitflags! { - /// Options for modifying the behavior of [`waitid`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitIdOptions: u32 { - /// Return immediately if no child has exited. - const NOHANG = bitcast!(backend::process::wait::WNOHANG); - /// Return if a stopped child has been resumed by delivery of - /// [`Signal::Cont`]. - /// - /// [`Signal::Cont`]: crate::process::Signal::Cont - const CONTINUED = bitcast!(backend::process::wait::WCONTINUED); - /// Wait for processed that have exited. - #[cfg(not(target_os = "cygwin"))] - const EXITED = bitcast!(backend::process::wait::WEXITED); - /// Keep processed in a waitable state. - #[cfg(not(target_os = "cygwin"))] - const NOWAIT = bitcast!(backend::process::wait::WNOWAIT); - /// Wait for processes that have been stopped. - #[cfg(not(target_os = "cygwin"))] - const STOPPED = bitcast!(backend::process::wait::WSTOPPED); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// The status of a child process after calling [`wait`]/[`waitpid`]. -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct WaitStatus(i32); - -impl WaitStatus { - /// Creates a `WaitStatus` out of an integer. - #[inline] - pub(crate) fn new(status: i32) -> Self { - Self(status) - } - - /// Converts a `WaitStatus` into its raw representation as an integer. - #[inline] - pub const fn as_raw(self) -> i32 { - self.0 - } - - /// Returns whether the process is currently stopped. - #[inline] - #[doc(alias = "WIFSTOPPED")] - pub fn stopped(self) -> bool { - backend::process::wait::WIFSTOPPED(self.0) - } - - /// Returns whether the process has exited normally. - #[inline] - #[doc(alias = "WIFEXITED")] - pub fn exited(self) -> bool { - backend::process::wait::WIFEXITED(self.0) - } - - /// Returns whether the process was terminated by a signal. - #[inline] - #[doc(alias = "WIFSIGNALED")] - pub fn signaled(self) -> bool { - backend::process::wait::WIFSIGNALED(self.0) - } - - /// Returns whether the process has continued from a job control stop. - #[inline] - #[doc(alias = "WIFCONTINUED")] - pub fn continued(self) -> bool { - backend::process::wait::WIFCONTINUED(self.0) - } - - /// Returns the number of the signal that stopped the process, if the - /// process was stopped by a signal. - #[inline] - #[doc(alias = "WSTOPSIG")] - pub fn stopping_signal(self) -> Option<i32> { - if self.stopped() { - Some(backend::process::wait::WSTOPSIG(self.0)) - } else { - None - } - } - - /// Returns the exit status number returned by the process, if it exited - /// normally. - #[inline] - #[doc(alias = "WEXITSTATUS")] - pub fn exit_status(self) -> Option<i32> { - if self.exited() { - Some(backend::process::wait::WEXITSTATUS(self.0)) - } else { - None - } - } - - /// Returns the number of the signal that terminated the process, if the - /// process was terminated by a signal. - #[inline] - #[doc(alias = "WTERMSIG")] - pub fn terminating_signal(self) -> Option<i32> { - if self.signaled() { - Some(backend::process::wait::WTERMSIG(self.0)) - } else { - None - } - } -} - -impl fmt::Debug for WaitStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("WaitStatus"); - s.field("stopped", &self.stopped()); - s.field("exited", &self.exited()); - s.field("signaled", &self.signaled()); - s.field("continued", &self.continued()); - if let Some(stopping_signal) = self.stopping_signal() { - s.field("stopping_signal", &stopping_signal); - } - if let Some(exit_status) = self.exit_status() { - s.field("exit_status", &exit_status); - } - if let Some(terminating_signal) = self.terminating_signal() { - s.field("terminating_signal", &terminating_signal); - } - s.finish() - } -} - -/// The status of a process after calling [`waitid`]. -#[derive(Clone, Copy)] -#[repr(transparent)] -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -pub struct WaitIdStatus(pub(crate) backend::c::siginfo_t); - -#[cfg(linux_raw)] -// SAFETY: `siginfo_t` does contain some raw pointers, such as the `si_ptr` -// and the `si_addr` fields, however it's up to users to use those correctly. -unsafe impl Send for WaitIdStatus {} - -#[cfg(linux_raw)] -// SAFETY: Same as with `Send`. -unsafe impl Sync for WaitIdStatus {} - -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -impl WaitIdStatus { - /// Returns whether the process is currently stopped. - #[inline] - pub fn stopped(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_STOPPED) - } - - /// Returns whether the process is currently trapped. - #[inline] - pub fn trapped(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_TRAPPED) - } - - /// Returns whether the process has exited normally. - #[inline] - pub fn exited(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_EXITED) - } - - /// Returns whether the process was terminated by a signal and did not - /// create a core file. - #[inline] - pub fn killed(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_KILLED) - } - - /// Returns whether the process was terminated by a signal and did create a - /// core file. - #[inline] - pub fn dumped(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_DUMPED) - } - - /// Returns whether the process has continued from a job control stop. - #[inline] - pub fn continued(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_CONTINUED) - } - - /// Returns the number of the signal that stopped the process, if the - /// process was stopped by a signal. - #[inline] - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn stopping_signal(&self) -> Option<i32> { - if self.stopped() { - Some(self.si_status()) - } else { - None - } - } - - /// Returns the number of the signal that trapped the process, if the - /// process was trapped by a signal. - #[inline] - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn trapping_signal(&self) -> Option<i32> { - if self.trapped() { - Some(self.si_status()) - } else { - None - } - } - - /// Returns the exit status number returned by the process, if it exited - /// normally. - #[inline] - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn exit_status(&self) -> Option<i32> { - if self.exited() { - Some(self.si_status()) - } else { - None - } - } - - /// Returns the number of the signal that terminated the process, if the - /// process was terminated by a signal. - #[inline] - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn terminating_signal(&self) -> Option<i32> { - if self.killed() || self.dumped() { - Some(self.si_status()) - } else { - None - } - } - - /// Return the raw `si_signo` value returned from `waitid`. - #[cfg(linux_raw)] - pub fn raw_signo(&self) -> crate::ffi::c_int { - self.0.si_signo() - } - - /// Return the raw `si_signo` value returned from `waitid`. - #[cfg(not(linux_raw))] - pub fn raw_signo(&self) -> crate::ffi::c_int { - self.0.si_signo - } - - /// Return the raw `si_errno` value returned from `waitid`. - #[cfg(linux_raw)] - pub fn raw_errno(&self) -> crate::ffi::c_int { - self.0.si_errno() - } - - /// Return the raw `si_errno` value returned from `waitid`. - #[cfg(not(linux_raw))] - pub fn raw_errno(&self) -> crate::ffi::c_int { - self.0.si_errno - } - - /// Return the raw `si_code` value returned from `waitid`. - #[cfg(linux_raw)] - pub fn raw_code(&self) -> crate::ffi::c_int { - self.0.si_code() - } - - /// Return the raw `si_code` value returned from `waitid`. - #[cfg(not(linux_raw))] - pub fn raw_code(&self) -> crate::ffi::c_int { - self.0.si_code - } - - // This is disabled on NetBSD because the libc crate's `si_status()` - // implementation doesn't appear to match what's in NetBSD's headers and we - // don't get a meaningful value returned. - // TODO: Report this upstream. - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - #[allow(unsafe_code)] - fn si_status(&self) -> crate::ffi::c_int { - // SAFETY: POSIX [specifies] that the `siginfo_t` returned by a - // `waitid` call always has a valid `si_status` value. - // - // [specifies]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/signal.h.html - unsafe { self.0.si_status() } - } -} - -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -impl fmt::Debug for WaitIdStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("WaitIdStatus"); - s.field("stopped", &self.stopped()); - s.field("exited", &self.exited()); - s.field("killed", &self.killed()); - s.field("trapped", &self.trapped()); - s.field("dumped", &self.dumped()); - s.field("continued", &self.continued()); - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(stopping_signal) = self.stopping_signal() { - s.field("stopping_signal", &stopping_signal); - } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(trapping_signal) = self.trapping_signal() { - s.field("trapping_signal", &trapping_signal); - } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(exit_status) = self.exit_status() { - s.field("exit_status", &exit_status); - } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(terminating_signal) = self.terminating_signal() { - s.field("terminating_signal", &terminating_signal); - } - s.finish() - } -} - -/// The identifier to wait on in a call to [`waitid`]. -#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "wasi")))] -#[derive(Debug, Clone)] -#[non_exhaustive] -pub enum WaitId<'a> { - /// Wait on all processes. - #[doc(alias = "P_ALL")] - All, - - /// Wait for a specific process ID. - #[doc(alias = "P_PID")] - Pid(Pid), - - /// Wait for a specific process group ID, or the calling process' group ID. - #[doc(alias = "P_PGID")] - Pgid(Option<Pid>), - - /// Wait for a specific process file descriptor. - #[cfg(target_os = "linux")] - #[doc(alias = "P_PIDFD")] - PidFd(BorrowedFd<'a>), - - /// Eat the lifetime for non-Linux platforms. - #[doc(hidden)] - #[cfg(not(target_os = "linux"))] - __EatLifetime(core::marker::PhantomData<&'a ()>), -} - -/// `waitpid(pid, waitopts)`—Wait for a specific process to change state. -/// -/// If the pid is `None`, the call will wait for any child process whose -/// process group id matches that of the calling process. Otherwise, the call -/// will wait for the child process with the given pid. -/// -/// On Success, returns the status of the selected process. -/// -/// If `NOHANG` was specified in the options, and the selected child process -/// didn't change state, returns `None`. -/// -/// To wait for a given process group (the `< -1` case of `waitpid`), use -/// [`waitpgid`] or [`waitid`]. To wait for any process (the `-1` case of -/// `waitpid`), use [`wait`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html -/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html -#[doc(alias = "wait4")] -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn waitpid(pid: Option<Pid>, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - backend::process::syscalls::waitpid(pid, waitopts) -} - -/// `waitpid(-pgid, waitopts)`—Wait for a process in a specific process group -/// to change state. -/// -/// The call will wait for any child process with the given pgid. -/// -/// On Success, returns the status of the selected process. -/// -/// If `NOHANG` was specified in the options, and no selected child process -/// changed state, returns `None`. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html -/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - backend::process::syscalls::waitpgid(pgid, waitopts) -} - -/// `wait(waitopts)`—Wait for any of the children of calling process to -/// change state. -/// -/// On success, returns the pid of the child process whose state changed, and -/// the status of said process. -/// -/// If `NOHANG` was specified in the options, and the selected child process -/// didn't change state, returns `None`. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html -/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - backend::process::syscalls::wait(waitopts) -} - -/// `waitid(_, _, _, opts)`—Wait for the specified child process to change -/// state. -#[cfg(not(any( - target_os = "cygwin", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[inline] -pub fn waitid<'a, Id: Into<WaitId<'a>>>( - id: Id, - options: WaitIdOptions, -) -> io::Result<Option<WaitIdStatus>> { - backend::process::syscalls::waitid(id.into(), options) -} diff --git a/vendor/rustix/src/pty.rs b/vendor/rustix/src/pty.rs deleted file mode 100644 index 560dfc13..00000000 --- a/vendor/rustix/src/pty.rs +++ /dev/null @@ -1,223 +0,0 @@ -//! Pseudoterminal operations. -//! -//! For the `openpty` and `login_tty` functions, see the -//! [rustix-openpty crate]. -//! -//! [rustix-openpty crate]: https://crates.io/crates/rustix-openpty - -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::fd::{AsFd, OwnedFd}; -use crate::fs::OFlags; -use crate::{backend, io}; -#[cfg(all( - feature = "alloc", - any( - apple, - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" - ) -))] -use {crate::ffi::CString, alloc::vec::Vec}; - -#[cfg(target_os = "linux")] -use crate::{fd::FromRawFd as _, ioctl}; - -bitflags::bitflags! { - /// `O_*` flags for use with [`openpt`] and [`ioctl_tiocgptpeer`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct OpenptFlags: u32 { - /// `O_RDWR` - const RDWR = c::O_RDWR as c::c_uint; - - /// `O_NOCTTY` - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "l4re", target_os = "redox", target_os = "vita")))] - const NOCTTY = c::O_NOCTTY as c::c_uint; - - /// `O_CLOEXEC` - /// - /// The standard `posix_openpt` function doesn't support `CLOEXEC`, but - /// rustix supports it on Linux, and FreeBSD and NetBSD support it. - #[cfg(any(linux_kernel, target_os = "freebsd", target_os = "netbsd"))] - const CLOEXEC = c::O_CLOEXEC as c::c_uint; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -impl From<OpenptFlags> for OFlags { - #[inline] - fn from(flags: OpenptFlags) -> Self { - // `OpenptFlags` is a subset of `OFlags`. - Self::from_bits_retain(flags.bits() as _) - } -} - -/// `posix_openpt(flags)`—Open a pseudoterminal device. -/// -/// On Linux, an additional `CLOEXEC` flag value may be passed to request the -/// close-on-exec flag be set. -/// -/// On Linux, if the system has no free pseudoterminals available, the -/// underlying system call fails with [`io::Errno::NOSPC`], however this rustix -/// function translates that to [`io::Errno::AGAIN`], so that the linux_raw and -/// libc backends have the same behavior. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [FreeBSD] -/// - [DragonFly BSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_openpt.html -/// [Linux]: https://man7.org/linux/man-pages/man3/posix_openpt.3.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/posix_openpt.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=posix_openpt&sektion=2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=posix_openpt§ion=3 -/// [NetBSD]: https://man.netbsd.org/posix_openpt.3 -/// [OpenBSD]: https://man.openbsd.org/posix_openpt -/// [illumos]: https://illumos.org/man/3C/posix_openpt -#[inline] -#[doc(alias = "posix_openpt")] -pub fn openpt(flags: OpenptFlags) -> io::Result<OwnedFd> { - // On Linux, open the device ourselves so that we can support `CLOEXEC`. - #[cfg(linux_kernel)] - { - use crate::fs::{open, Mode}; - match open(cstr!("/dev/ptmx"), flags.into(), Mode::empty()) { - // Match libc `openat` behavior with `ENOSPC`. - Err(io::Errno::NOSPC) => Err(io::Errno::AGAIN), - otherwise => otherwise, - } - } - - // On all other platforms, use `openpt`. - #[cfg(not(linux_kernel))] - { - backend::pty::syscalls::openpt(flags) - } -} - -/// `ptsname(fd)`—Return the name of a pseudoterminal. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/ptsname.html -/// [Linux]: https://man7.org/linux/man-pages/man3/ptsname.3.html -/// [illumos]: https://www.illumos.org/man/3C/ptsname -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Allocation.html#index-ptsname -#[cfg(all( - feature = "alloc", - any( - apple, - linux_like, - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos" - ) -))] -#[inline] -#[doc(alias = "ptsname_r")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn ptsname<Fd: AsFd, B: Into<Vec<u8>>>(fd: Fd, reuse: B) -> io::Result<CString> { - backend::pty::syscalls::ptsname(fd.as_fd(), reuse.into()) -} - -/// `unlockpt(fd)`—Unlock a pseudoterminal. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlockpt.html -/// [Linux]: https://man7.org/linux/man-pages/man3/unlockpt.3.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Allocation.html#index-unlockpt -#[inline] -pub fn unlockpt<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::pty::syscalls::unlockpt(fd.as_fd()) -} - -/// `grantpt(fd)`—Grant access to the user side of a pseudoterminal. -/// -/// On Linux, calling this function has no effect, as the kernel is expected to -/// grant the appropriate access. On all other platforms, this function has -/// unspecified behavior if the calling process has a [`Signal::CHILD`] signal -/// handler installed. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/grantpt.html -/// [Linux]: https://man7.org/linux/man-pages/man3/grantpt.3.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Allocation.html#index-grantpt -/// [`Signal::CHILD`]: crate::process::Signal::CHILD -#[inline] -pub fn grantpt<Fd: AsFd>(fd: Fd) -> io::Result<()> { - #[cfg(not(linux_kernel))] - { - backend::pty::syscalls::grantpt(fd.as_fd()) - } - - // On Linux, we assume the kernel has already granted the needed - // permissions to the user side of the pseudoterminal. - #[cfg(linux_kernel)] - { - let _ = fd; - Ok(()) - } -} - -/// `ioctl(fd, TIOCGPTPEER)`—Open the user side of a pseudoterminal. -/// -/// This function is currently only implemented on Linux. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_tty.2.html -#[cfg(target_os = "linux")] -#[inline] -pub fn ioctl_tiocgptpeer<Fd: AsFd>(fd: Fd, flags: OpenptFlags) -> io::Result<OwnedFd> { - unsafe { ioctl::ioctl(fd, Tiocgptpeer(flags)) } -} - -#[cfg(target_os = "linux")] -struct Tiocgptpeer(OpenptFlags); - -#[cfg(target_os = "linux")] -unsafe impl ioctl::Ioctl for Tiocgptpeer { - type Output = OwnedFd; - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> ioctl::Opcode { - c::TIOCGPTPEER as ioctl::Opcode - } - - fn as_ptr(&mut self) -> *mut c::c_void { - self.0.bits() as *mut c::c_void - } - - unsafe fn output_from_ptr( - ret: ioctl::IoctlOutput, - _arg: *mut c::c_void, - ) -> io::Result<Self::Output> { - Ok(OwnedFd::from_raw_fd(ret)) - } -} diff --git a/vendor/rustix/src/rand/getrandom.rs b/vendor/rustix/src/rand/getrandom.rs deleted file mode 100644 index 69af9a3d..00000000 --- a/vendor/rustix/src/rand/getrandom.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! Wrappers for `getrandom`. - -#![allow(unsafe_code)] - -use crate::buffer::Buffer; -use crate::{backend, io}; - -pub use backend::rand::types::GetRandomFlags; - -/// `getrandom(buf, flags)`—Reads a sequence of random bytes. -/// -/// This is a very low-level API which may be difficult to use correctly. Most -/// users should prefer to use [`getrandom`] or [`rand`] APIs instead. -/// -/// This function is implemented using a system call, and not the -/// [vDSO mechanism] introduced in Linux 6.11. See [#1185] for details. -/// -/// [`getrandom`]: https://crates.io/crates/getrandom -/// [`rand`]: https://crates.io/crates/rand -/// [vDSO mechanism]: https://lwn.net/Articles/983186/ -/// [#1185]: https://github.com/bytecodealliance/rustix/issues/1185 -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/getrandom.2.html -#[inline] -pub fn getrandom<Buf: Buffer<u8>>(mut buf: Buf, flags: GetRandomFlags) -> io::Result<Buf::Output> { - // SAFETY: `getrandom` behaves. - let len = unsafe { backend::rand::syscalls::getrandom(buf.parts_mut(), flags)? }; - // SAFETY: `getrandom` behaves. - unsafe { Ok(buf.assume_init(len)) } -} diff --git a/vendor/rustix/src/rand/mod.rs b/vendor/rustix/src/rand/mod.rs deleted file mode 100644 index e767c590..00000000 --- a/vendor/rustix/src/rand/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! Random-related operations. - -#[cfg(linux_kernel)] -mod getrandom; - -#[cfg(linux_kernel)] -pub use getrandom::{getrandom, GetRandomFlags}; diff --git a/vendor/rustix/src/runtime.rs b/vendor/rustix/src/runtime.rs deleted file mode 100644 index 9b612b8b..00000000 --- a/vendor/rustix/src/runtime.rs +++ /dev/null @@ -1,925 +0,0 @@ -//! Experimental low-level implementation details for libc-like runtime -//! libraries such as [Origin]. -//! -//! ⚠ These are not normal functions. ⚠ -//! -//! - Some of the functions in this module cannot be used in a process which -//! also has a libc present. This can be true even for functions that have -//! the same name as a libc function that Rust code can use. Such functions -//! are not marked `unsafe` (unless they are unsafe for other reasons), even -//! though they invoke Undefined Behavior if called in a process which has a -//! libc present. -//! -//! - Some of the functions in this module don't behave exactly the same way -//! as functions in libc with similar names. Sometimes information about the -//! differences is included in the Linux documentation under “C -//! library/kernel differences” sections. But not always. -//! -//! - The safety requirements of the functions in this module are not fully -//! documented. -//! -//! - The API for these functions is not considered stable, and this module is -//! `doc(hidden)`. -//! -//! ⚠ Caution is indicated. ⚠ -//! -//! These functions are for implementing thread-local storage (TLS), managing -//! threads, loaded libraries, and other process-wide resources. Most of -//! `rustix` doesn't care about what other libraries are linked into the -//! program or what they're doing, but the features in this module generally -//! can only be used by one entity within a process. -//! -//! All that said, there are some functions in this module would could -//! potentially be stabilized and moved to other modules. See also the -//! documentation for specific functions in the [`not_implemented`] module, and -//! the discussion in [#1314]. -//! -//! [Origin]: https://github.com/sunfishcode/origin#readme -//! [`not_implemented`]: crate::not_implemented -//! [#1314]: https://github.com/bytecodealliance/rustix/issues/1314 -//! -//! # Safety -//! -//! This module is intended to be used for implementing a runtime library such -//! as libc. Use of these features for any other purpose is likely to create -//! serious problems. -#![allow(unsafe_code)] - -use crate::ffi::CStr; -#[cfg(feature = "fs")] -use crate::fs::AtFlags; -use crate::pid::Pid; -use crate::{backend, io}; -#[cfg(feature = "fs")] -use backend::fd::AsFd; -use core::ffi::c_void; - -pub use crate::kernel_sigset::KernelSigSet; -pub use crate::signal::Signal; - -/// `kernel_sigaction` -/// -/// On some architectures, the `sa_restorer` field is omitted. -/// -/// This type does not have the same layout as `libc::sigaction`. -#[allow(missing_docs)] -#[derive(Debug, Default, Clone)] -#[repr(C)] -pub struct KernelSigaction { - pub sa_handler_kernel: KernelSighandler, - pub sa_flags: KernelSigactionFlags, - #[cfg(not(any( - target_arch = "csky", - target_arch = "loongarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv32", - target_arch = "riscv64" - )))] - pub sa_restorer: KernelSigrestore, - pub sa_mask: KernelSigSet, -} - -bitflags::bitflags! { - /// Flags for use with [`KernelSigaction`]. - /// - /// This type does not have the same layout as `sa_flags` field in - /// `libc::sigaction`, however the flags have the same values as their - /// libc counterparts. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)] - pub struct KernelSigactionFlags: crate::ffi::c_ulong { - /// `SA_NOCLDSTOP` - const NOCLDSTOP = linux_raw_sys::general::SA_NOCLDSTOP as _; - - /// `SA_NOCLDWAIT` (since Linux 2.6) - const NOCLDWAIT = linux_raw_sys::general::SA_NOCLDWAIT as _; - - /// `SA_NODEFER` - const NODEFER = linux_raw_sys::general::SA_NODEFER as _; - - /// `SA_ONSTACK` - const ONSTACK = linux_raw_sys::general::SA_ONSTACK as _; - - /// `SA_RESETHAND` - const RESETHAND = linux_raw_sys::general::SA_RESETHAND as _; - - /// `SA_RESTART` - const RESTART = linux_raw_sys::general::SA_RESTART as _; - - /// `SA_RESTORER` - #[cfg(not(any( - target_arch = "csky", - target_arch = "loongarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv32", - target_arch = "riscv64" - )))] - const RESTORER = linux_raw_sys::general::SA_RESTORER as _; - - /// `SA_SIGINFO` (since Linux 2.2) - const SIGINFO = linux_raw_sys::general::SA_SIGINFO as _; - - /// `SA_UNSUPPORTED` (since Linux 5.11) - const UNSUPPORTED = linux_raw_sys::general::SA_UNSUPPORTED as _; - - /// `SA_EXPOSE_TAGBITS` (since Linux 5.11) - const EXPOSE_TAGBITS = linux_raw_sys::general::SA_EXPOSE_TAGBITS as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `__sigrestore_t` -/// -/// This type differs from `libc::sigrestore_t`, but can be transmuted to it. -pub type KernelSigrestore = Option<unsafe extern "C" fn()>; - -/// `__kernel_sighandler_t` -/// -/// This type differs from `libc::sighandler_t`, but can be transmuted to it. -pub type KernelSighandler = Option<unsafe extern "C" fn(arg1: crate::ffi::c_int)>; - -/// Return a special “ignore” signal handler for ignoring signals. -/// -/// This isn't the `SIG_IGN` value itself; it's a function that returns the -/// `SIG_IGN` value. -/// -/// If you're looking for `kernel_sig_dfl`; use [`KERNEL_SIG_DFL`]. -#[doc(alias = "SIG_IGN")] -#[must_use] -pub const fn kernel_sig_ign() -> KernelSighandler { - linux_raw_sys::signal_macros::sig_ign() -} - -/// A special “default” signal handler representing the default behavior -/// for handling a signal. -/// -/// If you're looking for `KERNEL_SIG_IGN`; use [`kernel_sig_ign`]. -#[doc(alias = "SIG_DFL")] -pub const KERNEL_SIG_DFL: KernelSighandler = linux_raw_sys::signal_macros::SIG_DFL; - -/// `stack_t` -/// -/// This type is guaranteed to have the same layout as `libc::stack_t`. -/// -/// If we want to expose this in public APIs, we should encapsulate the -/// `linux_raw_sys` type. -pub use linux_raw_sys::general::stack_t as Stack; - -/// `siginfo_t` -/// -/// This type is guaranteed to have the same layout as `libc::siginfo_t`. -/// -/// If we want to expose this in public APIs, we should encapsulate the -/// `linux_raw_sys` type. -pub use linux_raw_sys::general::siginfo_t as Siginfo; - -pub use crate::timespec::{Nsecs, Secs, Timespec}; - -/// `SIG_*` constants for use with [`kernel_sigprocmask`]. -#[repr(u32)] -pub enum How { - /// `SIG_BLOCK` - BLOCK = linux_raw_sys::general::SIG_BLOCK, - - /// `SIG_UNBLOCK` - UNBLOCK = linux_raw_sys::general::SIG_UNBLOCK, - - /// `SIG_SETMASK` - SETMASK = linux_raw_sys::general::SIG_SETMASK, -} - -#[cfg(target_arch = "x86")] -#[inline] -pub unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { - backend::runtime::syscalls::tls::set_thread_area(u_info) -} - -#[cfg(target_arch = "arm")] -#[inline] -pub unsafe fn arm_set_tls(data: *mut c_void) -> io::Result<()> { - backend::runtime::syscalls::tls::arm_set_tls(data) -} - -/// `prctl(PR_SET_FS, data)`—Set the x86-64 `fs` register. -/// -/// # Safety -/// -/// This is a very low-level feature for implementing threading libraries. -/// See the references links above. -#[cfg(target_arch = "x86_64")] -#[inline] -pub unsafe fn set_fs(data: *mut c_void) { - backend::runtime::syscalls::tls::set_fs(data) -} - -/// Set the x86-64 thread ID address. -/// -/// # Safety -/// -/// This is a very low-level feature for implementing threading libraries. -/// See the references links above. -#[inline] -pub unsafe fn set_tid_address(data: *mut c_void) -> Pid { - backend::runtime::syscalls::tls::set_tid_address(data) -} - -#[cfg(target_arch = "x86")] -pub use backend::runtime::tls::UserDesc; - -/// `syscall(SYS_exit, status)`—Exit the current thread. -/// -/// # Safety -/// -/// This is a very low-level feature for implementing threading libraries. -#[inline] -pub unsafe fn exit_thread(status: i32) -> ! { - backend::runtime::syscalls::tls::exit_thread(status) -} - -/// Exit all the threads in the current process' thread group. -/// -/// This is equivalent to `_exit` and `_Exit` in libc. -/// -/// This does not call any `__cxa_atexit`, `atexit`, or any other destructors. -/// Most programs should use [`std::process::exit`] instead of calling this -/// directly. -/// -/// # References -/// - [POSIX `_Exit`] -/// - [Linux `exit_group`] -/// - [Linux `_Exit`] -/// -/// [POSIX `_Exit`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/_Exit.html -/// [Linux `exit_group`]: https://man7.org/linux/man-pages/man2/exit_group.2.html -/// [Linux `_Exit`]: https://man7.org/linux/man-pages/man2/_Exit.2.html -#[doc(alias = "_exit", alias = "_Exit")] -#[inline] -pub fn exit_group(status: i32) -> ! { - backend::runtime::syscalls::exit_group(status) -} - -/// `EXIT_SUCCESS` for use with [`exit_group`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html -/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_SUCCESS: i32 = backend::c::EXIT_SUCCESS; - -/// `EXIT_FAILURE` for use with [`exit_group`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html -/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_FAILURE: i32 = backend::c::EXIT_FAILURE; - -/// `(getauxval(AT_PHDR), getauxval(AT_PHENT), getauxval(AT_PHNUM))`—Returns -/// the address, ELF segment header size, and number of ELF segment headers for -/// the main executable. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[inline] -pub fn exe_phdrs() -> (*const c_void, usize, usize) { - backend::param::auxv::exe_phdrs() -} - -/// `getauxval(AT_ENTRY)`—Returns the address of the program entrypoint. -/// -/// Most code interested in the program entrypoint address should instead use a -/// symbol reference to `_start`. That will be properly PC-relative or -/// relocated if needed, and will come with appropriate pointer type and -/// pointer provenance. -/// -/// This function is intended only for use in code that implements those -/// relocations, to compute the ASLR offset. It has type `usize`, so it doesn't -/// carry any provenance, and it shouldn't be used to dereference memory. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[inline] -pub fn entry() -> usize { - backend::param::auxv::entry() -} - -/// `getauxval(AT_RANDOM)`—Returns the address of 16 pseudorandom bytes. -/// -/// These bytes are for use by libc. For anything else, use the `rand` crate. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[inline] -pub fn random() -> *const [u8; 16] { - backend::param::auxv::random() -} - -/// `fork()`—Creates a new process by duplicating the calling process. -/// -/// On success, `Fork::ParentOf` containing the pid of the child process is -/// returned in the parent, and `Fork::Child` containing the pid of the child -/// process is returned in the child. -/// -/// Unlike its POSIX and libc counterparts, this `fork` does not invoke any -/// handlers (such as those registered with `pthread_atfork`). -/// -/// The program environment in the child after a `fork` and before an `execve` -/// is very special. All code that executes in this environment must avoid: -/// -/// - Acquiring any other locks that are held in other threads on the parent -/// at the time of the `fork`, as the child only contains one thread, and -/// attempting to acquire such locks will deadlock (though this is [not -/// considered unsafe]). -/// -/// - Performing any dynamic allocation using the global allocator, since -/// global allocators may use locks to ensure thread safety, and their locks -/// may not be released in the child process, so attempts to allocate may -/// deadlock (as described in the previous point). -/// -/// - Accessing any external state which the parent assumes it has exclusive -/// access to, such as a file protected by a file lock, as this could -/// corrupt the external state. -/// -/// - Accessing any random-number-generator state inherited from the parent, -/// as the parent may have the same state and generate the same random -/// numbers, which may violate security invariants. -/// -/// - Accessing any thread runtime state, since this function does not update -/// the thread id in the thread runtime, so thread runtime functions could -/// cause undefined behavior. -/// -/// - Accessing any memory shared with the parent, such as a [`MAP_SHARED`] -/// mapping, even with anonymous or [`memfd_create`] mappings, as this could -/// cause undefined behavior. -/// -/// - Calling any C function which isn't known to be [async-signal-safe], as -/// that could cause undefined behavior. The extent to which this also -/// applies to Rust functions is unclear at this time. -/// -/// - And more. -/// -/// # Safety -/// -/// The child must avoid accessing any memory shared with the parent in a -/// way that invokes undefined behavior. It must avoid accessing any threading -/// runtime functions in a way that invokes undefined behavior. And it must -/// avoid invoking any undefined behavior through any function that is not -/// guaranteed to be async-signal-safe. But, what does async-signal-safe even -/// mean in a Rust program? This documentation does not have all the answers. -/// -/// So you're on your own. And on top of all the troubles with `fork` in -/// general, this wrapper implementation is highly experimental. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// # Literary interlude -/// -/// > Do not jump on ancient uncles. -/// > Do not yell at average mice. -/// > Do not wear a broom to breakfast. -/// > Do not ask a snake’s advice. -/// > Do not bathe in chocolate pudding. -/// > Do not talk to bearded bears. -/// > Do not smoke cigars on sofas. -/// > Do not dance on velvet chairs. -/// > Do not take a whale to visit -/// > Russell’s mother’s cousin’s yacht. -/// > And whatever else you do do -/// > It is better you -/// > Do not. -/// -/// — “Rules”, by Karla Kuskin -/// -/// [`MAP_SHARED`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mmap.html -/// [not considered unsafe]: https://doc.rust-lang.org/reference/behavior-not-considered-unsafe.html#deadlocks -/// [`memfd_create`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fork.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fork.2.html -/// [async-signal-safe]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html#tag_15_04_03 -pub unsafe fn kernel_fork() -> io::Result<Fork> { - backend::runtime::syscalls::kernel_fork() -} - -/// Regular Unix `fork` doesn't tell the child its own PID because it assumes -/// the child can just do `getpid`. That's true, but it's more fun if it -/// doesn't have to. -pub enum Fork { - /// This is returned in the child process after a `fork`. It holds the PID - /// of the child. - Child(Pid), - - /// This is returned in the parent process after a `fork`. It holds the PID - /// of the child. - ParentOf(Pid), -} - -/// `execveat(dirfd, path.as_c_str(), argv, envp, flags)`—Execute a new -/// command using the current process. -/// -/// Taking raw-pointers-to-raw-pointers is convenient for c-scape, but we -/// should think about potentially a more Rust-idiomatic API if this is ever -/// made public. -/// -/// # Safety -/// -/// The `argv` and `envp` pointers must point to NUL-terminated arrays, and -/// their contents must be pointers to NUL-terminated byte arrays. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/execveat.2.html -#[inline] -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[must_use] -pub unsafe fn execveat<Fd: AsFd>( - dirfd: Fd, - path: &CStr, - argv: *const *const u8, - envp: *const *const u8, - flags: AtFlags, -) -> io::Errno { - backend::runtime::syscalls::execveat(dirfd.as_fd(), path, argv, envp, flags) -} - -/// `execve(path.as_c_str(), argv, envp)`—Execute a new command using the -/// current process. -/// -/// Taking raw-pointers-to-raw-pointers is convenient for c-scape, but we -/// should think about potentially a more Rust-idiomatic API if this is ever -/// made public. -/// -/// # Safety -/// -/// The `argv` and `envp` pointers must point to NUL-terminated arrays, and -/// their contents must be pointers to NUL-terminated byte arrays. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/execve.2.html -#[inline] -#[must_use] -pub unsafe fn execve(path: &CStr, argv: *const *const u8, envp: *const *const u8) -> io::Errno { - backend::runtime::syscalls::execve(path, argv, envp) -} - -/// `sigaction(signal, &new, &old)`—Modify and/or query a signal handler. -/// -/// # Safety -/// -/// You're on your own. And on top of all the troubles with signal handlers, -/// this implementation is highly experimental. Even further, it differs from -/// the libc `sigaction` in several non-obvious and unsafe ways. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigaction.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sigaction.2.html -#[inline] -pub unsafe fn kernel_sigaction( - signal: Signal, - new: Option<KernelSigaction>, -) -> io::Result<KernelSigaction> { - backend::runtime::syscalls::kernel_sigaction(signal, new) -} - -/// `sigaltstack(new, old)`—Modify and/or query a signal stack. -/// -/// # Safety -/// -/// The memory region described by `new` must readable and writable and larger -/// than the platform minimum signal stack size, and must have a guard region -/// that conforms to the platform conventions for stack guard regions. The -/// flags in `new` must be valid. This function does not diagnose all the -/// errors that libc `sigaltstack` functions are documented as diagnosing. -/// -/// While the memory region pointed to by `new` is registered as a signal -/// stack, it must remain readable and writable, and must not be mutated in -/// any way other than by having a signal handler run in it, and must not be -/// the referent of a Rust reference from outside the signal handler. -/// -/// If code elsewhere in the program is depending on signal handlers being run -/// on a particular stack, this could break that code's assumptions. And if the -/// caller is depending on signal handlers being run on the stack specified in -/// the call, its assumptions could be broken by code elsewhere in the program -/// calling this function. -/// -/// There are probably things out there that assume that all alternate signal -/// stack registration goes through libc, and this does not go through libc. -/// -/// There may be further safety hazards not yet documented here. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigaltstack.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sigaltstack.2.html -#[inline] -pub unsafe fn kernel_sigaltstack(new: Option<Stack>) -> io::Result<Stack> { - backend::runtime::syscalls::kernel_sigaltstack(new) -} - -/// `tkill(tid, sig)`—Send a signal to a thread. -/// -/// # Safety -/// -/// Causing an individual thread to abruptly terminate without involving the -/// process' thread runtime (such as the libpthread or the libc) evokes -/// undefined behavior. -/// -/// Also, this is not `tgkill`, so the warning about the hazard of recycled -/// thread IDs applies. -/// -/// There may be further safety hazards not yet documented here. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/tkill.2.html -#[inline] -pub unsafe fn tkill(tid: Pid, sig: Signal) -> io::Result<()> { - backend::runtime::syscalls::tkill(tid, sig) -} - -/// `rt_sigprocmask(how, set, oldset)`—Adjust the process signal mask. -/// -/// If this is ever exposed publicly, we should think about whether it should -/// mask out signals reserved by libc. -/// -/// # Safety -/// -/// If there is a libc in the process, the `set` must not contain any signal -/// reserved by the libc. -/// -/// If code elsewhere in the program is depending on delivery of a signal for -/// any reason, for example to prevent it from executing some code, this could -/// cause it to miss that signal, and for example execute that code. And if the -/// caller is depending on delivery of a signal for any reason, its assumptions -/// could be broken by code elsewhere in the program calling this function. -/// -/// There may be further safety hazards not yet documented here. -/// -/// # References -/// - [Linux `rt_sigprocmask`] -/// - [Linux `pthread_sigmask`] -/// -/// [Linux `rt_sigprocmask`]: https://man7.org/linux/man-pages/man2/rt_sigprocmask.2.html -/// [Linux `pthread_sigmask`]: https://man7.org/linux/man-pages/man3/pthread_sigmask.3.html -#[inline] -#[doc(alias = "pthread_sigmask")] -#[doc(alias = "rt_sigprocmask")] -pub unsafe fn kernel_sigprocmask(how: How, set: Option<&KernelSigSet>) -> io::Result<KernelSigSet> { - backend::runtime::syscalls::kernel_sigprocmask(how, set) -} - -/// `sigpending()`—Query the pending signals. -/// -/// If this is ever exposed publicly, we should think about whether it should -/// mask out signals reserved by libc. -/// -/// # References -/// - [Linux `sigpending`] -/// -/// [Linux `sigpending`]: https://man7.org/linux/man-pages/man2/sigpending.2.html -#[inline] -pub fn kernel_sigpending() -> KernelSigSet { - backend::runtime::syscalls::kernel_sigpending() -} - -/// `sigsuspend(set)`—Suspend the calling thread and wait for signals. -/// -/// If this is ever exposed publicly, we should think about whether it should -/// be made to fail if given signals reserved by libc. -/// -/// # References -/// - [Linux `sigsuspend`] -/// -/// [Linux `sigsuspend`]: https://man7.org/linux/man-pages/man2/sigsuspend.2.html -#[inline] -pub fn kernel_sigsuspend(set: &KernelSigSet) -> io::Result<()> { - backend::runtime::syscalls::kernel_sigsuspend(set) -} - -/// `sigwait(set)`—Wait for signals. -/// -/// If this is ever exposed publicly, we should think about whether it should -/// mask out signals reserved by libc. -/// -/// # Safety -/// -/// If there is a libc in the process, the `set` must not contain any signal -/// reserved by the libc. -/// -/// If code elsewhere in the program is depending on delivery of a signal for -/// any reason, for example to prevent it from executing some code, this could -/// cause it to miss that signal, and for example execute that code. And if the -/// caller is depending on delivery of a signal for any reason, its assumptions -/// could be broken by code elsewhere in the program calling this function. -/// -/// There may be further safety hazards not yet documented here. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/sigwait.3.html -#[inline] -pub unsafe fn kernel_sigwait(set: &KernelSigSet) -> io::Result<Signal> { - backend::runtime::syscalls::kernel_sigwait(set) -} - -/// `sigwaitinfo(set)`—Wait for signals, returning a [`Siginfo`]. -/// -/// If this is ever exposed publicly, we should think about whether it should -/// mask out signals reserved by libc. -/// -/// # Safety -/// -/// If there is a libc in the process, the `set` must not contain any signal -/// reserved by the libc. -/// -/// If code elsewhere in the program is depending on delivery of a signal for -/// any reason, for example to prevent it from executing some code, this could -/// cause it to miss that signal, and for example execute that code. And if the -/// caller is depending on delivery of a signal for any reason, its assumptions -/// could be broken by code elsewhere in the program calling this function. -/// -/// There may be further safety hazards not yet documented here. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sigwaitinfo.2.html -#[inline] -pub unsafe fn kernel_sigwaitinfo(set: &KernelSigSet) -> io::Result<Siginfo> { - backend::runtime::syscalls::kernel_sigwaitinfo(set) -} - -/// `sigtimedwait(set)`—Wait for signals, optionally with a timeout. -/// -/// If this is ever exposed publicly, we should think about whether it should -/// mask out signals reserved by libc. -/// -/// # Safety -/// -/// If there is a libc in the process, the `set` must not contain any signal -/// reserved by the libc. -/// -/// If code elsewhere in the program is depending on delivery of a signal for -/// any reason, for example to prevent it from executing some code, this could -/// cause it to miss that signal, and for example execute that code. And if the -/// caller is depending on delivery of a signal for any reason, its assumptions -/// could be broken by code elsewhere in the program calling this function. -/// -/// There may be further safety hazards not yet documented here. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sigtimedwait.2.html -#[inline] -pub unsafe fn kernel_sigtimedwait( - set: &KernelSigSet, - timeout: Option<&Timespec>, -) -> io::Result<Siginfo> { - backend::runtime::syscalls::kernel_sigtimedwait(set, timeout) -} - -/// `getauxval(AT_SECURE)`—Returns the Linux “secure execution” mode. -/// -/// Return a boolean value indicating whether “secure execution” mode was -/// requested, due to the process having elevated privileges. This includes -/// whether the `AT_SECURE` AUX value is set, and whether the initial real UID -/// and GID differ from the initial effective UID and GID. -/// -/// The meaning of “secure execution” mode is beyond the scope of this -/// comment. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html -#[inline] -pub fn linux_secure() -> bool { - backend::param::auxv::linux_secure() -} - -/// `brk(addr)`—Change the location of the “program break”. -/// -/// # Safety -/// -/// This is not identical to `brk` in libc. libc `brk` may have bookkeeping -/// that needs to be kept up to date that this doesn't keep up to date, so -/// don't use it unless you know your code won't share a process with a libc -/// (perhaps because you yourself are implementing a libc). -#[inline] -pub unsafe fn kernel_brk(addr: *mut c_void) -> io::Result<*mut c_void> { - backend::runtime::syscalls::kernel_brk(addr) -} - -/// `SIGRTMIN`—The start of the raw OS “real-time” signal range. -/// -/// This is the raw `SIGRTMIN` value from the OS, which is not the same as the -/// `SIGRTMIN` macro provided by libc. Don't use this unless you know your code -/// won't share a process with a libc (perhaps because you yourself are -/// implementing a libc). -pub const KERNEL_SIGRTMIN: i32 = linux_raw_sys::general::SIGRTMIN as i32; - -/// `SIGRTMAX`—The last of the raw OS “real-time” signal range. -/// -/// This is the raw `SIGRTMAX` value from the OS, which is not the same as the -/// `SIGRTMAX` macro provided by libc. Don't use this unless you know your code -/// won't share a process with a libc (perhaps because you yourself are -/// implementing a libc). -pub const KERNEL_SIGRTMAX: i32 = { - // Use the actual `SIGRTMAX` value on platforms which define it. - #[cfg(not(any( - target_arch = "arm", - target_arch = "s390x", - target_arch = "x86", - target_arch = "x86_64", - )))] - { - linux_raw_sys::general::SIGRTMAX as i32 - } - - // On platforms that don't, derive it from `_NSIG`. - // - // In the Linux kernel headers, `_NSIG` refers to the number of signals - // known to the kernel. It's 64 on most architectures. - // - // In libc headers, `_NSIG` refers to the exclusive upper bound of the - // signals known to the kernel. It's 65 on most architectures. - // - // This discrepancy arises because a signal value of 0 is used as a - // sentinel, and the first `sigset_t` bit is signal 1 instead of 0. The - // Linux kernel headers and libc headers disagree on the interpretation of - // `_NSIG` as a result. - // - // Here, we use the Linux kernel header value. - #[cfg(any( - target_arch = "arm", - target_arch = "s390x", - target_arch = "x86", - target_arch = "x86_64", - ))] - { - linux_raw_sys::general::_NSIG as i32 - } -}; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_assumptions() { - assert!(libc::SIGSYS < KERNEL_SIGRTMIN); - assert!(KERNEL_SIGRTMIN <= libc::SIGRTMIN()); - - // POSIX guarantees at least 8 RT signals. - assert!(libc::SIGRTMIN() + 8 <= KERNEL_SIGRTMAX); - - // POSIX guarantees at least 8 RT signals, and it's not uncommon for - // libc implementations to reserve up to 3 for their own purposes. - assert!(KERNEL_SIGRTMIN + 8 + 3 <= KERNEL_SIGRTMAX); - - assert!(KERNEL_SIGRTMAX <= libc::SIGRTMAX()); - assert!(libc::SIGRTMAX() as u32 <= linux_raw_sys::general::_NSIG); - - assert!(KERNEL_SIGRTMAX as usize - 1 < core::mem::size_of::<KernelSigSet>() * 8); - } - - #[test] - fn test_layouts_matching_libc() { - use linux_raw_sys::general::siginfo__bindgen_ty_1__bindgen_ty_1; - - // c-scape assumes rustix's `Siginfo` matches libc's. We don't use - // check_types macros because we want to test compatibility with actual - // libc, not the `crate::backend::c` which might be our own - // implementation. - assert_eq_size!(Siginfo, libc::siginfo_t); - assert_eq_align!(Siginfo, libc::siginfo_t); - assert_eq!( - memoffset::span_of!(Siginfo, ..), - memoffset::span_of!(Siginfo, __bindgen_anon_1) - ); - assert_eq!( - memoffset::span_of!(siginfo__bindgen_ty_1__bindgen_ty_1, si_signo), - memoffset::span_of!(libc::siginfo_t, si_signo) - ); - assert_eq!( - memoffset::span_of!(siginfo__bindgen_ty_1__bindgen_ty_1, si_errno), - memoffset::span_of!(libc::siginfo_t, si_errno) - ); - assert_eq!( - memoffset::span_of!(siginfo__bindgen_ty_1__bindgen_ty_1, si_code), - memoffset::span_of!(libc::siginfo_t, si_code) - ); - - // c-scape assumes rustix's `Stack` matches libc's. Similar to above. - assert_eq_size!(Stack, libc::stack_t); - assert_eq_align!(Stack, libc::stack_t); - assert_eq!( - memoffset::span_of!(Stack, ss_sp), - memoffset::span_of!(libc::stack_t, ss_sp) - ); - assert_eq!( - memoffset::span_of!(Stack, ss_flags), - memoffset::span_of!(libc::stack_t, ss_flags) - ); - assert_eq!( - memoffset::span_of!(Stack, ss_size), - memoffset::span_of!(libc::stack_t, ss_size) - ); - } - - #[test] - fn test_layouts_matching_kernel() { - use linux_raw_sys::general as c; - - // Rustix's versions of these must match the kernel's versions. - // Some architectures have `sa_restorer`. - #[cfg(not(any( - target_arch = "csky", - target_arch = "loongarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv32", - target_arch = "riscv64" - )))] - check_renamed_struct!( - KernelSigaction, - kernel_sigaction, - sa_handler_kernel, - sa_flags, - sa_restorer, - sa_mask - ); - // Some architectures omit `sa_restorer`. - #[cfg(any( - target_arch = "csky", - target_arch = "loongarch64", - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "riscv32", - target_arch = "riscv64" - ))] - check_renamed_struct!( - KernelSigaction, - kernel_sigaction, - sa_handler_kernel, - sa_flags, - sa_mask - ); - assert_eq_size!(KernelSigactionFlags, crate::ffi::c_ulong); - assert_eq_align!(KernelSigactionFlags, crate::ffi::c_ulong); - check_renamed_type!(KernelSigrestore, __sigrestore_t); - check_renamed_type!(KernelSighandler, __kernel_sighandler_t); - - assert_eq!( - libc::SA_NOCLDSTOP, - KernelSigactionFlags::NOCLDSTOP.bits() as _ - ); - assert_eq!( - libc::SA_NOCLDWAIT, - KernelSigactionFlags::NOCLDWAIT.bits() as _ - ); - assert_eq!(libc::SA_NODEFER, KernelSigactionFlags::NODEFER.bits() as _); - assert_eq!(libc::SA_ONSTACK, KernelSigactionFlags::ONSTACK.bits() as _); - assert_eq!( - libc::SA_RESETHAND, - KernelSigactionFlags::RESETHAND.bits() as _ - ); - assert_eq!(libc::SA_RESTART, KernelSigactionFlags::RESTART.bits() as _); - assert_eq!(libc::SA_SIGINFO, KernelSigactionFlags::SIGINFO.bits() as _); - } -} diff --git a/vendor/rustix/src/shm.rs b/vendor/rustix/src/shm.rs deleted file mode 100644 index f279250d..00000000 --- a/vendor/rustix/src/shm.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! POSIX shared memory -//! -//! # Examples -//! -//! ``` -//! use rustix::fs::{ftruncate, Mode}; -//! use rustix::mm::{mmap, MapFlags, ProtFlags}; -//! use rustix::{io, shm}; -//! use std::mem::size_of; -//! use std::ptr::null_mut; -//! -//! # fn example() -> io::Result<()> { -//! // A type describing the data to be shared. -//! #[repr(C)] -//! struct MyBufferType { -//! // … -//! } -//! -//! // Create the shared memory object. -//! let shm_path = "/rustix-shm-example"; -//! let fd = shm::open( -//! shm_path, -//! shm::OFlags::CREATE | shm::OFlags::EXCL | shm::OFlags::RDWR, -//! Mode::RUSR | Mode::WUSR, -//! )?; -//! -//! // Resize the shared memory object to the size of our data. -//! ftruncate(&fd, size_of::<MyBufferType>() as u64)?; -//! -//! // Map the shared memory object into our address space. -//! // -//! // SAFETY: We're creating a new mapping that's independent of any existing -//! // memory allocations. There are interesting things to say about *using* -//! // `ptr`, but that's for another safety comment. -//! let ptr = unsafe { -//! mmap( -//! null_mut(), -//! size_of::<MyBufferType>(), -//! ProtFlags::READ | ProtFlags::WRITE, -//! MapFlags::SHARED, -//! &fd, -//! 0, -//! )? -//! }; -//! -//! // Use `ptr`… -//! -//! // Remove the shared memory object name. -//! shm::unlink(shm_path)?; -//! # Ok(()) -//! # } -//! ``` - -#![allow(unused_qualifications)] - -use crate::fd::OwnedFd; -use crate::{backend, io, path}; - -use super::shm; -pub use crate::backend::fs::types::Mode; -pub use crate::backend::shm::types::ShmOFlags as OFlags; - -/// `shm_open(name, oflags, mode)`—Opens a shared memory object. -/// -/// For portability, `name` should begin with a slash, contain no other -/// slashes, and be no longer than an implementation-defined limit (255 on -/// Linux). -/// -/// Exactly one of [`shm::OFlags::RDONLY`] and [`shm::OFlags::RDWR`] should be -/// passed. The file descriptor will be opened with `FD_CLOEXEC` set. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_open.html -/// [Linux]: https://man7.org/linux/man-pages/man3/shm_open.3.html -#[doc(alias = "shm_open")] -#[inline] -pub fn open<P: path::Arg>(name: P, flags: shm::OFlags, mode: Mode) -> io::Result<OwnedFd> { - name.into_with_c_str(|name| backend::shm::syscalls::shm_open(name, flags, mode)) -} - -/// `shm_unlink(name)`—Unlinks a shared memory object. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_unlink.html -/// [Linux]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html -#[doc(alias = "shm_unlink")] -#[inline] -pub fn unlink<P: path::Arg>(name: P) -> io::Result<()> { - name.into_with_c_str(backend::shm::syscalls::shm_unlink) -} diff --git a/vendor/rustix/src/signal.rs b/vendor/rustix/src/signal.rs deleted file mode 100644 index e69c64b8..00000000 --- a/vendor/rustix/src/signal.rs +++ /dev/null @@ -1,539 +0,0 @@ -//! Signal numbers. -//! -//! # Safety -//! -//! Some signal numbers are reserved by the libc. -//! [`Signal::from_raw_unchecked`] and [`Signal::from_raw_nonzero_unchecked`] -//! allow constructing `Signal` values with arbitrary values. Users must avoid -//! using reserved values to send, consume, or block any signals or alter any -//! signal handlers. -//! -//! See the individual functions' safety comments for more details. -#![allow(unsafe_code)] - -use crate::backend::c; -use core::fmt; -use core::num::NonZeroI32; - -/// A signal number for use with [`kill_process`], [`kill_process_group`], and -/// [`kill_current_process_group`]. -/// -/// For additional constructors such as [`Signal::rt_min`] -/// (aka `libc::SIGRTMIN`), [`Signal::rt_max`] (aka `libc::SIGRTMAX`), -/// [`Signal::rt`] (aka `|n| libc::SIGRTMIN() + n`), [`Signal::from_raw`], and -/// [`Signal::from_raw_nonzero`], see [rustix-libc-wrappers]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/signal.h.html -/// [Linux]: https://man7.org/linux/man-pages/man7/signal.7.html -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Signals.html -/// -/// [`kill_process`]: crate::process::kill_process -/// [`kill_process_group`]: crate::process::kill_process_group -/// [`kill_current_process_group`]: crate::process::kill_current_process_group -/// [`Signal::rt_min`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.rt_min -/// [`Signal::rt_max`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.rt_max -/// [`Signal::rt`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.rt -/// [`Signal::from_raw`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.from_raw -/// [`Signal::from_raw_nonzero`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.from_raw_nonzero -/// [rustix-libc-wrappers]: https://docs.rs/rustix-libc-wrappers -#[doc(alias = "SIGRTMIN")] -#[doc(alias = "SIGRTMAX")] -#[derive(Copy, Clone, Eq, PartialEq)] -#[repr(transparent)] -pub struct Signal(NonZeroI32); - -// SAFETY: The libc-defined signal values are all non-zero. -#[rustfmt::skip] -impl Signal { - /// `SIGHUP` - pub const HUP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGHUP) }); - /// `SIGINT` - pub const INT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGINT) }); - /// `SIGQUIT` - pub const QUIT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGQUIT) }); - /// `SIGILL` - pub const ILL: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGILL) }); - /// `SIGTRAP` - pub const TRAP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTRAP) }); - /// `SIGABRT`, aka `SIGIOT` - #[doc(alias = "IOT")] - #[doc(alias = "ABRT")] - pub const ABORT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGABRT) }); - /// `SIGBUS` - pub const BUS: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGBUS) }); - /// `SIGFPE` - pub const FPE: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGFPE) }); - /// `SIGKILL` - pub const KILL: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGKILL) }); - /// `SIGUSR1` - #[cfg(not(target_os = "vita"))] - pub const USR1: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGUSR1) }); - /// `SIGSEGV` - pub const SEGV: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSEGV) }); - /// `SIGUSR2` - #[cfg(not(target_os = "vita"))] - pub const USR2: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGUSR2) }); - /// `SIGPIPE` - pub const PIPE: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGPIPE) }); - /// `SIGALRM` - #[doc(alias = "ALRM")] - pub const ALARM: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGALRM) }); - /// `SIGTERM` - pub const TERM: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTERM) }); - /// `SIGSTKFLT` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "vita", - all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ), - ), - )))] - pub const STKFLT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSTKFLT) }); - /// `SIGCHLD` - #[cfg(not(target_os = "vita"))] - #[doc(alias = "CHLD")] - pub const CHILD: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGCHLD) }); - /// `SIGCONT` - #[cfg(not(target_os = "vita"))] - pub const CONT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGCONT) }); - /// `SIGSTOP` - #[cfg(not(target_os = "vita"))] - pub const STOP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSTOP) }); - /// `SIGTSTP` - #[cfg(not(target_os = "vita"))] - pub const TSTP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTSTP) }); - /// `SIGTTIN` - #[cfg(not(target_os = "vita"))] - pub const TTIN: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTTIN) }); - /// `SIGTTOU` - #[cfg(not(target_os = "vita"))] - pub const TTOU: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTTOU) }); - /// `SIGURG` - #[cfg(not(target_os = "vita"))] - pub const URG: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGURG) }); - /// `SIGXCPU` - #[cfg(not(target_os = "vita"))] - pub const XCPU: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGXCPU) }); - /// `SIGXFSZ` - #[cfg(not(target_os = "vita"))] - pub const XFSZ: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGXFSZ) }); - /// `SIGVTALRM` - #[cfg(not(target_os = "vita"))] - #[doc(alias = "VTALRM")] - pub const VTALARM: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGVTALRM) }); - /// `SIGPROF` - #[cfg(not(target_os = "vita"))] - pub const PROF: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGPROF) }); - /// `SIGWINCH` - #[cfg(not(target_os = "vita"))] - pub const WINCH: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGWINCH) }); - /// `SIGIO`, aka `SIGPOLL` - #[doc(alias = "POLL")] - #[cfg(not(any(target_os = "haiku", target_os = "vita")))] - pub const IO: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGIO) }); - /// `SIGPWR` - #[cfg(not(any( - bsd, - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "vita" - )))] - #[doc(alias = "PWR")] - pub const POWER: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGPWR) }); - /// `SIGSYS`, aka `SIGUNUSED` - #[doc(alias = "UNUSED")] - pub const SYS: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSYS) }); - /// `SIGEMT` - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "hermit", - all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ) - ) - ))] - pub const EMT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGEMT) }); - /// `SIGINFO` - #[cfg(bsd)] - pub const INFO: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGINFO) }); - /// `SIGTHR` - #[cfg(target_os = "freebsd")] - #[doc(alias = "LWP")] - pub const THR: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTHR) }); - /// `SIGLIBRT` - #[cfg(target_os = "freebsd")] - pub const LIBRT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGLIBRT) }); -} - -impl Signal { - /// Convert a `Signal` to a raw signal number. - /// - /// To convert to a `NonZeroI32`, use [`Signal::as_raw_nonzero`]. - #[inline] - pub const fn as_raw(self) -> i32 { - self.0.get() - } - - /// Convert a `Signal` to a raw non-zero signal number. - #[inline] - pub const fn as_raw_nonzero(self) -> NonZeroI32 { - self.0 - } - - /// Convert a raw signal number into a `Signal` without checks. - /// - /// For a safe checked version, see [`Signal::from_raw`] in - /// [rustix-libc-wrappers]. - /// - /// # Safety - /// - /// `sig` must be a valid and non-zero signal number. - /// - /// And, if `sig` is a signal number reserved by the libc, such as a value - /// from the libc [`SIGRTMIN`] to the libc [`SIGRTMAX`], inclusive, then - /// the resulting `Signal` must not be used to send, consume, or block any - /// signals or alter any signal handlers. - /// - /// [`Signal::from_raw`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.from_raw - /// [rustix-libc-wrappers]: https://docs.rs/rustix-libc-wrappers - /// [`SIGRTMIN`]: https://docs.rs/libc/*/libc/fn.SIGRTMIN.html - /// [`SIGRTMAX`]: https://docs.rs/libc/*/libc/fn.SIGRTMAX.html - #[inline] - pub const unsafe fn from_raw_unchecked(sig: i32) -> Self { - Self::from_raw_nonzero_unchecked(NonZeroI32::new_unchecked(sig)) - } - - /// Convert a raw non-zero signal number into a `Signal` without checks. - /// - /// For a safe checked version, see [`Signal::from_raw_nonzero`] in - /// [rustix-libc-wrappers]. - /// - /// # Safety - /// - /// `sig` must be a valid signal number. - /// - /// And, if `sig` is a signal number reserved by the libc, such as a value - /// from [`SIGRTMIN`] to [`SIGRTMAX`] inclusive, then the resulting - /// `Signal` must not be used to send, consume, or block any signals or - /// alter any signal handlers. - /// - /// [`Signal::from_raw_nonzero`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.from_raw_nonzero - /// [rustix-libc-wrappers]: https://docs.rs/rustix-libc-wrappers - /// [`SIGRTMIN`]: https://docs.rs/libc/*/libc/fn.SIGRTMIN.html - /// [`SIGRTMAX`]: https://docs.rs/libc/*/libc/fn.SIGRTMAX.html - #[inline] - pub const unsafe fn from_raw_nonzero_unchecked(sig: NonZeroI32) -> Self { - Self(sig) - } - - /// Convert a raw named signal number into a `Signal`. - /// - /// If the given signal number corresponds to one of the named constant - /// signal values, such as [`Signal::HUP`] or [`Signal::INT`], return the - /// `Signal` value. Otherwise return `None`. - /// - /// Signals in the range `SIGRTMIN` through `SIGRTMAX` are not supported by - /// this function. For a constructor that does recognize those values, see - /// [`Signal::from_raw`] in [rustix-libc-wrappers]. - /// - /// [`Signal::from_raw`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.from_raw - /// [rustix-libc-wrappers]: https://docs.rs/rustix-libc-wrappers - pub const fn from_named_raw(sig: i32) -> Option<Self> { - if let Some(sig) = NonZeroI32::new(sig) { - Self::from_named_raw_nonzero(sig) - } else { - None - } - } - - /// Convert a raw non-zero named signal number into a `Signal`. - /// - /// If the given signal number corresponds to one of the constant signal - /// values, such as [`Signal::HUP`] or [`Signal::INT`], return the - /// `Signal` value. Otherwise return `None`. - /// - /// Signals in the range `SIGRTMIN` through `SIGRTMAX` are not supported by - /// this function. For a constructor that does recognize those values, see - /// [`Signal::from_raw_nonzero`] in [rustix-libc-wrappers]. - /// - /// [`Signal::from_raw_nonzero`]: https://docs.rs/rustix-libc-wrappers/*/rustix_libc_wrappers/trait.SignalExt.html#tymethod.from_raw_nonzero - /// [rustix-libc-wrappers]: https://docs.rs/rustix-libc-wrappers - pub const fn from_named_raw_nonzero(sig: NonZeroI32) -> Option<Self> { - match sig.get() { - c::SIGHUP => Some(Self::HUP), - c::SIGINT => Some(Self::INT), - c::SIGQUIT => Some(Self::QUIT), - c::SIGILL => Some(Self::ILL), - c::SIGTRAP => Some(Self::TRAP), - c::SIGABRT => Some(Self::ABORT), - c::SIGBUS => Some(Self::BUS), - c::SIGFPE => Some(Self::FPE), - c::SIGKILL => Some(Self::KILL), - #[cfg(not(target_os = "vita"))] - c::SIGUSR1 => Some(Self::USR1), - c::SIGSEGV => Some(Self::SEGV), - #[cfg(not(target_os = "vita"))] - c::SIGUSR2 => Some(Self::USR2), - c::SIGPIPE => Some(Self::PIPE), - c::SIGALRM => Some(Self::ALARM), - c::SIGTERM => Some(Self::TERM), - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "vita", - all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ), - ) - )))] - c::SIGSTKFLT => Some(Self::STKFLT), - #[cfg(not(target_os = "vita"))] - c::SIGCHLD => Some(Self::CHILD), - #[cfg(not(target_os = "vita"))] - c::SIGCONT => Some(Self::CONT), - #[cfg(not(target_os = "vita"))] - c::SIGSTOP => Some(Self::STOP), - #[cfg(not(target_os = "vita"))] - c::SIGTSTP => Some(Self::TSTP), - #[cfg(not(target_os = "vita"))] - c::SIGTTIN => Some(Self::TTIN), - #[cfg(not(target_os = "vita"))] - c::SIGTTOU => Some(Self::TTOU), - #[cfg(not(target_os = "vita"))] - c::SIGURG => Some(Self::URG), - #[cfg(not(target_os = "vita"))] - c::SIGXCPU => Some(Self::XCPU), - #[cfg(not(target_os = "vita"))] - c::SIGXFSZ => Some(Self::XFSZ), - #[cfg(not(target_os = "vita"))] - c::SIGVTALRM => Some(Self::VTALARM), - #[cfg(not(target_os = "vita"))] - c::SIGPROF => Some(Self::PROF), - #[cfg(not(target_os = "vita"))] - c::SIGWINCH => Some(Self::WINCH), - #[cfg(not(any(target_os = "haiku", target_os = "vita")))] - c::SIGIO => Some(Self::IO), - #[cfg(not(any( - bsd, - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "vita" - )))] - c::SIGPWR => Some(Self::POWER), - c::SIGSYS => Some(Self::SYS), - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "hermit", - all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ) - ) - ))] - c::SIGEMT => Some(Self::EMT), - #[cfg(bsd)] - c::SIGINFO => Some(Self::INFO), - #[cfg(target_os = "freebsd")] - c::SIGTHR => Some(Self::THR), - #[cfg(target_os = "freebsd")] - c::SIGLIBRT => Some(Self::LIBRT), - - _ => None, - } - } -} - -impl fmt::Debug for Signal { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - Self::HUP => "Signal::HUP".fmt(f), - Self::INT => "Signal::INT".fmt(f), - Self::QUIT => "Signal::QUIT".fmt(f), - Self::ILL => "Signal::ILL".fmt(f), - Self::TRAP => "Signal::TRAP".fmt(f), - Self::ABORT => "Signal::ABORT".fmt(f), - Self::BUS => "Signal::BUS".fmt(f), - Self::FPE => "Signal::FPE".fmt(f), - Self::KILL => "Signal::KILL".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::USR1 => "Signal::USR1".fmt(f), - Self::SEGV => "Signal::SEGV".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::USR2 => "Signal::USR2".fmt(f), - Self::PIPE => "Signal::PIPE".fmt(f), - Self::ALARM => "Signal::ALARM".fmt(f), - Self::TERM => "Signal::TERM".fmt(f), - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "nto", - target_os = "vita", - all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ), - ), - )))] - Self::STKFLT => "Signal::STKFLT".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::CHILD => "Signal::CHILD".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::CONT => "Signal::CONT".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::STOP => "Signal::STOP".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::TSTP => "Signal::TSTP".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::TTIN => "Signal::TTIN".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::TTOU => "Signal::TTOU".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::URG => "Signal::URG".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::XCPU => "Signal::XCPU".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::XFSZ => "Signal::XFSZ".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::VTALARM => "Signal::VTALARM".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::PROF => "Signal::PROF".fmt(f), - #[cfg(not(target_os = "vita"))] - Self::WINCH => "Signal::WINCH".fmt(f), - #[cfg(not(any(target_os = "haiku", target_os = "vita")))] - Self::IO => "Signal::IO".fmt(f), - #[cfg(not(any( - bsd, - target_os = "haiku", - target_os = "horizon", - target_os = "hurd", - target_os = "vita" - )))] - Self::POWER => "Signal::POWER".fmt(f), - Self::SYS => "Signal::SYS".fmt(f), - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "hermit", - all( - linux_kernel, - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ) - ) - ))] - Self::EMT => "Signal::EMT".fmt(f), - #[cfg(bsd)] - Self::INFO => "Signal::INFO".fmt(f), - #[cfg(target_os = "freebsd")] - Self::THR => "Signal::THR".fmt(f), - #[cfg(target_os = "freebsd")] - Self::LIBRT => "Signal::LIBRT".fmt(f), - - n => { - "Signal::from_raw(".fmt(f)?; - n.as_raw().fmt(f)?; - ")".fmt(f) - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_basics() { - assert_eq!(Signal::HUP.as_raw(), libc::SIGHUP); - unsafe { - assert_eq!(Signal::from_raw_unchecked(libc::SIGHUP), Signal::HUP); - assert_eq!( - Signal::from_raw_nonzero_unchecked(NonZeroI32::new(libc::SIGHUP).unwrap()), - Signal::HUP - ); - } - } - - #[test] - fn test_named() { - assert_eq!(Signal::from_named_raw(-1), None); - assert_eq!(Signal::from_named_raw(0), None); - assert_eq!(Signal::from_named_raw(c::SIGHUP), Some(Signal::HUP)); - assert_eq!(Signal::from_named_raw(c::SIGSEGV), Some(Signal::SEGV)); - assert_eq!(Signal::from_named_raw(c::SIGSYS), Some(Signal::SYS)); - #[cfg(any(linux_like, solarish, target_os = "hurd"))] - { - assert_eq!(Signal::from_named_raw(libc::SIGRTMIN()), None); - assert_eq!(Signal::from_named_raw(libc::SIGRTMAX()), None); - } - } -} diff --git a/vendor/rustix/src/static_assertions.rs b/vendor/rustix/src/static_assertions.rs deleted file mode 100644 index 3d071181..00000000 --- a/vendor/rustix/src/static_assertions.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! Workarounds for Rust 1.63 where some things in the `static_assertions` -//! crate do things that don't work in const contexts. We want to call them in -//! const contexts in Rust versions where that's supported so that problems are -//! caught at compile time, and fall back to dynamic asserts in Rust 1.63. - -#![allow(unused_macros)] - -macro_rules! assert_eq_size { - ($x:ty, $y:ty) => { - assert_eq!(core::mem::size_of::<$x>(), core::mem::size_of::<$y>()); - }; -} - -macro_rules! assert_eq_align { - ($x:ty, $y:ty) => { - assert_eq!(core::mem::align_of::<$x>(), core::mem::align_of::<$y>()); - }; -} - -macro_rules! const_assert_eq { - ($x:expr, $y:expr) => { - assert_eq!($x, $y); - }; -} - -macro_rules! const_assert_ne { - ($x:expr, $y:expr) => { - assert_ne!($x, $y); - }; -} - -macro_rules! const_assert { - ($x:expr) => { - assert!($x); - }; -} diff --git a/vendor/rustix/src/stdio.rs b/vendor/rustix/src/stdio.rs deleted file mode 100644 index e5ea0d4f..00000000 --- a/vendor/rustix/src/stdio.rs +++ /dev/null @@ -1,523 +0,0 @@ -//! Functions returning the stdio file descriptors. -//! -//! # Safety -//! -//! Some of the functions in this module can cause the process' stdio file -//! descriptors to be closed, which breaks the assumption made in Rust's std -//! that these file descriptors are always open. -//! -//! And in no-std mode, some of the functions in this module similarly assume -//! that the process' stdio file descriptors are open, which we don't take as -//! given in no-std mode because we don't have std also making that assumption. -//! -//! See the individual functions' safety comments for more details. -#![allow(unsafe_code)] - -use crate::backend; -use crate::fd::OwnedFd; -use backend::c; -use backend::fd::{BorrowedFd, FromRawFd as _, RawFd}; - -#[cfg(not(any(windows, target_os = "wasi")))] -use { - crate::io, - backend::fd::{AsFd, AsRawFd as _}, - core::mem::ManuallyDrop, -}; - -/// `STDIN_FILENO`—Standard input, borrowed. -/// -/// In `std`-using configurations, this is a safe function, because the -/// standard library already assumes that the stdin file descriptor is always -/// valid. In `no_std` configurations, it is `unsafe`. -/// -/// # Warning -/// -/// This function allows reading directly from stdin without coordinating -/// with the buffering performed by [`std::io::Stdin`], so it could cause -/// corrupted input. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdin.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdin&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdin.4 -/// [OpenBSD]: https://man.openbsd.org/stdin.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdin§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdin -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdin -#[cfg(feature = "std")] -#[doc(alias = "STDIN_FILENO")] -#[inline] -pub const fn stdin() -> BorrowedFd<'static> { - // SAFETY: When "std" is enabled, the standard library assumes that the - // stdio file descriptors are all valid. - unsafe { BorrowedFd::borrow_raw(c::STDIN_FILENO as RawFd) } -} - -/// `STDIN_FILENO`—Standard input, borrowed. -/// -/// In `std`-using configurations, this is a safe function, because the -/// standard library already assumes that the stdin file descriptor is always -/// valid. In `no_std` configurations, it is `unsafe`. -/// -/// # Safety -/// -/// In `no_std` configurations, the process' stdin file descriptor can be -/// closed, potentially on other threads, in which case the file descriptor -/// index number (`STDIN_FILENO`) could be dynamically reused for other -/// purposes, potentially on different threads. -/// -/// # Warning -/// -/// This function allows reading directly from stdin without coordinating -/// with the buffering performed by [`std::io::Stdin`], so it could cause -/// corrupted input. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdin.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdin&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdin.4 -/// [OpenBSD]: https://man.openbsd.org/stdin.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdin§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdin -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdin -#[cfg(not(feature = "std"))] -#[doc(alias = "STDIN_FILENO")] -#[inline] -pub const unsafe fn stdin() -> BorrowedFd<'static> { - BorrowedFd::borrow_raw(c::STDIN_FILENO as RawFd) -} - -/// `STDIN_FILENO`—Standard input, owned. -/// -/// This is similar to [`stdin`], however it returns an `OwnedFd` which closes -/// standard input when it is dropped. -/// -/// # Safety -/// -/// Safe `std`-using Rust code is permitted to assume that the stdin file -/// descriptor is always valid. This function returns an `OwnedFd` which will -/// close the stdin file descriptor when dropped. -/// -/// # Warning -/// -/// This has the same hazards as [`stdin`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdin.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdin&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdin.4 -/// [OpenBSD]: https://man.openbsd.org/stdin.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdin§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdin -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdin -#[doc(alias = "STDIN_FILENO")] -#[inline] -pub unsafe fn take_stdin() -> OwnedFd { - backend::fd::OwnedFd::from_raw_fd(c::STDIN_FILENO as RawFd) -} - -/// `STDOUT_FILENO`—Standard output, borrowed. -/// -/// In `std`-using configurations, this is a safe function, because the -/// standard library already assumes that the stdout file descriptor is always -/// valid. In `no_std` configurations, it is `unsafe`. -/// -/// # Warning -/// -/// This function allows writing directly to stdout without coordinating -/// with the buffering performed by [`std::io::Stdout`], so it could cause -/// corrupted output. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdout.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdout&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdout.4 -/// [OpenBSD]: https://man.openbsd.org/stdout.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdout§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdout -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdout -#[cfg(feature = "std")] -#[doc(alias = "STDOUT_FILENO")] -#[inline] -pub const fn stdout() -> BorrowedFd<'static> { - // SAFETY: When "std" is enabled, the standard library assumes that the - // stdio file descriptors are all valid. - unsafe { BorrowedFd::borrow_raw(c::STDOUT_FILENO as RawFd) } -} - -/// `STDOUT_FILENO`—Standard output, borrowed. -/// -/// In `std`-using configurations, this is a safe function, because the -/// standard library already assumes that the stdout file descriptor is always -/// valid. In `no_std` configurations, it is `unsafe`. -/// -/// # Safety -/// -/// In `no_std` configurations, the process' stdout file descriptor can be -/// closed, potentially on other threads, in which case the file descriptor -/// index number (`STDOUT_FILENO`) could be dynamically reused for other -/// purposes, potentially on different threads. -/// -/// # Warning -/// -/// This function allows writing directly to stdout without coordinating -/// with the buffering performed by [`std::io::Stdout`], so it could cause -/// corrupted output. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdout.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdout&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdout.4 -/// [OpenBSD]: https://man.openbsd.org/stdout.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdout§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdout -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdout -#[cfg(not(feature = "std"))] -#[doc(alias = "STDOUT_FILENO")] -#[inline] -pub const unsafe fn stdout() -> BorrowedFd<'static> { - BorrowedFd::borrow_raw(c::STDOUT_FILENO as RawFd) -} - -/// `STDOUT_FILENO`—Standard output, owned. -/// -/// This is similar to [`stdout`], however it returns an `OwnedFd` which closes -/// standard output when it is dropped. -/// -/// # Safety -/// -/// Safe `std`-using Rust code is permitted to assume that the stdout file -/// descriptor is always valid. This function returns an `OwnedFd` which will -/// close the stdout file descriptor when dropped. -/// -/// # Warning -/// -/// This has the same hazards as [`stdout`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdout.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdout&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdout.4 -/// [OpenBSD]: https://man.openbsd.org/stdout.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdout§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdout -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdout -#[doc(alias = "STDOUT_FILENO")] -#[inline] -pub unsafe fn take_stdout() -> OwnedFd { - backend::fd::OwnedFd::from_raw_fd(c::STDOUT_FILENO as RawFd) -} - -/// `STDERR_FILENO`—Standard error, borrowed. -/// -/// In `std`-using configurations, this is a safe function, because the -/// standard library already assumes that the stderr file descriptor is always -/// valid. In `no_std` configurations, it is `unsafe`. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stderr.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stderr&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stderr.4 -/// [OpenBSD]: https://man.openbsd.org/stderr.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stderr§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stderr -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stderr -#[cfg(feature = "std")] -#[doc(alias = "STDERR_FILENO")] -#[inline] -pub const fn stderr() -> BorrowedFd<'static> { - // SAFETY: When "std" is enabled, the standard library assumes that the - // stdio file descriptors are all valid. - unsafe { BorrowedFd::borrow_raw(c::STDERR_FILENO as RawFd) } -} - -/// `STDERR_FILENO`—Standard error, borrowed. -/// -/// In `std`-using configurations, this is a safe function, because the -/// standard library already assumes that the stderr file descriptor is always -/// valid. In `no_std` configurations, it is `unsafe`. -/// -/// # Safety -/// -/// In `no_std` configurations, the process' stderr file descriptor can be -/// closed, potentially on other threads, in which case the file descriptor -/// index number (`STDERR_FILENO`) could be dynamically reused for other -/// purposes, potentially on different threads. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stderr.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stderr&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stderr.4 -/// [OpenBSD]: https://man.openbsd.org/stderr.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stderr§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stderr -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stderr -#[cfg(not(feature = "std"))] -#[doc(alias = "STDERR_FILENO")] -#[inline] -pub const unsafe fn stderr() -> BorrowedFd<'static> { - BorrowedFd::borrow_raw(c::STDERR_FILENO as RawFd) -} - -/// `STDERR_FILENO`—Standard error, owned. -/// -/// This is similar to [`stderr`], however it returns an `OwnedFd` which closes -/// standard output when it is dropped. -/// -/// # Safety -/// -/// Safe std-using Rust code is permitted to assume that the stderr file -/// descriptor is always valid. This function returns an `OwnedFd` which will -/// close the stderr file descriptor when dropped. -/// -/// # Other hazards -/// -/// This has the same hazards as [`stderr`]. -/// -/// And, when the `OwnedFd` is dropped, subsequent newly created file -/// descriptors may unknowingly reuse the stderr file descriptor number, which -/// may break common assumptions, so it should typically only be dropped at the -/// end of a program when no more file descriptors will be created. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stderr.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stderr&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stderr.4 -/// [OpenBSD]: https://man.openbsd.org/stderr.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stderr§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stderr -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stderr -#[doc(alias = "STDERR_FILENO")] -#[inline] -pub unsafe fn take_stderr() -> OwnedFd { - backend::fd::OwnedFd::from_raw_fd(c::STDERR_FILENO as RawFd) -} - -/// `STDIN_FILENO`—Standard input, raw. -/// -/// This is similar to [`stdin`], however it returns a `RawFd`. -/// -/// # Other hazards -/// -/// This has the same hazards as [`stdin`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdin.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdin&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdin.4 -/// [OpenBSD]: https://man.openbsd.org/stdin.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdin§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdin -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdin -#[doc(alias = "STDIN_FILENO")] -#[inline] -pub const fn raw_stdin() -> RawFd { - c::STDIN_FILENO as RawFd -} - -/// `STDOUT_FILENO`—Standard output, raw. -/// -/// This is similar to [`stdout`], however it returns a `RawFd`. -/// -/// # Other hazards -/// -/// This has the same hazards as [`stdout`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdout.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stdout&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stdout.4 -/// [OpenBSD]: https://man.openbsd.org/stdout.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stdout§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stdout -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stdout -#[doc(alias = "STDOUT_FILENO")] -#[inline] -pub const fn raw_stdout() -> RawFd { - c::STDOUT_FILENO as RawFd -} - -/// `STDERR_FILENO`—Standard error, raw. -/// -/// This is similar to [`stderr`], however it returns a `RawFd`. -/// -/// # Other hazards -/// -/// This has the same hazards as [`stderr`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stderr.html -/// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=stderr&sektion=4 -/// [NetBSD]: https://man.netbsd.org/stderr.4 -/// [OpenBSD]: https://man.openbsd.org/stderr.4 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=stderr§ion=4 -/// [illumos]: https://illumos.org/man/4FS/stderr -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Standard-Streams.html#index-stderr -#[doc(alias = "STDERR_FILENO")] -#[inline] -pub const fn raw_stderr() -> RawFd { - c::STDERR_FILENO as RawFd -} - -/// Utility function to safely `dup2` over stdin (fd 0). -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub fn dup2_stdin<Fd: AsFd>(fd: Fd) -> io::Result<()> { - let fd = fd.as_fd(); - if fd.as_raw_fd() != c::STDIN_FILENO { - // SAFETY: We wrap the returned `OwnedFd` to `ManuallyDrop` so that it - // isn't dropped. - let mut target = ManuallyDrop::new(unsafe { take_stdin() }); - backend::io::syscalls::dup2(fd, &mut target)?; - } - Ok(()) -} - -/// Utility function to safely `dup2` over stdout (fd 1). -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub fn dup2_stdout<Fd: AsFd>(fd: Fd) -> io::Result<()> { - let fd = fd.as_fd(); - if fd.as_raw_fd() != c::STDOUT_FILENO { - // SAFETY: We wrap the returned `OwnedFd` to `ManuallyDrop` so that it - // isn't dropped. - let mut target = ManuallyDrop::new(unsafe { take_stdout() }); - backend::io::syscalls::dup2(fd, &mut target)?; - } - Ok(()) -} - -/// Utility function to safely `dup2` over stderr (fd 2). -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -pub fn dup2_stderr<Fd: AsFd>(fd: Fd) -> io::Result<()> { - let fd = fd.as_fd(); - if fd.as_raw_fd() != c::STDERR_FILENO { - // SAFETY: We wrap the returned `OwnedFd` to `ManuallyDrop` so that it - // isn't dropped. - let mut target = ManuallyDrop::new(unsafe { take_stderr() }); - backend::io::syscalls::dup2(fd, &mut target)?; - } - Ok(()) -} diff --git a/vendor/rustix/src/system.rs b/vendor/rustix/src/system.rs deleted file mode 100644 index 70204aef..00000000 --- a/vendor/rustix/src/system.rs +++ /dev/null @@ -1,317 +0,0 @@ -//! Uname and other system-level functions. - -#![allow(unsafe_code)] - -use crate::backend; -#[cfg(target_os = "linux")] -use crate::backend::c; -use crate::ffi::CStr; -#[cfg(not(any(target_os = "espidf", target_os = "emscripten", target_os = "vita")))] -use crate::io; -use core::fmt; - -#[cfg(linux_kernel)] -pub use backend::system::types::Sysinfo; - -#[cfg(linux_kernel)] -use crate::fd::AsFd; -#[cfg(linux_kernel)] -use crate::ffi::c_int; - -/// `uname()`—Returns high-level information about the runtime OS and -/// hardware. -/// -/// For `gethostname()`, use [`Uname::nodename`] on the result. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// - [NetBSD] -/// - [FreeBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// - [glibc] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/uname.html -/// [Linux]: https://man7.org/linux/man-pages/man2/uname.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/uname.3.html -/// [NetBSD]: https://man.netbsd.org/uname.3 -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=uname&sektion=3 -/// [OpenBSD]: https://man.openbsd.org/uname.3 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=uname§ion=3 -/// [illumos]: https://illumos.org/man/2/uname -/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Platform-Type.html -#[doc(alias = "gethostname")] -#[inline] -pub fn uname() -> Uname { - Uname(backend::system::syscalls::uname()) -} - -/// `struct utsname`—Return type for [`uname`]. -#[doc(alias = "utsname")] -pub struct Uname(backend::system::types::RawUname); - -impl Uname { - /// `sysname`—Operating system release name. - #[inline] - pub fn sysname(&self) -> &CStr { - Self::to_cstr(self.0.sysname.as_ptr().cast()) - } - - /// `nodename`—Name with vague meaning. - /// - /// This is intended to be a network name, however it's unable to convey - /// information about hosts that have multiple names, or any information - /// about where the names are visible. - /// - /// This corresponds to the `gethostname` value. - #[inline] - pub fn nodename(&self) -> &CStr { - Self::to_cstr(self.0.nodename.as_ptr().cast()) - } - - /// `release`—Operating system release version string. - #[inline] - pub fn release(&self) -> &CStr { - Self::to_cstr(self.0.release.as_ptr().cast()) - } - - /// `version`—Operating system build identifiers. - #[inline] - pub fn version(&self) -> &CStr { - Self::to_cstr(self.0.version.as_ptr().cast()) - } - - /// `machine`—Hardware architecture identifier. - #[inline] - pub fn machine(&self) -> &CStr { - Self::to_cstr(self.0.machine.as_ptr().cast()) - } - - /// `domainname`—NIS or YP domain identifier. - #[cfg(linux_kernel)] - #[inline] - pub fn domainname(&self) -> &CStr { - Self::to_cstr(self.0.domainname.as_ptr().cast()) - } - - #[inline] - fn to_cstr<'a>(ptr: *const u8) -> &'a CStr { - // SAFETY: Strings returned from the kernel are always NUL-terminated. - unsafe { CStr::from_ptr(ptr.cast()) } - } -} - -impl fmt::Debug for Uname { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(not(linux_kernel))] - { - write!( - f, - "{:?} {:?} {:?} {:?} {:?}", - self.sysname(), - self.nodename(), - self.release(), - self.version(), - self.machine(), - ) - } - #[cfg(linux_kernel)] - { - write!( - f, - "{:?} {:?} {:?} {:?} {:?} {:?}", - self.sysname(), - self.nodename(), - self.release(), - self.version(), - self.machine(), - self.domainname(), - ) - } - } -} - -/// `sysinfo()`—Returns status information about the runtime OS. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/uname.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn sysinfo() -> Sysinfo { - backend::system::syscalls::sysinfo() -} - -/// `sethostname(name)`—Sets the system host name. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sethostname.2.html -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -#[inline] -pub fn sethostname(name: &[u8]) -> io::Result<()> { - backend::system::syscalls::sethostname(name) -} - -/// `setdomain(name)`—Sets the system NIS domain name. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setdomainname.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setdomainname&sektion=3 -#[cfg(not(any( - target_os = "cygwin", - target_os = "emscripten", - target_os = "espidf", - target_os = "haiku", - target_os = "horizon", - target_os = "illumos", - target_os = "redox", - target_os = "solaris", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub fn setdomainname(name: &[u8]) -> io::Result<()> { - backend::system::syscalls::setdomainname(name) -} - -/// Reboot command for use with [`reboot`]. -#[cfg(target_os = "linux")] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -#[non_exhaustive] -pub enum RebootCommand { - /// Disables the Ctrl-Alt-Del keystroke. - /// - /// When disabled, the keystroke will send a [`Signal::INT`] to - /// [`Pid::INIT`]. - /// - /// [`Signal::INT`]: crate::process::Signal::INT - /// [`Pid::INIT`]: crate::process::Pid::INIT - CadOff = c::LINUX_REBOOT_CMD_CAD_OFF, - /// Enables the Ctrl-Alt-Del keystroke. - /// - /// When enabled, the keystroke will trigger a [`Restart`]. - /// - /// [`Restart`]: Self::Restart - CadOn = c::LINUX_REBOOT_CMD_CAD_ON, - /// Prints the message "System halted" and halts the system - Halt = c::LINUX_REBOOT_CMD_HALT, - /// Execute a kernel that has been loaded earlier with [`kexec_load`]. - /// - /// [`kexec_load`]: https://man7.org/linux/man-pages/man2/kexec_load.2.html - Kexec = c::LINUX_REBOOT_CMD_KEXEC, - /// Prints the message "Power down.", stops the system, and tries to remove - /// all power - PowerOff = c::LINUX_REBOOT_CMD_POWER_OFF, - /// Prints the message "Restarting system." and triggers a restart - Restart = c::LINUX_REBOOT_CMD_RESTART, - /// Hibernate the system by suspending to disk - SwSuspend = c::LINUX_REBOOT_CMD_SW_SUSPEND, -} - -/// `reboot`—Reboot the system or enable/disable Ctrl-Alt-Del. -/// -/// The reboot syscall, despite the name, can actually do much more than -/// reboot. -/// -/// Among other things, it can: -/// - Restart, Halt, Power Off, and Suspend the system -/// - Enable and disable the Ctrl-Alt-Del keystroke -/// - Execute other kernels -/// - Terminate init inside PID namespaces -/// -/// It is highly recommended to carefully read the kernel documentation before -/// calling this function. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/reboot.2.html -#[cfg(target_os = "linux")] -pub fn reboot(cmd: RebootCommand) -> io::Result<()> { - backend::system::syscalls::reboot(cmd) -} - -/// `init_module`—Load a kernel module. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/init_module.2.html -#[inline] -#[cfg(linux_kernel)] -pub fn init_module(image: &[u8], param_values: &CStr) -> io::Result<()> { - backend::system::syscalls::init_module(image, param_values) -} - -/// `finit_module`—Load a kernel module from a file descriptor. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/finit_module.2.html -#[inline] -#[cfg(linux_kernel)] -pub fn finit_module<Fd: AsFd>(fd: Fd, param_values: &CStr, flags: c_int) -> io::Result<()> { - backend::system::syscalls::finit_module(fd.as_fd(), param_values, flags) -} - -/// `delete_module`—Unload a kernel module. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/delete_module.2.html -#[inline] -#[cfg(linux_kernel)] -pub fn delete_module(name: &CStr, flags: c_int) -> io::Result<()> { - backend::system::syscalls::delete_module(name, flags) -} - -#[cfg(test)] -mod tests { - #[allow(unused_imports)] - use super::*; - #[allow(unused_imports)] - use crate::backend::c; - - #[cfg(linux_kernel)] - #[test] - fn test_sysinfo_layouts() { - // Don't assert the size for `Sysinfo` because `c::sysinfo` has a - // computed-size padding field at the end that bindgen doesn't support, - // and `c::sysinfo` may add fields over time. - assert_eq!( - core::mem::align_of::<Sysinfo>(), - core::mem::align_of::<c::sysinfo>() - ); - check_renamed_struct_field!(Sysinfo, sysinfo, uptime); - check_renamed_struct_field!(Sysinfo, sysinfo, loads); - check_renamed_struct_field!(Sysinfo, sysinfo, totalram); - check_renamed_struct_field!(Sysinfo, sysinfo, freeram); - check_renamed_struct_field!(Sysinfo, sysinfo, sharedram); - check_renamed_struct_field!(Sysinfo, sysinfo, bufferram); - check_renamed_struct_field!(Sysinfo, sysinfo, totalswap); - check_renamed_struct_field!(Sysinfo, sysinfo, freeswap); - check_renamed_struct_field!(Sysinfo, sysinfo, procs); - check_renamed_struct_field!(Sysinfo, sysinfo, totalhigh); - check_renamed_struct_field!(Sysinfo, sysinfo, freehigh); - check_renamed_struct_field!(Sysinfo, sysinfo, mem_unit); - } -} diff --git a/vendor/rustix/src/termios/ioctl.rs b/vendor/rustix/src/termios/ioctl.rs deleted file mode 100644 index 22945566..00000000 --- a/vendor/rustix/src/termios/ioctl.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! Terminal-related `ioctl` functions. - -#![allow(unsafe_code)] - -use crate::fd::AsFd; -use crate::{backend, io, ioctl}; -use backend::c; - -/// `ioctl(fd, TIOCEXCL)`—Enables exclusive mode on a terminal. -/// -/// In exclusive mode, subsequent unprivileged `open` calls on the terminal -/// device fail with [`io::Errno::BUSY`]. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=tty&sektion=4 -/// [NetBSD]: https://man.netbsd.org/tty.4 -/// [OpenBSD]: https://man.openbsd.org/tty.4 -#[cfg(not(any( - windows, - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -#[inline] -#[doc(alias = "TIOCEXCL")] -pub fn ioctl_tiocexcl<Fd: AsFd>(fd: Fd) -> io::Result<()> { - // SAFETY: `TIOCEXCL` is a no-argument setter opcode. - unsafe { - let ctl = ioctl::NoArg::<{ c::TIOCEXCL as _ }>::new(); - ioctl::ioctl(fd, ctl) - } -} - -/// `ioctl(fd, TIOCNXCL)`—Disables exclusive mode on a terminal. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=tty&sektion=4 -/// [NetBSD]: https://man.netbsd.org/tty.4 -/// [OpenBSD]: https://man.openbsd.org/tty.4 -#[cfg(not(any( - windows, - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -#[inline] -#[doc(alias = "TIOCNXCL")] -pub fn ioctl_tiocnxcl<Fd: AsFd>(fd: Fd) -> io::Result<()> { - // SAFETY: `TIOCNXCL` is a no-argument setter opcode. - unsafe { - let ctl = ioctl::NoArg::<{ c::TIOCNXCL as _ }>::new(); - ioctl::ioctl(fd, ctl) - } -} diff --git a/vendor/rustix/src/termios/mod.rs b/vendor/rustix/src/termios/mod.rs deleted file mode 100644 index 98efb9b3..00000000 --- a/vendor/rustix/src/termios/mod.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Terminal I/O stream operations. -//! -//! This API automatically supports setting arbitrary I/O speeds, on any -//! platform that supports them, including Linux and the BSDs. -//! -//! The [`speed`] module contains various predefined speed constants which are -//! more likely to be portable, however any `u32` value can be passed to -//! [`Termios::set_speed`], [`Termios::set_input_speed`], and -//! [`Termios::set_output_speed`], and they will simply fail if the speed is -//! not supported by the platform or the device. - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "wasi", -)))] -mod ioctl; -#[cfg(not(target_os = "wasi"))] -mod tc; -#[cfg(not(windows))] -mod tty; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -mod types; - -#[cfg(not(any( - target_os = "cygwin", - target_os = "espidf", - target_os = "haiku", - target_os = "wasi", -)))] -pub use ioctl::*; -#[cfg(not(target_os = "wasi"))] -pub use tc::*; -#[cfg(not(windows))] -pub use tty::*; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub use types::*; diff --git a/vendor/rustix/src/termios/tc.rs b/vendor/rustix/src/termios/tc.rs deleted file mode 100644 index dabd17eb..00000000 --- a/vendor/rustix/src/termios/tc.rs +++ /dev/null @@ -1,225 +0,0 @@ -use crate::fd::AsFd; -#[cfg(not(target_os = "espidf"))] -use crate::termios::{Action, OptionalActions, QueueSelector, Termios, Winsize}; -use crate::{backend, io}; - -pub use crate::pid::Pid; - -/// `tcgetattr(fd)`—Get terminal attributes. -/// -/// Also known as the `TCGETS` (or `TCGETS2` on Linux) operation with `ioctl`. -/// -/// On Linux, this uses `TCGETS2`. If that fails in a way that indicates that -/// the host doesn't support it, this falls back to the old `TCGETS`, manually -/// initializes the fields that `TCGETS` doesn't initialize, and fails with -/// `io::Errno::RANGE` if the input or output speeds cannot be supported. -/// -/// # References -/// - [POSIX `tcgetattr`] -/// - [Linux `ioctl_tty`] -/// - [Linux `termios`] -/// -/// [POSIX `tcgetattr`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetattr.html -/// [Linux `ioctl_tty`]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html -#[cfg(not(any(windows, target_os = "espidf", target_os = "wasi")))] -#[inline] -#[doc(alias = "TCGETS")] -#[doc(alias = "TCGETS2")] -#[doc(alias = "tcgetattr2")] -pub fn tcgetattr<Fd: AsFd>(fd: Fd) -> io::Result<Termios> { - backend::termios::syscalls::tcgetattr(fd.as_fd()) -} - -/// `tcgetwinsize(fd)`—Get the current terminal window size. -/// -/// Also known as the `TIOCGWINSZ` operation with `ioctl`. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -#[cfg(not(any( - windows, - target_os = "horizon", - target_os = "espidf", - target_os = "wasi" -)))] -#[inline] -#[doc(alias = "TIOCGWINSZ")] -pub fn tcgetwinsize<Fd: AsFd>(fd: Fd) -> io::Result<Winsize> { - backend::termios::syscalls::tcgetwinsize(fd.as_fd()) -} - -/// `tcgetpgrp(fd)`—Get the terminal foreground process group. -/// -/// Also known as the `TIOCGPGRP` operation with `ioctl`. -/// -/// On Linux, if `fd` is a pseudo-terminal, the underlying system call here can -/// return a pid of 0, which rustix's `Pid` type doesn't support. So rustix -/// instead handles this case by failing with [`io::Errno::OPNOTSUPP`] if the -/// pid is 0. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetpgrp.html -/// [Linux]: https://man7.org/linux/man-pages/man3/tcgetpgrp.3.html -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -#[doc(alias = "TIOCGPGRP")] -pub fn tcgetpgrp<Fd: AsFd>(fd: Fd) -> io::Result<Pid> { - backend::termios::syscalls::tcgetpgrp(fd.as_fd()) -} - -/// `tcsetpgrp(fd, pid)`—Set the terminal foreground process group. -/// -/// Also known as the `TIOCSPGRP` operation with `ioctl`. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetpgrp.html -/// [Linux]: https://man7.org/linux/man-pages/man3/tcsetpgrp.3.html -#[cfg(not(any(windows, target_os = "wasi")))] -#[inline] -#[doc(alias = "TIOCSPGRP")] -pub fn tcsetpgrp<Fd: AsFd>(fd: Fd, pid: Pid) -> io::Result<()> { - backend::termios::syscalls::tcsetpgrp(fd.as_fd(), pid) -} - -/// `tcsetattr(fd)`—Set terminal attributes. -/// -/// Also known as the `TCSETS` (or `TCSETS2` on Linux) operation with `ioctl`. -/// -/// On Linux, this uses `TCSETS2`. If that fails in a way that indicates that -/// the host doesn't support it, this falls back to the old `TCSETS`, and fails -/// with `io::Errno::RANGE` if the input or output speeds cannot be supported. -/// -/// # References -/// - [POSIX `tcsetattr`] -/// - [Linux `ioctl_tty`] -/// - [Linux `termios`] -/// -/// [POSIX `tcsetattr`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetattr.html -/// [Linux `ioctl_tty`]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html -#[cfg(not(target_os = "espidf"))] -#[inline] -#[doc(alias = "TCSETS")] -#[doc(alias = "TCSETS2")] -#[doc(alias = "tcsetattr2")] -pub fn tcsetattr<Fd: AsFd>( - fd: Fd, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - backend::termios::syscalls::tcsetattr(fd.as_fd(), optional_actions, termios) -} - -/// `tcsendbreak(fd, 0)`—Transmit zero-valued bits. -/// -/// This transmits zero-valued bits for at least 0.25 seconds. -/// -/// This function does not have a `duration` parameter, and always uses the -/// implementation-defined value, which transmits for at least 0.25 seconds. -/// -/// Also known as the `TCSBRK` operation with `ioctl`, with a duration -/// parameter of 0. -/// -/// # References -/// - [POSIX `tcsendbreak`] -/// - [Linux `ioctl_tty`] -/// - [Linux `termios`] -/// -/// [POSIX `tcsendbreak`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsendbreak.html -/// [Linux `ioctl_tty`]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html -#[inline] -#[doc(alias = "TCSBRK")] -pub fn tcsendbreak<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::termios::syscalls::tcsendbreak(fd.as_fd()) -} - -/// `tcdrain(fd, duration)`—Wait until all pending output has been written. -/// -/// # References -/// - [POSIX `tcdrain`] -/// - [Linux `ioctl_tty`] -/// - [Linux `termios`] -/// -/// [POSIX `tcsetattr`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcdrain.html -/// [Linux `ioctl_tty`]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html -#[cfg(not(target_os = "espidf"))] -#[inline] -pub fn tcdrain<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::termios::syscalls::tcdrain(fd.as_fd()) -} - -/// `tcflush(fd, queue_selector)`—Wait until all pending output has been -/// written. -/// -/// # References -/// - [POSIX `tcflush`] -/// - [Linux `ioctl_tty`] -/// - [Linux `termios`] -/// -/// [POSIX `tcflush`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflush.html -/// [Linux `ioctl_tty`]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html -#[cfg(not(target_os = "espidf"))] -#[inline] -#[doc(alias = "TCFLSH")] -pub fn tcflush<Fd: AsFd>(fd: Fd, queue_selector: QueueSelector) -> io::Result<()> { - backend::termios::syscalls::tcflush(fd.as_fd(), queue_selector) -} - -/// `tcflow(fd, action)`—Suspend or resume transmission or reception. -/// -/// # References -/// - [POSIX `tcflow`] -/// - [Linux `ioctl_tty`] -/// - [Linux `termios`] -/// -/// [POSIX `tcflow`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflow.html -/// [Linux `ioctl_tty`]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html -#[cfg(not(target_os = "espidf"))] -#[inline] -#[doc(alias = "TCXONC")] -pub fn tcflow<Fd: AsFd>(fd: Fd, action: Action) -> io::Result<()> { - backend::termios::syscalls::tcflow(fd.as_fd(), action) -} - -/// `tcgetsid(fd)`—Return the session ID of the current session with `fd` as -/// its controlling terminal. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetsid.html -/// [Linux]: https://man7.org/linux/man-pages/man3/tcgetsid.3.html -#[inline] -#[doc(alias = "TIOCGSID")] -pub fn tcgetsid<Fd: AsFd>(fd: Fd) -> io::Result<Pid> { - backend::termios::syscalls::tcgetsid(fd.as_fd()) -} - -/// `tcsetwinsize(fd)`—Set the current terminal window size. -/// -/// Also known as the `TIOCSWINSZ` operation with `ioctl`. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "TIOCSWINSZ")] -pub fn tcsetwinsize<Fd: AsFd>(fd: Fd, winsize: Winsize) -> io::Result<()> { - backend::termios::syscalls::tcsetwinsize(fd.as_fd(), winsize) -} diff --git a/vendor/rustix/src/termios/tty.rs b/vendor/rustix/src/termios/tty.rs deleted file mode 100644 index 000ec8ba..00000000 --- a/vendor/rustix/src/termios/tty.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! Functions which operate on file descriptors which might be terminals. - -use crate::backend; -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::path::SMALL_PATH_BUFFER_SIZE; -use backend::fd::AsFd; -#[cfg(feature = "alloc")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use {crate::ffi::CString, crate::io, alloc::vec::Vec, backend::fd::BorrowedFd}; - -/// `isatty(fd)`—Tests whether a file descriptor refers to a terminal. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/isatty.html -/// [Linux]: https://man7.org/linux/man-pages/man3/isatty.3.html -#[inline] -pub fn isatty<Fd: AsFd>(fd: Fd) -> bool { - backend::termios::syscalls::isatty(fd.as_fd()) -} - -/// `ttyname_r(fd)`—Returns the name of the tty open on `fd`. -/// -/// If `reuse` already has available capacity, reuse it if possible. -/// -/// On Linux, this function depends on procfs being mounted on /proc. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/ttyname.html -/// [Linux]: https://man7.org/linux/man-pages/man3/ttyname.3.html -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -#[doc(alias = "ttyname_r")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -#[inline] -pub fn ttyname<Fd: AsFd, B: Into<Vec<u8>>>(fd: Fd, reuse: B) -> io::Result<CString> { - _ttyname(fd.as_fd(), reuse.into()) -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -#[allow(unsafe_code)] -fn _ttyname(fd: BorrowedFd<'_>, mut buffer: Vec<u8>) -> io::Result<CString> { - buffer.clear(); - buffer.reserve(SMALL_PATH_BUFFER_SIZE); - - loop { - match backend::termios::syscalls::ttyname(fd, buffer.spare_capacity_mut()) { - Err(io::Errno::RANGE) => { - // Use `Vec` reallocation strategy to grow capacity - // exponentially. - buffer.reserve(buffer.capacity() + 1); - } - Ok(len) => { - // SAFETY: Assume the backend returns the length of the string - // excluding the NUL. - unsafe { - buffer.set_len(len + 1); - } - - // SAFETY: - // - “ttyname_r stores this pathname in the buffer buf” - // - [POSIX definition 3.271: Pathname]: “A string that is - // used to identify a file.” - // - [POSIX definition 3.375: String]: “A contiguous sequence - // of bytes terminated by and including the first null byte.” - // - // Thus, there will be a single NUL byte at the end of the - // string. - // - // [POSIX definition 3.271: Pathname]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_271 - // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_375 - unsafe { - return Ok(CString::from_vec_with_nul_unchecked(buffer)); - } - } - Err(errno) => return Err(errno), - } - } -} diff --git a/vendor/rustix/src/termios/types.rs b/vendor/rustix/src/termios/types.rs deleted file mode 100644 index d9589087..00000000 --- a/vendor/rustix/src/termios/types.rs +++ /dev/null @@ -1,1654 +0,0 @@ -use crate::backend::c; -use crate::backend::termios::types; -#[cfg(target_os = "nto")] -use crate::ffi; -use crate::{backend, io}; -use bitflags::bitflags; - -/// `struct termios` for use with [`tcgetattr`] and [`tcsetattr`]. -/// -/// [`tcgetattr`]: crate::termios::tcgetattr -/// [`tcsetattr`]: crate::termios::tcsetattr -#[repr(C)] -#[derive(Clone)] -pub struct Termios { - /// How is input interpreted? - #[doc(alias = "c_iflag")] - pub input_modes: InputModes, - - /// How is output translated? - #[doc(alias = "c_oflag")] - pub output_modes: OutputModes, - - /// Low-level configuration flags. - #[doc(alias = "c_cflag")] - pub control_modes: ControlModes, - - /// High-level configuration flags. - #[doc(alias = "c_lflag")] - pub local_modes: LocalModes, - - /// Line discipline. - #[doc(alias = "c_line")] - #[cfg(not(all(linux_raw, any(target_arch = "powerpc", target_arch = "powerpc64"))))] - #[cfg(any( - linux_like, - target_env = "newlib", - target_os = "fuchsia", - target_os = "haiku", - target_os = "redox" - ))] - pub line_discipline: u8, - - /// How are various special control codes handled? - #[doc(alias = "c_cc")] - #[cfg(not(target_os = "haiku"))] - pub special_codes: SpecialCodes, - - #[cfg(target_os = "nto")] - pub(crate) __reserved: [ffi::c_uint; 3], - - /// Line discipline. - // On PowerPC, this field comes after `c_cc`. - #[doc(alias = "c_line")] - #[cfg(all(linux_raw, any(target_arch = "powerpc", target_arch = "powerpc64")))] - pub line_discipline: c::cc_t, - - /// See the `input_speed` and `set_input_seed` functions. - /// - /// On Linux and BSDs, this is the arbitrary integer speed value. On all - /// other platforms, this is the encoded speed value. - #[cfg(not(any(solarish, all(libc, target_env = "newlib"), target_os = "aix")))] - pub(crate) input_speed: c::speed_t, - - /// See the `output_speed` and `set_output_seed` functions. - /// - /// On Linux and BSDs, this is the integer speed value. On all other - /// platforms, this is the encoded speed value. - #[cfg(not(any(solarish, all(libc, target_env = "newlib"), target_os = "aix")))] - pub(crate) output_speed: c::speed_t, - - /// How are various special control codes handled? - #[doc(alias = "c_cc")] - #[cfg(target_os = "haiku")] - pub special_codes: SpecialCodes, -} - -impl Termios { - /// `cfmakeraw(self)`—Set a `Termios` value to the settings for “raw” mode. - /// - /// In raw mode, input is available a byte at a time, echoing is disabled, - /// and special terminal input and output codes are disabled. - #[cfg(not(target_os = "nto"))] - #[doc(alias = "cfmakeraw")] - #[inline] - pub fn make_raw(&mut self) { - backend::termios::syscalls::cfmakeraw(self) - } - - /// Return the input communication speed. - /// - /// Unlike the `c_ispeed` field in glibc and others, this returns the - /// integer value of the speed, rather than the `B*` encoded constant - /// value. - #[doc(alias = "c_ispeed")] - #[doc(alias = "cfgetispeed")] - #[doc(alias = "cfgetspeed")] - #[inline] - pub fn input_speed(&self) -> u32 { - // On Linux and BSDs, `input_speed` is the arbitrary integer speed. - #[cfg(any(linux_kernel, bsd))] - { - debug_assert!(u32::try_from(self.input_speed).is_ok()); - self.input_speed as u32 - } - - // On illumos, `input_speed` is not present. - #[cfg(any(solarish, all(libc, target_env = "newlib"), target_os = "aix"))] - unsafe { - speed::decode(c::cfgetispeed(crate::utils::as_ptr(self).cast())).unwrap() - } - - // On other platforms, it's the encoded speed. - #[cfg(not(any( - linux_kernel, - bsd, - solarish, - all(libc, target_env = "newlib"), - target_os = "aix" - )))] - { - speed::decode(self.input_speed).unwrap() - } - } - - /// Return the output communication speed. - /// - /// Unlike the `c_ospeed` field in glibc and others, this returns the - /// arbitrary integer value of the speed, rather than the `B*` encoded - /// constant value. - #[inline] - pub fn output_speed(&self) -> u32 { - // On Linux and BSDs, `output_speed` is the arbitrary integer speed. - #[cfg(any(linux_kernel, bsd))] - { - debug_assert!(u32::try_from(self.output_speed).is_ok()); - self.output_speed as u32 - } - - // On illumos, `output_speed` is not present. - #[cfg(any(solarish, all(libc, target_env = "newlib"), target_os = "aix"))] - unsafe { - speed::decode(c::cfgetospeed(crate::utils::as_ptr(self).cast())).unwrap() - } - - // On other platforms, it's the encoded speed. - #[cfg(not(any( - linux_kernel, - bsd, - solarish, - all(libc, target_env = "newlib"), - target_os = "aix" - )))] - { - speed::decode(self.output_speed).unwrap() - } - } - - /// Set the input and output communication speeds. - /// - /// Unlike the `c_ispeed` and `c_ospeed` fields in glibc and others, this - /// takes the arbitrary integer value of the speed, rather than the `B*` - /// encoded constant value. Not all implementations support all integer - /// values; use the constants in the [`speed`] module for likely-supported - /// speeds. - #[cfg(not(target_os = "nto"))] - #[doc(alias = "cfsetspeed")] - #[doc(alias = "CBAUD")] - #[doc(alias = "CBAUDEX")] - #[doc(alias = "CIBAUD")] - #[doc(alias = "CIBAUDEX")] - #[inline] - pub fn set_speed(&mut self, new_speed: u32) -> io::Result<()> { - backend::termios::syscalls::set_speed(self, new_speed) - } - - /// Set the input communication speed. - /// - /// Unlike the `c_ispeed` field in glibc and others, this takes the - /// arbitrary integer value of the speed, rather than the `B*` encoded - /// constant value. Not all implementations support all integer values; use - /// the constants in the [`speed`] module for known-supported speeds. - /// - /// On some platforms, changing the input speed changes the output speed to - /// the same speed. - #[doc(alias = "c_ispeed")] - #[doc(alias = "cfsetispeed")] - #[doc(alias = "CIBAUD")] - #[doc(alias = "CIBAUDEX")] - #[inline] - pub fn set_input_speed(&mut self, new_speed: u32) -> io::Result<()> { - backend::termios::syscalls::set_input_speed(self, new_speed) - } - - /// Set the output communication speed. - /// - /// Unlike the `c_ospeed` field in glibc and others, this takes the - /// arbitrary integer value of the speed, rather than the `B*` encoded - /// constant value. Not all implementations support all integer values; use - /// the constants in the [`speed`] module for known-supported speeds. - /// - /// On some platforms, changing the output speed changes the input speed to - /// the same speed. - #[doc(alias = "c_ospeed")] - #[doc(alias = "cfsetospeed")] - #[doc(alias = "CBAUD")] - #[doc(alias = "CBAUDEX")] - #[inline] - pub fn set_output_speed(&mut self, new_speed: u32) -> io::Result<()> { - backend::termios::syscalls::set_output_speed(self, new_speed) - } -} - -impl core::fmt::Debug for Termios { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut d = f.debug_struct("Termios"); - d.field("input_modes", &self.input_modes); - d.field("output_modes", &self.output_modes); - - // This includes any bits set in the `CBAUD` and `CIBAUD` ranges, which - // is a little ugly, because we also decode those bits for the speeds - // below. However, it seems better to print them here than to hide - // them, because hiding them would make the `Termios` debug output - // appear to disagree with the `ControlModes` debug output for the same - // value, which could be confusing. - d.field("control_modes", &self.control_modes); - - d.field("local_modes", &self.local_modes); - #[cfg(any( - linux_like, - target_env = "newlib", - target_os = "fuchsia", - target_os = "haiku", - target_os = "redox" - ))] - { - d.field("line_discipline", &SpecialCode(self.line_discipline)); - } - d.field("special_codes", &self.special_codes); - d.field("input_speed", &self.input_speed()); - d.field("output_speed", &self.output_speed()); - d.finish() - } -} - -bitflags! { - /// Flags controlling terminal input. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct InputModes: types::tcflag_t { - /// `IGNBRK` - const IGNBRK = c::IGNBRK; - - /// `BRKINT` - const BRKINT = c::BRKINT; - - /// `IGNPAR` - const IGNPAR = c::IGNPAR; - - /// `PARMRK` - const PARMRK = c::PARMRK; - - /// `INPCK` - const INPCK = c::INPCK; - - /// `ISTRIP` - const ISTRIP = c::ISTRIP; - - /// `INLCR` - const INLCR = c::INLCR; - - /// `IGNCR` - const IGNCR = c::IGNCR; - - /// `ICRNL` - const ICRNL = c::ICRNL; - - /// `IUCLC` - #[cfg(any(linux_kernel, solarish, target_os = "aix", target_os = "haiku", target_os = "nto"))] - const IUCLC = c::IUCLC; - - /// `IXON` - const IXON = c::IXON; - - /// `IXANY` - #[cfg(not(target_os = "redox"))] - const IXANY = c::IXANY; - - /// `IXOFF` - const IXOFF = c::IXOFF; - - /// `IMAXBEL` - #[cfg(not(any(target_os = "haiku", target_os = "redox")))] - const IMAXBEL = c::IMAXBEL; - - /// `IUTF8` - #[cfg(not(any( - freebsdlike, - netbsdlike, - solarish, - target_os = "aix", - target_os = "emscripten", - target_os = "haiku", - target_os = "hurd", - target_os = "redox", - )))] - const IUTF8 = c::IUTF8; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// Flags controlling terminal output. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct OutputModes: types::tcflag_t { - /// `OPOST` - const OPOST = c::OPOST; - - /// `OLCUC` - #[cfg(not(any( - apple, - freebsdlike, - target_os = "aix", - target_os = "netbsd", - target_os = "redox", - )))] - const OLCUC = c::OLCUC; - - /// `ONLCR` - const ONLCR = c::ONLCR; - - /// `OCRNL` - const OCRNL = c::OCRNL; - - /// `ONOCR` - const ONOCR = c::ONOCR; - - /// `ONLRET` - const ONLRET = c::ONLRET; - - /// `OFILL` - #[cfg(not(bsd))] - const OFILL = c::OFILL; - - /// `OFDEL` - #[cfg(not(bsd))] - const OFDEL = c::OFDEL; - - /// `NLDLY` - #[cfg(not(any(bsd, solarish, target_os = "redox")))] - const NLDLY = c::NLDLY; - - /// `NL0` - #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] - const NL0 = c::NL0; - - /// `NL1` - #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] - const NL1 = c::NL1; - - /// `CRDLY` - #[cfg(not(any(bsd, solarish, target_os = "redox")))] - const CRDLY = c::CRDLY; - - /// `CR0` - #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] - const CR0 = c::CR0; - - /// `CR1` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const CR1 = c::CR1; - - /// `CR2` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const CR2 = c::CR2; - - /// `CR3` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const CR3 = c::CR3; - - /// `TABDLY` - #[cfg(not(any( - netbsdlike, - solarish, - target_os = "dragonfly", - target_os = "redox", - )))] - const TABDLY = c::TABDLY; - - /// `TAB0` - #[cfg(not(any( - netbsdlike, - solarish, - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "redox", - )))] - const TAB0 = c::TAB0; - - /// `TAB1` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const TAB1 = c::TAB1; - - /// `TAB2` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const TAB2 = c::TAB2; - - /// `TAB3` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const TAB3 = c::TAB3; - - /// `XTABS` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "redox", - )))] - const XTABS = c::XTABS; - - /// `BSDLY` - #[cfg(not(any(bsd, solarish, target_os = "redox")))] - const BSDLY = c::BSDLY; - - /// `BS0` - #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] - const BS0 = c::BS0; - - /// `BS1` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const BS1 = c::BS1; - - /// `FFDLY` - #[cfg(not(any(bsd, solarish, target_os = "redox")))] - const FFDLY = c::FFDLY; - - /// `FF0` - #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] - const FF0 = c::FF0; - - /// `FF1` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const FF1 = c::FF1; - - /// `VTDLY` - #[cfg(not(any(bsd, solarish, target_os = "redox")))] - const VTDLY = c::VTDLY; - - /// `VT0` - #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] - const VT0 = c::VT0; - - /// `VT1` - #[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", - )))] - const VT1 = c::VT1; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// Flags controlling special terminal modes. - /// - /// `CBAUD`, `CBAUDEX`, `CIBAUD`, `CIBAUDEX`, and various `B*` speed - /// constants are often included in the control modes, however rustix - /// handles them separately, in [`Termios::set_speed`] and related - /// functions. If you see extra bits in the `Debug` output, they're - /// probably these flags. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ControlModes: types::tcflag_t { - /// `CSIZE` - const CSIZE = c::CSIZE; - - /// `CS5` - const CS5 = c::CS5; - - /// `CS6` - const CS6 = c::CS6; - - /// `CS7` - const CS7 = c::CS7; - - /// `CS8` - const CS8 = c::CS8; - - /// `CSTOPB` - const CSTOPB = c::CSTOPB; - - /// `CREAD` - const CREAD = c::CREAD; - - /// `PARENB` - const PARENB = c::PARENB; - - /// `PARODD` - const PARODD = c::PARODD; - - /// `HUPCL` - const HUPCL = c::HUPCL; - - /// `CLOCAL` - const CLOCAL = c::CLOCAL; - - /// `CRTSCTS` - #[cfg(not(any(target_os = "aix", target_os = "nto", target_os = "redox")))] - const CRTSCTS = c::CRTSCTS; - - /// `CMSPAR` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "emscripten", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - target_os = "redox", - )))] - const CMSPAR = c::CMSPAR; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -bitflags! { - /// Flags controlling “local” terminal modes. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct LocalModes: types::tcflag_t { - /// `XCASE` - #[cfg(any(linux_kernel, target_arch = "s390x", target_os = "haiku"))] - const XCASE = c::XCASE; - - /// `ECHOCTL` - #[cfg(not(target_os = "redox"))] - const ECHOCTL = c::ECHOCTL; - - /// `ECHOPRT` - #[cfg(not(any(target_os = "cygwin", target_os = "nto", target_os = "redox")))] - const ECHOPRT = c::ECHOPRT; - - /// `ECHOKE` - #[cfg(not(target_os = "redox"))] - const ECHOKE = c::ECHOKE; - - /// `FLUSHO` - #[cfg(not(any(target_os = "nto", target_os = "redox")))] - const FLUSHO = c::FLUSHO; - - /// `PENDIN` - #[cfg(not(any(target_os = "cygwin", target_os = "nto", target_os = "redox")))] - const PENDIN = c::PENDIN; - - /// `EXTPROC` - #[cfg(not(any( - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - target_os = "redox", - )))] - const EXTPROC = c::EXTPROC; - - /// `ISIG` - const ISIG = c::ISIG; - - /// `ICANON`—A flag for the `c_lflag` field of [`Termios`] indicating - /// canonical mode. - const ICANON = c::ICANON; - - /// `ECHO` - const ECHO = c::ECHO; - - /// `ECHOE` - const ECHOE = c::ECHOE; - - /// `ECHOK` - const ECHOK = c::ECHOK; - - /// `ECHONL` - const ECHONL = c::ECHONL; - - /// `NOFLSH` - const NOFLSH = c::NOFLSH; - - /// `TOSTOP` - const TOSTOP = c::TOSTOP; - - /// `IEXTEN` - const IEXTEN = c::IEXTEN; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Speeds for use with [`Termios::set_speed`], [`Termios::set_input_speed`], -/// and [`Termios::set_output_speed`]. -/// -/// Unlike in some platforms' libc APIs, these always have the same numerical -/// value as their names; for example, `B50` has the value `50`, and so on. -/// Consequently, it's not necessary to use them. They are provided here -/// because they help identify speeds which are likely to be supported, on -/// platforms and devices which don't support arbitrary speeds. -pub mod speed { - #[cfg(not(bsd))] - use crate::backend::c; - - /// `B0` - pub const B0: u32 = 0; - - /// `B50` - pub const B50: u32 = 50; - - /// `B75` - pub const B75: u32 = 75; - - /// `B110` - pub const B110: u32 = 110; - - /// `B134` - pub const B134: u32 = 134; - - /// `B150` - pub const B150: u32 = 150; - - /// `B200` - pub const B200: u32 = 200; - - /// `B300` - pub const B300: u32 = 300; - - /// `B600` - pub const B600: u32 = 600; - - /// `B1200` - pub const B1200: u32 = 1200; - - /// `B1800` - pub const B1800: u32 = 1800; - - /// `B2400` - pub const B2400: u32 = 2400; - - /// `B4800` - pub const B4800: u32 = 4800; - - /// `B9600` - pub const B9600: u32 = 9600; - - /// `B19200` - #[doc(alias = "EXTA")] - pub const B19200: u32 = 19200; - - /// `B38400` - #[doc(alias = "EXTB")] - pub const B38400: u32 = 38400; - - /// `B57600` - #[cfg(not(target_os = "aix"))] - pub const B57600: u32 = 57600; - - /// `B115200` - #[cfg(not(target_os = "aix"))] - pub const B115200: u32 = 115_200; - - /// `B230400` - #[cfg(not(target_os = "aix"))] - pub const B230400: u32 = 230_400; - - /// `B460800` - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "openbsd" - )))] - pub const B460800: u32 = 460_800; - - /// `B500000` - #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - pub const B500000: u32 = 500_000; - - /// `B576000` - #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - pub const B576000: u32 = 576_000; - - /// `B921600` - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "openbsd" - )))] - pub const B921600: u32 = 921_600; - - /// `B1000000` - #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] - pub const B1000000: u32 = 1_000_000; - - /// `B1152000` - #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] - pub const B1152000: u32 = 1_152_000; - - /// `B1500000` - #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] - pub const B1500000: u32 = 1_500_000; - - /// `B2000000` - #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] - pub const B2000000: u32 = 2_000_000; - - /// `B2500000` - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", - )))] - pub const B2500000: u32 = 2_500_000; - - /// `B3000000` - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", - )))] - pub const B3000000: u32 = 3_000_000; - - /// `B3500000` - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", - )))] - pub const B3500000: u32 = 3_500_000; - - /// `B4000000` - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", - )))] - pub const B4000000: u32 = 4_000_000; - - /// Translate from a `c::speed_t` code to an arbitrary integer speed value - /// `u32`. - /// - /// On BSD platforms, integer speed values are already the same as their - /// encoded values. - /// - /// On Linux on PowerPC, `TCGETS`/`TCSETS` support the `c_ispeed` and - /// `c_ospeed` fields. - /// - /// On Linux on architectures other than PowerPC, `TCGETS`/`TCSETS` don't - /// support the `c_ispeed` and `c_ospeed` fields, so we have to fall back - /// to `TCGETS2`/`TCSETS2` to support them. - #[cfg(not(any( - bsd, - all(linux_kernel, any(target_arch = "powerpc", target_arch = "powerpc64")) - )))] - pub(crate) const fn decode(encoded_speed: c::speed_t) -> Option<u32> { - match encoded_speed { - c::B0 => Some(0), - c::B50 => Some(50), - c::B75 => Some(75), - c::B110 => Some(110), - c::B134 => Some(134), - c::B150 => Some(150), - c::B200 => Some(200), - c::B300 => Some(300), - c::B600 => Some(600), - c::B1200 => Some(1200), - c::B1800 => Some(1800), - c::B2400 => Some(2400), - c::B4800 => Some(4800), - c::B9600 => Some(9600), - c::B19200 => Some(19200), - c::B38400 => Some(38400), - #[cfg(not(target_os = "aix"))] - c::B57600 => Some(57600), - #[cfg(not(target_os = "aix"))] - c::B115200 => Some(115_200), - #[cfg(not(any(target_os = "aix", target_os = "nto")))] - c::B230400 => Some(230_400), - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "nto", - target_os = "openbsd" - )))] - c::B460800 => Some(460_800), - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - )))] - c::B500000 => Some(500_000), - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - )))] - c::B576000 => Some(576_000), - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "nto", - target_os = "openbsd" - )))] - c::B921600 => Some(921_600), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - c::B1000000 => Some(1_000_000), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - c::B1152000 => Some(1_152_000), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - c::B1500000 => Some(1_500_000), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - c::B2000000 => Some(2_000_000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - c::B2500000 => Some(2_500_000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - c::B3000000 => Some(3_000_000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - c::B3500000 => Some(3_500_000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - c::B4000000 => Some(4_000_000), - _ => None, - } - } - - /// Translate from an arbitrary `u32` arbitrary integer speed value to a - /// `c::speed_t` code. - #[cfg(not(bsd))] - pub(crate) const fn encode(speed: u32) -> Option<c::speed_t> { - match speed { - 0 => Some(c::B0), - 50 => Some(c::B50), - 75 => Some(c::B75), - 110 => Some(c::B110), - 134 => Some(c::B134), - 150 => Some(c::B150), - 200 => Some(c::B200), - 300 => Some(c::B300), - 600 => Some(c::B600), - 1200 => Some(c::B1200), - 1800 => Some(c::B1800), - 2400 => Some(c::B2400), - 4800 => Some(c::B4800), - 9600 => Some(c::B9600), - 19200 => Some(c::B19200), - 38400 => Some(c::B38400), - #[cfg(not(target_os = "aix"))] - 57600 => Some(c::B57600), - #[cfg(not(target_os = "aix"))] - 115_200 => Some(c::B115200), - #[cfg(not(any(target_os = "aix", target_os = "nto")))] - 230_400 => Some(c::B230400), - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "nto", - target_os = "openbsd", - )))] - 460_800 => Some(c::B460800), - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - )))] - 500_000 => Some(c::B500000), - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "nto" - )))] - 576_000 => Some(c::B576000), - #[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "nto", - target_os = "openbsd" - )))] - 921_600 => Some(c::B921600), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - 1_000_000 => Some(c::B1000000), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - 1_152_000 => Some(c::B1152000), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - 1_500_000 => Some(c::B1500000), - #[cfg(not(any( - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris" - )))] - 2_000_000 => Some(c::B2000000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - 2_500_000 => Some(c::B2500000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - 3_000_000 => Some(c::B3000000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - 3_500_000 => Some(c::B3500000), - #[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "cygwin", - target_os = "haiku", - target_os = "nto", - target_os = "solaris", - )))] - 4_000_000 => Some(c::B4000000), - _ => None, - } - } -} - -/// An array indexed by [`SpecialCodeIndex`] indicating the current values of -/// various special control codes. -#[repr(transparent)] -#[derive(Clone)] -pub struct SpecialCodes(pub(crate) [c::cc_t; c::NCCS as usize]); - -impl core::ops::Index<SpecialCodeIndex> for SpecialCodes { - type Output = u8; - - fn index(&self, index: SpecialCodeIndex) -> &Self::Output { - &self.0[index.0] - } -} - -impl core::ops::IndexMut<SpecialCodeIndex> for SpecialCodes { - fn index_mut(&mut self, index: SpecialCodeIndex) -> &mut Self::Output { - &mut self.0[index.0] - } -} - -impl core::fmt::Debug for SpecialCodes { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "SpecialCodes {{")?; - let mut first = true; - for i in 0..self.0.len() { - if first { - write!(f, " ")?; - } else { - write!(f, ", ")?; - } - first = false; - let index = SpecialCodeIndex(i); - write!(f, "{:?}: {:?}", index, SpecialCode(self[index]))?; - } - if !first { - write!(f, " ")?; - } - write!(f, "}}") - } -} - -/// A newtype for pretty printing. -struct SpecialCode(u8); - -impl core::fmt::Debug for SpecialCode { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - if self.0 == 0 { - write!(f, "<undef>") - } else if self.0 < 0x20 { - write!(f, "^{}", (self.0 + 0x40) as char) - } else if self.0 == 0x7f { - write!(f, "^?") - } else if self.0 >= 0x80 { - write!(f, "M-")?; - SpecialCode(self.0 - 0x80).fmt(f) - } else { - write!(f, "{}", (self.0 as char)) - } - } -} - -/// Indices for use with [`Termios::special_codes`]. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct SpecialCodeIndex(usize); - -#[rustfmt::skip] -impl SpecialCodeIndex { - /// `VINTR` - pub const VINTR: Self = Self(c::VINTR as usize); - - /// `VQUIT` - pub const VQUIT: Self = Self(c::VQUIT as usize); - - /// `VERASE` - pub const VERASE: Self = Self(c::VERASE as usize); - - /// `VKILL` - pub const VKILL: Self = Self(c::VKILL as usize); - - /// `VEOF` - pub const VEOF: Self = Self(c::VEOF as usize); - - /// `VTIME` - pub const VTIME: Self = Self(c::VTIME as usize); - - /// `VMIN` - pub const VMIN: Self = Self(c::VMIN as usize); - - /// `VSWTC` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - pub const VSWTC: Self = Self(c::VSWTC as usize); - - /// `VSTART` - pub const VSTART: Self = Self(c::VSTART as usize); - - /// `VSTOP` - pub const VSTOP: Self = Self(c::VSTOP as usize); - - /// `VSUSP` - pub const VSUSP: Self = Self(c::VSUSP as usize); - - /// `VEOL` - pub const VEOL: Self = Self(c::VEOL as usize); - - /// `VREPRINT` - #[cfg(not(target_os = "haiku"))] - pub const VREPRINT: Self = Self(c::VREPRINT as usize); - - /// `VDISCARD` - #[cfg(not(any(target_os = "aix", target_os = "haiku")))] - pub const VDISCARD: Self = Self(c::VDISCARD as usize); - - /// `VWERASE` - #[cfg(not(any(target_os = "aix", target_os = "haiku")))] - pub const VWERASE: Self = Self(c::VWERASE as usize); - - /// `VLNEXT` - #[cfg(not(target_os = "haiku"))] - pub const VLNEXT: Self = Self(c::VLNEXT as usize); - - /// `VEOL2` - pub const VEOL2: Self = Self(c::VEOL2 as usize); - - /// `VSWTCH` - #[cfg(any(solarish, target_os = "haiku", target_os = "nto"))] - pub const VSWTCH: Self = Self(c::VSWTCH as usize); - - /// `VDSUSP` - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "hurd", - target_os = "nto" - ))] - pub const VDSUSP: Self = Self(c::VDSUSP as usize); - - /// `VSTATUS` - #[cfg(any(bsd, target_os = "hurd", target_os = "illumos"))] - pub const VSTATUS: Self = Self(c::VSTATUS as usize); - - /// `VERASE2` - #[cfg(any(freebsdlike, target_os = "illumos"))] - pub const VERASE2: Self = Self(c::VERASE2 as usize); -} - -impl core::fmt::Debug for SpecialCodeIndex { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match *self { - Self::VINTR => write!(f, "VINTR"), - Self::VQUIT => write!(f, "VQUIT"), - Self::VERASE => write!(f, "VERASE"), - Self::VKILL => write!(f, "VKILL"), - #[cfg(not(any( - solarish, - all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")), - target_os = "aix", - target_os = "haiku", - )))] - Self::VEOF => write!(f, "VEOF"), - #[cfg(not(any( - solarish, - all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")), - target_os = "aix", - target_os = "haiku", - )))] - Self::VTIME => write!(f, "VTIME"), - #[cfg(not(any( - solarish, - all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")), - target_os = "aix", - target_os = "haiku", - )))] - Self::VMIN => write!(f, "VMIN"), - - // On Solarish platforms, Linux on SPARC, AIX, and Haiku, `VMIN` - // and `VTIME` have the same value as `VEOF` and `VEOL`. - #[cfg(any( - solarish, - all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")), - target_os = "aix", - target_os = "haiku", - ))] - Self::VMIN => write!(f, "VMIN/VEOF"), - #[cfg(any( - solarish, - all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")), - target_os = "aix", - target_os = "haiku", - ))] - Self::VTIME => write!(f, "VTIME/VEOL"), - - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "hurd", - target_os = "nto", - )))] - Self::VSWTC => write!(f, "VSWTC"), - Self::VSTART => write!(f, "VSTART"), - Self::VSTOP => write!(f, "VSTOP"), - Self::VSUSP => write!(f, "VSUSP"), - #[cfg(not(any( - solarish, - all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")), - target_os = "aix", - target_os = "haiku", - )))] - Self::VEOL => write!(f, "VEOL"), - #[cfg(not(target_os = "haiku"))] - Self::VREPRINT => write!(f, "VREPRINT"), - #[cfg(not(any(target_os = "aix", target_os = "haiku")))] - Self::VDISCARD => write!(f, "VDISCARD"), - #[cfg(not(any(target_os = "aix", target_os = "haiku")))] - Self::VWERASE => write!(f, "VWERASE"), - #[cfg(not(target_os = "haiku"))] - Self::VLNEXT => write!(f, "VLNEXT"), - Self::VEOL2 => write!(f, "VEOL2"), - #[cfg(any(solarish, target_os = "haiku", target_os = "nto"))] - Self::VSWTCH => write!(f, "VSWTCH"), - #[cfg(any( - bsd, - solarish, - target_os = "aix", - target_os = "hurd", - target_os = "nto" - ))] - Self::VDSUSP => write!(f, "VDSUSP"), - #[cfg(any(bsd, target_os = "hurd", target_os = "illumos"))] - Self::VSTATUS => write!(f, "VSTATUS"), - #[cfg(any(freebsdlike, target_os = "illumos"))] - Self::VERASE2 => write!(f, "VERASE2"), - - _ => write!(f, "unknown"), - } - } -} - -/// `TCSA*` values for use with [`tcsetattr`]. -/// -/// [`tcsetattr`]: crate::termios::tcsetattr -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum OptionalActions { - /// `TCSANOW`—Make the change immediately. - #[doc(alias = "TCSANOW")] - Now = c::TCSANOW as u32, - - /// `TCSADRAIN`—Make the change after all output has been transmitted. - #[doc(alias = "TCSADRAIN")] - Drain = c::TCSADRAIN as u32, - - /// `TCSAFLUSH`—Discard any pending input and then make the change - /// after all output has been transmitted. - #[doc(alias = "TCSAFLUSH")] - Flush = c::TCSAFLUSH as u32, -} - -/// `TC*` values for use with [`tcflush`]. -/// -/// [`tcflush`]: crate::termios::tcflush -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum QueueSelector { - /// `TCIFLUSH`—Flush data received but not read. - #[doc(alias = "TCIFLUSH")] - IFlush = c::TCIFLUSH as u32, - - /// `TCOFLUSH`—Flush data written but not transmitted. - #[doc(alias = "TCOFLUSH")] - OFlush = c::TCOFLUSH as u32, - - /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. - #[doc(alias = "TCIOFLUSH")] - IOFlush = c::TCIOFLUSH as u32, -} - -/// `TC*` values for use with [`tcflow`]. -/// -/// [`tcflow`]: crate::termios::tcflow -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Action { - /// `TCOOFF`—Suspend output. - #[doc(alias = "TCOOFF")] - OOff = c::TCOOFF as u32, - - /// `TCOON`—Restart suspended output. - #[doc(alias = "TCOON")] - OOn = c::TCOON as u32, - - /// `TCIOFF`—Transmits a STOP byte. - #[doc(alias = "TCIOFF")] - IOff = c::TCIOFF as u32, - - /// `TCION`—Transmits a START byte. - #[doc(alias = "TCION")] - IOn = c::TCION as u32, -} - -/// `struct winsize` for use with [`tcgetwinsize`]. -/// -/// [`tcgetwinsize`]: crate::termios::tcgetwinsize -#[doc(alias = "winsize")] -#[repr(C)] -#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] -#[allow(missing_docs)] -pub struct Winsize { - /// The number of rows the terminal has. - pub ws_row: u16, - /// The number of columns the terminal has. - pub ws_col: u16, - - pub ws_xpixel: u16, - pub ws_ypixel: u16, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn termios_layouts() { - check_renamed_type!(InputModes, tcflag_t); - check_renamed_type!(OutputModes, tcflag_t); - check_renamed_type!(ControlModes, tcflag_t); - check_renamed_type!(LocalModes, tcflag_t); - assert_eq_size!(u8, libc::cc_t); - assert_eq_size!(types::tcflag_t, libc::tcflag_t); - - check_renamed_struct!(Winsize, winsize, ws_row, ws_col, ws_xpixel, ws_ypixel); - - // On platforms with a termios/termios2 split, check `termios`. - #[cfg(linux_raw)] - { - check_renamed_type!(Termios, termios2); - check_renamed_struct_renamed_field!(Termios, termios2, input_modes, c_iflag); - check_renamed_struct_renamed_field!(Termios, termios2, output_modes, c_oflag); - check_renamed_struct_renamed_field!(Termios, termios2, control_modes, c_cflag); - check_renamed_struct_renamed_field!(Termios, termios2, local_modes, c_lflag); - check_renamed_struct_renamed_field!(Termios, termios2, line_discipline, c_line); - check_renamed_struct_renamed_field!(Termios, termios2, special_codes, c_cc); - check_renamed_struct_renamed_field!(Termios, termios2, input_speed, c_ispeed); - check_renamed_struct_renamed_field!(Termios, termios2, output_speed, c_ospeed); - - // We assume that `termios` has the same layout as `termios2` minus the - // `c_ispeed` and `c_ospeed` fields. - check_renamed_struct_renamed_field!(Termios, termios, input_modes, c_iflag); - check_renamed_struct_renamed_field!(Termios, termios, output_modes, c_oflag); - check_renamed_struct_renamed_field!(Termios, termios, control_modes, c_cflag); - check_renamed_struct_renamed_field!(Termios, termios, local_modes, c_lflag); - check_renamed_struct_renamed_field!(Termios, termios, special_codes, c_cc); - - // On everything except PowerPC, `termios` matches `termios2` except - // for the addition of `c_ispeed` and `c_ospeed`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - const_assert_eq!( - memoffset::offset_of!(Termios, input_speed), - core::mem::size_of::<c::termios>() - ); - - // On PowerPC, `termios2` is `termios`. - #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] - assert_eq_size!(c::termios2, c::termios); - } - - #[cfg(not(linux_raw))] - { - // On MIPS, SPARC, and Android, the libc lacks the ospeed and ispeed - // fields. - #[cfg(all( - not(all( - target_env = "gnu", - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ) - )), - not(all(libc, target_os = "android")) - ))] - check_renamed_type!(Termios, termios); - #[cfg(not(all( - not(all( - target_env = "gnu", - any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6", - target_arch = "sparc", - target_arch = "sparc64" - ) - )), - not(all(libc, target_os = "android")) - )))] - const_assert!(core::mem::size_of::<Termios>() >= core::mem::size_of::<c::termios>()); - - check_renamed_struct_renamed_field!(Termios, termios, input_modes, c_iflag); - check_renamed_struct_renamed_field!(Termios, termios, output_modes, c_oflag); - check_renamed_struct_renamed_field!(Termios, termios, control_modes, c_cflag); - check_renamed_struct_renamed_field!(Termios, termios, local_modes, c_lflag); - #[cfg(any( - linux_like, - target_env = "newlib", - target_os = "fuchsia", - target_os = "haiku", - target_os = "redox" - ))] - check_renamed_struct_renamed_field!(Termios, termios, line_discipline, c_line); - check_renamed_struct_renamed_field!(Termios, termios, special_codes, c_cc); - #[cfg(not(any( - linux_kernel, - solarish, - target_os = "emscripten", - target_os = "fuchsia" - )))] - { - check_renamed_struct_renamed_field!(Termios, termios, input_speed, c_ispeed); - check_renamed_struct_renamed_field!(Termios, termios, output_speed, c_ospeed); - } - #[cfg(any(target_env = "musl", target_os = "fuchsia"))] - { - check_renamed_struct_renamed_field!(Termios, termios, input_speed, __c_ispeed); - check_renamed_struct_renamed_field!(Termios, termios, output_speed, __c_ospeed); - } - } - - check_renamed_type!(OptionalActions, c_int); - check_renamed_type!(QueueSelector, c_int); - check_renamed_type!(Action, c_int); - } - - #[test] - #[cfg(not(any( - solarish, - target_os = "cygwin", - target_os = "emscripten", - target_os = "haiku", - target_os = "redox", - )))] - fn termios_legacy() { - // Check that our doc aliases above are correct. - const_assert_eq!(c::EXTA, c::B19200); - const_assert_eq!(c::EXTB, c::B38400); - } - - #[cfg(bsd)] - #[test] - fn termios_bsd() { - // On BSD platforms we can assume that the `B*` constants have their - // arbitrary integer speed value. Confirm this. - const_assert_eq!(c::B0, 0); - const_assert_eq!(c::B50, 50); - const_assert_eq!(c::B19200, 19200); - const_assert_eq!(c::B38400, 38400); - } - - #[test] - #[cfg(not(bsd))] - fn termios_speed_encoding() { - assert_eq!(speed::encode(0), Some(c::B0)); - assert_eq!(speed::encode(50), Some(c::B50)); - assert_eq!(speed::encode(19200), Some(c::B19200)); - assert_eq!(speed::encode(38400), Some(c::B38400)); - assert_eq!(speed::encode(1), None); - assert_eq!(speed::encode(!0), None); - - #[cfg(not(linux_kernel))] - { - assert_eq!(speed::decode(c::B0), Some(0)); - assert_eq!(speed::decode(c::B50), Some(50)); - assert_eq!(speed::decode(c::B19200), Some(19200)); - assert_eq!(speed::decode(c::B38400), Some(38400)); - } - } - - #[cfg(linux_kernel)] - #[test] - fn termios_ioctl_contiguity() { - // When using `termios2`, we assume that we can add the optional actions - // value to the ioctl request code. Test this assumption. - - const_assert_eq!(c::TCSETS2, c::TCSETS2 + 0); - const_assert_eq!(c::TCSETSW2, c::TCSETS2 + 1); - const_assert_eq!(c::TCSETSF2, c::TCSETS2 + 2); - - const_assert_eq!(c::TCSANOW - c::TCSANOW, 0); - const_assert_eq!(c::TCSADRAIN - c::TCSANOW, 1); - const_assert_eq!(c::TCSAFLUSH - c::TCSANOW, 2); - - // MIPS is different here. - #[cfg(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - ))] - { - assert_eq!(i128::from(c::TCSANOW) - i128::from(c::TCSETS), 0); - assert_eq!(i128::from(c::TCSADRAIN) - i128::from(c::TCSETS), 1); - assert_eq!(i128::from(c::TCSAFLUSH) - i128::from(c::TCSETS), 2); - } - #[cfg(not(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )))] - { - const_assert_eq!(c::TCSANOW, 0); - const_assert_eq!(c::TCSADRAIN, 1); - const_assert_eq!(c::TCSAFLUSH, 2); - } - } - - #[cfg(linux_kernel)] - #[test] - fn termios_cibaud() { - // Test an assumption. - const_assert_eq!(c::CIBAUD, c::CBAUD << c::IBSHIFT); - } -} diff --git a/vendor/rustix/src/thread/clock.rs b/vendor/rustix/src/thread/clock.rs deleted file mode 100644 index d6be40e8..00000000 --- a/vendor/rustix/src/thread/clock.rs +++ /dev/null @@ -1,117 +0,0 @@ -use crate::{backend, io}; -use core::fmt; - -pub use crate::timespec::{Nsecs, Secs, Timespec}; - -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "espidf", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -pub use crate::clockid::ClockId; - -/// `clock_nanosleep(id, 0, request, remain)`—Sleeps for a duration on a -/// given clock. -/// -/// This is `clock_nanosleep` specialized for the case of a relative sleep -/// interval. See [`clock_nanosleep_absolute`] for absolute intervals. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_nanosleep.html -/// [Linux]: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "haiku", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - backend::thread::syscalls::clock_nanosleep_relative(id, request) -} - -/// `clock_nanosleep(id, TIMER_ABSTIME, request, NULL)`—Sleeps until an -/// absolute time on a given clock. -/// -/// This is `clock_nanosleep` specialized for the case of an absolute sleep -/// interval. See [`clock_nanosleep_relative`] for relative intervals. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_nanosleep.html -/// [Linux]: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html -#[cfg(not(any( - apple, - target_os = "dragonfly", - target_os = "emscripten", - target_os = "espidf", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "haiku", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - target_os = "wasi", -)))] -#[inline] -pub fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { - backend::thread::syscalls::clock_nanosleep_absolute(id, request) -} - -/// `nanosleep(request, remain)`—Sleeps for a duration. -/// -/// This effectively uses the system monotonic clock. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/nanosleep.html -/// [Linux]: https://man7.org/linux/man-pages/man2/nanosleep.2.html -#[inline] -pub fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { - backend::thread::syscalls::nanosleep(request) -} - -/// A return type for `nanosleep` and `clock_nanosleep_relative`. -#[derive(Clone)] -#[must_use] -pub enum NanosleepRelativeResult { - /// The sleep completed normally. - Ok, - /// The sleep was interrupted, the remaining time is returned. - Interrupted(Timespec), - /// An invalid time value was provided. - Err(io::Errno), -} - -impl fmt::Debug for NanosleepRelativeResult { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Ok => f.write_str("Ok"), - Self::Interrupted(remaining) => write!( - f, - "Interrupted(Timespec {{ tv_sec: {:?}, tv_nsec: {:?} }})", - remaining.tv_sec, remaining.tv_nsec - ), - Self::Err(err) => write!(f, "Err({:?})", err), - } - } -} diff --git a/vendor/rustix/src/thread/futex.rs b/vendor/rustix/src/thread/futex.rs deleted file mode 100644 index 7ac49e69..00000000 --- a/vendor/rustix/src/thread/futex.rs +++ /dev/null @@ -1,600 +0,0 @@ -//! Linux `futex`. -//! -//! Futex is a very low-level mechanism for implementing concurrency primitives -//! such as mutexes, rwlocks, and condvars. For a higher-level API that -//! provides those abstractions, see [rustix-futex-syntax]. -//! -//! # Examples -//! -//! ``` -//! use rustix::thread::futex; -//! use std::sync::atomic::AtomicU32; -//! -//! # fn test(futex: &AtomicU32) -> rustix::io::Result<()> { -//! // Wake up one waiter. -//! futex::wake(futex, futex::Flags::PRIVATE, 1)?; -//! # Ok(()) -//! # } -//! ``` -//! -//! # References -//! - [Linux `futex` system call] -//! - [Linux `futex` feature] -//! -//! [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -//! [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -//! [rustix-futex-sync]: https://crates.io/crates/rustix-futex-sync -#![allow(unsafe_code)] - -use core::ffi::c_void; -use core::num::NonZeroU32; -use core::ptr; -use core::sync::atomic::AtomicU32; - -use crate::backend::thread::futex::Operation; -use crate::backend::thread::syscalls::{futex_timeout, futex_val2}; -use crate::fd::{FromRawFd as _, OwnedFd, RawFd}; -use crate::{backend, io}; - -pub use crate::clockid::ClockId; -pub use crate::timespec::{Nsecs, Secs, Timespec}; - -pub use backend::thread::futex::{Flags, WaitFlags, OWNER_DIED, WAITERS}; - -/// `syscall(SYS_futex, uaddr, FUTEX_WAIT, val, timeout, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn wait( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - timeout: Option<&Timespec>, -) -> io::Result<()> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_timeout(uaddr, Operation::Wait, flags, val, timeout, ptr::null(), 0).map(|val| { - debug_assert_eq!( - val, 0, - "The return value should always equal zero, if the call is successful" - ); - }) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_WAKE, val, NULL, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn wake(uaddr: &AtomicU32, flags: Flags, val: u32) -> io::Result<usize> { - // SAFETY: The raw pointers come from references or null. - unsafe { futex_val2(uaddr, Operation::Wake, flags, val, 0, ptr::null(), 0) } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_FD, val, NULL, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn fd(uaddr: &AtomicU32, flags: Flags, val: u32) -> io::Result<OwnedFd> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_val2(uaddr, Operation::Fd, flags, val, 0, ptr::null(), 0).map(|val| { - let fd = val as RawFd; - debug_assert_eq!(fd as usize, val, "return value should be a valid fd"); - OwnedFd::from_raw_fd(fd) - }) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_REQUEUE, val, val2, uaddr2, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn requeue( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - val2: u32, - uaddr2: &AtomicU32, -) -> io::Result<usize> { - // SAFETY: The raw pointers come from references or null. - unsafe { futex_val2(uaddr, Operation::Requeue, flags, val, val2, uaddr2, 0) } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_CMP_REQUEUE, val, val2, uaddr2, val3)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn cmp_requeue( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - val2: u32, - uaddr2: &AtomicU32, - val3: u32, -) -> io::Result<usize> { - // SAFETY: The raw pointers come from references or null. - unsafe { futex_val2(uaddr, Operation::CmpRequeue, flags, val, val2, uaddr2, val3) } -} - -/// `FUTEX_OP_*` operations for use with [`wake_op`]. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -#[allow(clippy::identity_op)] -pub enum WakeOp { - /// `FUTEX_OP_SET`: `uaddr2 = oparg;` - Set = 0, - /// `FUTEX_OP_ADD`: `uaddr2 += oparg;` - Add = 1, - /// `FUTEX_OP_OR`: `uaddr2 |= oparg;` - Or = 2, - /// `FUTEX_OP_ANDN`: `uaddr2 &= ~oparg;` - AndN = 3, - /// `FUTEX_OP_XOR`: `uaddr2 ^= oparg;` - XOr = 4, - /// `FUTEX_OP_SET | FUTEX_OP_ARG_SHIFT`: `uaddr2 = (oparg << 1);` - SetShift = 0 | 8, - /// `FUTEX_OP_ADD | FUTEX_OP_ARG_SHIFT`: `uaddr2 += (oparg << 1);` - AddShift = 1 | 8, - /// `FUTEX_OP_OR | FUTEX_OP_ARG_SHIFT`: `uaddr2 |= (oparg << 1);` - OrShift = 2 | 8, - /// `FUTEX_OP_ANDN | FUTEX_OP_ARG_SHIFT`: `uaddr2 &= !(oparg << 1);` - AndNShift = 3 | 8, - /// `FUTEX_OP_XOR | FUTEX_OP_ARG_SHIFT`: `uaddr2 ^= (oparg << 1);` - XOrShift = 4 | 8, -} - -/// `FUTEX_OP_CMP_*` operations for use with [`wake_op`]. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum WakeOpCmp { - /// `FUTEX_OP_CMP_EQ`: `if oldval == cmparg { wake(); }` - Eq = 0, - /// `FUTEX_OP_CMP_EQ`: `if oldval != cmparg { wake(); }` - Ne = 1, - /// `FUTEX_OP_CMP_EQ`: `if oldval < cmparg { wake(); }` - Lt = 2, - /// `FUTEX_OP_CMP_EQ`: `if oldval <= cmparg { wake(); }` - Le = 3, - /// `FUTEX_OP_CMP_EQ`: `if oldval > cmparg { wake(); }` - Gt = 4, - /// `FUTEX_OP_CMP_EQ`: `if oldval >= cmparg { wake(); }` - Ge = 5, -} - -/// `syscall(SYS_futex, uaddr, FUTEX_WAKE_OP, val, val2, uaddr2, val3)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -#[allow(clippy::too_many_arguments)] -pub fn wake_op( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - val2: u32, - uaddr2: &AtomicU32, - op: WakeOp, - cmp: WakeOpCmp, - oparg: u16, - cmparg: u16, -) -> io::Result<usize> { - if oparg >= 1 << 12 || cmparg >= 1 << 12 { - return Err(io::Errno::INVAL); - } - - let val3 = - ((op as u32) << 28) | ((cmp as u32) << 24) | ((oparg as u32) << 12) | (cmparg as u32); - - // SAFETY: The raw pointers come from references or null. - unsafe { futex_val2(uaddr, Operation::WakeOp, flags, val, val2, uaddr2, val3) } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_LOCK_PI, 0, timeout, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn lock_pi(uaddr: &AtomicU32, flags: Flags, timeout: Option<&Timespec>) -> io::Result<()> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_timeout(uaddr, Operation::LockPi, flags, 0, timeout, ptr::null(), 0).map(|val| { - debug_assert_eq!( - val, 0, - "The return value should always equal zero, if the call is successful" - ); - }) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_UNLOCK_PI, 0, NULL, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn unlock_pi(uaddr: &AtomicU32, flags: Flags) -> io::Result<()> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_val2(uaddr, Operation::UnlockPi, flags, 0, 0, ptr::null(), 0).map(|val| { - debug_assert_eq!( - val, 0, - "The return value should always equal zero, if the call is successful" - ); - }) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_TRYLOCK_PI, 0, NULL, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn trylock_pi(uaddr: &AtomicU32, flags: Flags) -> io::Result<bool> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_val2(uaddr, Operation::TrylockPi, flags, 0, 0, ptr::null(), 0).map(|ret| ret == 0) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_WAIT_BITSET, val, timeout, NULL, val3)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn wait_bitset( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - timeout: Option<&Timespec>, - val3: NonZeroU32, -) -> io::Result<()> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_timeout( - uaddr, - Operation::WaitBitset, - flags, - val, - timeout, - ptr::null(), - val3.get(), - ) - .map(|val| { - debug_assert_eq!( - val, 0, - "The return value should always equal zero, if the call is successful" - ); - }) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_WAKE_BITSET, val, NULL, NULL, val3)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn wake_bitset( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - val3: NonZeroU32, -) -> io::Result<usize> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_val2( - uaddr, - Operation::WakeBitset, - flags, - val, - 0, - ptr::null(), - val3.get(), - ) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_WAIT_REQUEUE_PI, val, timeout, uaddr2, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn wait_requeue_pi( - uaddr: &AtomicU32, - flags: Flags, - val: u32, - timeout: Option<&Timespec>, - uaddr2: &AtomicU32, -) -> io::Result<()> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_timeout( - uaddr, - Operation::WaitRequeuePi, - flags, - val, - timeout, - uaddr2, - 0, - ) - .map(|val| { - debug_assert_eq!( - val, 0, - "The return value should always equal zero, if the call is successful" - ); - }) - } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_CMP_REQUEUE_PI, 1, val2, uaddr2, val3)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn cmp_requeue_pi( - uaddr: &AtomicU32, - flags: Flags, - val2: u32, - uaddr2: &AtomicU32, - val3: u32, -) -> io::Result<usize> { - // SAFETY: The raw pointers come from references or null. - unsafe { futex_val2(uaddr, Operation::CmpRequeuePi, flags, 1, val2, uaddr2, val3) } -} - -/// `syscall(SYS_futex, uaddr, FUTEX_LOCK_PI2, 0, timeout, NULL, 0)` -/// -/// This is a very low-level feature for implementing synchronization -/// primitives. See the references links. -/// -/// # References -/// - [Linux `futex` system call] -/// - [Linux `futex` feature] -/// -/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html -/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html -#[inline] -pub fn lock_pi2(uaddr: &AtomicU32, flags: Flags, timeout: Option<&Timespec>) -> io::Result<()> { - // SAFETY: The raw pointers come from references or null. - unsafe { - futex_timeout(uaddr, Operation::LockPi2, flags, 0, timeout, ptr::null(), 0).map(|val| { - debug_assert_eq!( - val, 0, - "The return value should always equal zero, if the call is successful" - ); - }) - } -} - -/// A pointer in the [`Wait`] struct. -#[repr(C)] -#[derive(Copy, Clone)] -#[non_exhaustive] -pub struct WaitPtr { - #[cfg(all(target_pointer_width = "32", target_endian = "big"))] - #[doc(hidden)] - pub __pad32: u32, - #[cfg(all(target_pointer_width = "16", target_endian = "big"))] - #[doc(hidden)] - pub __pad16: u16, - - /// The pointer value. - pub ptr: *mut c_void, - - #[cfg(all(target_pointer_width = "16", target_endian = "little"))] - #[doc(hidden)] - pub __pad16: u16, - #[cfg(all(target_pointer_width = "32", target_endian = "little"))] - #[doc(hidden)] - pub __pad32: u32, -} - -impl WaitPtr { - /// Construct a new `WaitPtr` holding the given raw pointer value. - #[inline] - pub const fn new(ptr: *mut c_void) -> Self { - Self { - ptr, - - #[cfg(target_pointer_width = "16")] - __pad16: 0, - #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] - __pad32: 0, - } - } -} - -impl Default for WaitPtr { - #[inline] - fn default() -> Self { - Self::new(ptr::null_mut()) - } -} - -impl From<*mut c_void> for WaitPtr { - #[inline] - fn from(ptr: *mut c_void) -> Self { - Self::new(ptr) - } -} - -impl core::fmt::Debug for WaitPtr { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.ptr.fmt(f) - } -} - -/// For use with [`waitv`]. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[non_exhaustive] -pub struct Wait { - /// The expected value. - pub val: u64, - /// The address to wait for. - pub uaddr: WaitPtr, - /// The type and size of futex to perform. - pub flags: WaitFlags, - - /// Reserved for future use. - pub(crate) __reserved: u32, -} - -impl Wait { - /// Construct a zero-initialized `Wait`. - #[inline] - pub const fn new() -> Self { - Self { - val: 0, - uaddr: WaitPtr::new(ptr::null_mut()), - flags: WaitFlags::empty(), - __reserved: 0, - } - } -} - -impl Default for Wait { - #[inline] - fn default() -> Self { - Self::new() - } -} - -/// `futex_waitv(waiters.as_ptr(), waiters.len(), flags, timeout, clockd)`— -/// Wait on an array of futexes, wake on any. -/// -/// This requires Linux ≥ 5.16. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://www.kernel.org/doc/html/latest/userspace-api/futex2.html -#[inline] -pub fn waitv( - waiters: &[Wait], - flags: WaitvFlags, - timeout: Option<&Timespec>, - clockid: ClockId, -) -> io::Result<usize> { - backend::thread::syscalls::futex_waitv(waiters, flags, timeout, clockid) -} - -bitflags::bitflags! { - /// Flags for use with the flags argument in [`waitv`]. - /// - /// At this time, no flags are defined. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitvFlags: u32 { - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_raw)] -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_layouts() { - use crate::backend::c; - - check_renamed_struct!(Wait, futex_waitv, val, uaddr, flags, __reserved); - } -} diff --git a/vendor/rustix/src/thread/id.rs b/vendor/rustix/src/thread/id.rs deleted file mode 100644 index aa67c9ea..00000000 --- a/vendor/rustix/src/thread/id.rs +++ /dev/null @@ -1,184 +0,0 @@ -//! CPU and thread identifiers. -//! -//! # Safety -//! -//! The `Cpuid`, type can be constructed from raw integers, which is marked -//! unsafe because actual OS's assign special meaning to some integer values. - -#![allow(unsafe_code)] -use crate::{backend, io}; -#[cfg(linux_kernel)] -use backend::thread::types::RawCpuid; - -pub use crate::pid::{Pid, RawPid}; -pub use crate::ugid::{Gid, RawGid, RawUid, Uid}; - -/// A Linux CPU ID. -#[cfg(linux_kernel)] -#[repr(transparent)] -#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] -pub struct Cpuid(RawCpuid); - -#[cfg(linux_kernel)] -impl Cpuid { - /// Converts a `RawCpuid` into a `Cpuid`. - /// - /// # Safety - /// - /// `raw` must be the value of a valid Linux CPU ID. - #[inline] - pub const unsafe fn from_raw(raw: RawCpuid) -> Self { - Self(raw) - } - - /// Converts a `Cpuid` into a `RawCpuid`. - #[inline] - pub const fn as_raw(self) -> RawCpuid { - self.0 - } -} - -/// `gettid()`—Returns the thread ID. -/// -/// This returns the OS thread ID, which is not necessarily the same as the -/// Rust's `std::thread::Thread::id` or the pthread ID. -/// -/// This function always does a system call. To avoid this overhead, ask the -/// thread runtime for the ID instead, for example using [`libc::gettid`] or -/// [`origin::thread::current_id`]. -/// -/// [`libc::gettid`]: https://docs.rs/libc/*/libc/fn.gettid.html -/// [`origin::thread::current_id`]: https://docs.rs/origin/*/origin/thread/fn.current_id.html -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/gettid.2.html -#[inline] -#[must_use] -pub fn gettid() -> Pid { - backend::thread::syscalls::gettid() -} - -/// `setuid(uid)`—Sets the effective user ID of the calling thread. -/// -/// # Warning -/// -/// This is not the `setuid` you are looking for… POSIX requires uids to be -/// process granular, but on Linux they are per-thread. Thus, this call only -/// changes the uid for the current *thread*, not the entire process even -/// though that is in violation of the POSIX standard. -/// -/// For details on this distinction, see the C library vs. kernel differences -/// in the [manual page][linux_notes]. This call implements the kernel -/// behavior. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setuid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setuid.2.html -/// [linux_notes]: https://man7.org/linux/man-pages/man2/setuid.2.html#NOTES -#[inline] -pub fn set_thread_uid(uid: Uid) -> io::Result<()> { - backend::thread::syscalls::setuid_thread(uid) -} - -/// `setresuid(ruid, euid, suid)`—Sets the real, effective, and saved user ID -/// of the calling thread. -/// -/// # Warning -/// -/// This is not the `setresuid` you are looking for… POSIX requires uids to be -/// process granular, but on Linux they are per-thread. Thus, this call only -/// changes the uid for the current *thread*, not the entire process even -/// though that is in violation of the POSIX standard. -/// -/// For details on this distinction, see the C library vs. kernel differences -/// in the [manual page][linux_notes] and the notes in [`set_thread_uid`]. This -/// call implements the kernel behavior. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setresuid.2.html -/// [linux_notes]: https://man7.org/linux/man-pages/man2/setresuid.2.html#NOTES -#[inline] -pub fn set_thread_res_uid(ruid: Uid, euid: Uid, suid: Uid) -> io::Result<()> { - backend::thread::syscalls::setresuid_thread(ruid, euid, suid) -} - -/// `setgid(gid)`—Sets the effective group ID of the current thread. -/// -/// # Warning -/// -/// This is not the `setgid` you are looking for… POSIX requires gids to be -/// process granular, but on Linux they are per-thread. Thus, this call only -/// changes the gid for the current *thread*, not the entire process even -/// though that is in violation of the POSIX standard. -/// -/// For details on this distinction, see the C library vs. kernel differences -/// in the [manual page][linux_notes]. This call implements the kernel -/// behavior. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setgid.2.html -/// [linux_notes]: https://man7.org/linux/man-pages/man2/setgid.2.html#NOTES -#[inline] -pub fn set_thread_gid(gid: Gid) -> io::Result<()> { - backend::thread::syscalls::setgid_thread(gid) -} - -/// `setresgid(rgid, egid, sgid)`—Sets the real, effective, and saved group -/// ID of the current thread. -/// -/// # Warning -/// -/// This is not the `setresgid` you are looking for… POSIX requires gids to be -/// process granular, but on Linux they are per-thread. Thus, this call only -/// changes the gid for the current *thread*, not the entire process even -/// though that is in violation of the POSIX standard. -/// -/// For details on this distinction, see the C library vs. kernel differences -/// in the [manual page][linux_notes] and the notes in [`set_thread_gid`]. This -/// call implements the kernel behavior. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setresgid.2.html -/// [linux_notes]: https://man7.org/linux/man-pages/man2/setresgid.2.html#NOTES -#[inline] -pub fn set_thread_res_gid(rgid: Gid, egid: Gid, sgid: Gid) -> io::Result<()> { - backend::thread::syscalls::setresgid_thread(rgid, egid, sgid) -} - -/// `setgroups(groups)`—Sets the supplementary group IDs for the calling -/// thread. -/// -/// # Warning -/// -/// This is not the `setgroups` you are looking for… POSIX requires gids to be -/// process granular, but on Linux they are per-thread. Thus, this call only -/// changes the gids for the current *thread*, not the entire process even -/// though that is in violation of the POSIX standard. -/// -/// For details on this distinction, see the C library vs. kernel differences -/// in the [manual page][linux_notes]. This call implements the kernel -/// behavior. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setgroups.2.html -/// [linux_notes]: https://man7.org/linux/man-pages/man2/setgroups.2.html#NOTES -#[cfg(linux_kernel)] -#[inline] -pub fn set_thread_groups(groups: &[Gid]) -> io::Result<()> { - backend::thread::syscalls::setgroups_thread(groups) -} diff --git a/vendor/rustix/src/thread/libcap.rs b/vendor/rustix/src/thread/libcap.rs deleted file mode 100644 index 0a0fbb4c..00000000 --- a/vendor/rustix/src/thread/libcap.rs +++ /dev/null @@ -1,185 +0,0 @@ -use bitflags::bitflags; -use core::mem::MaybeUninit; - -use crate::pid::Pid; -use crate::{backend, io}; - -/// `__user_cap_data_struct` -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct CapabilitySets { - /// `__user_cap_data_struct.effective` - pub effective: CapabilityFlags, - /// `__user_cap_data_struct.permitted` - pub permitted: CapabilityFlags, - /// `__user_cap_data_struct.inheritable` - pub inheritable: CapabilityFlags, -} - -bitflags! { - /// `CAP_*` constants. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CapabilityFlags: u64 { - /// `CAP_CHOWN` - const CHOWN = 1 << linux_raw_sys::general::CAP_CHOWN; - /// `CAP_DAC_OVERRIDE` - const DAC_OVERRIDE = 1 << linux_raw_sys::general::CAP_DAC_OVERRIDE; - /// `CAP_DAC_READ_SEARCH` - const DAC_READ_SEARCH = 1 << linux_raw_sys::general::CAP_DAC_READ_SEARCH; - /// `CAP_FOWNER` - const FOWNER = 1 << linux_raw_sys::general::CAP_FOWNER; - /// `CAP_FSETID` - const FSETID = 1 << linux_raw_sys::general::CAP_FSETID; - /// `CAP_KILL` - const KILL = 1 << linux_raw_sys::general::CAP_KILL; - /// `CAP_SETGID` - const SETGID = 1 << linux_raw_sys::general::CAP_SETGID; - /// `CAP_SETUID` - const SETUID = 1 << linux_raw_sys::general::CAP_SETUID; - /// `CAP_SETPCAP` - const SETPCAP = 1 << linux_raw_sys::general::CAP_SETPCAP; - /// `CAP_LINUX_IMMUTABLE` - const LINUX_IMMUTABLE = 1 << linux_raw_sys::general::CAP_LINUX_IMMUTABLE; - /// `CAP_NET_BIND_SERVICE` - const NET_BIND_SERVICE = 1 << linux_raw_sys::general::CAP_NET_BIND_SERVICE; - /// `CAP_NET_BROADCAST` - const NET_BROADCAST = 1 << linux_raw_sys::general::CAP_NET_BROADCAST; - /// `CAP_NET_ADMIN` - const NET_ADMIN = 1 << linux_raw_sys::general::CAP_NET_ADMIN; - /// `CAP_NET_RAW` - const NET_RAW = 1 << linux_raw_sys::general::CAP_NET_RAW; - /// `CAP_IPC_LOCK` - const IPC_LOCK = 1 << linux_raw_sys::general::CAP_IPC_LOCK; - /// `CAP_IPC_OWNER` - const IPC_OWNER = 1 << linux_raw_sys::general::CAP_IPC_OWNER; - /// `CAP_SYS_MODULE` - const SYS_MODULE = 1 << linux_raw_sys::general::CAP_SYS_MODULE; - /// `CAP_SYS_RAWIO` - const SYS_RAWIO = 1 << linux_raw_sys::general::CAP_SYS_RAWIO; - /// `CAP_SYS_CHROOT` - const SYS_CHROOT = 1 << linux_raw_sys::general::CAP_SYS_CHROOT; - /// `CAP_SYS_PTRACE` - const SYS_PTRACE = 1 << linux_raw_sys::general::CAP_SYS_PTRACE; - /// `CAP_SYS_PACCT` - const SYS_PACCT = 1 << linux_raw_sys::general::CAP_SYS_PACCT; - /// `CAP_SYS_ADMIN` - const SYS_ADMIN = 1 << linux_raw_sys::general::CAP_SYS_ADMIN; - /// `CAP_SYS_BOOT` - const SYS_BOOT = 1 << linux_raw_sys::general::CAP_SYS_BOOT; - /// `CAP_SYS_NICE` - const SYS_NICE = 1 << linux_raw_sys::general::CAP_SYS_NICE; - /// `CAP_SYS_RESOURCE` - const SYS_RESOURCE = 1 << linux_raw_sys::general::CAP_SYS_RESOURCE; - /// `CAP_SYS_TIME` - const SYS_TIME = 1 << linux_raw_sys::general::CAP_SYS_TIME; - /// `CAP_SYS_TTY_CONFIG` - const SYS_TTY_CONFIG = 1 << linux_raw_sys::general::CAP_SYS_TTY_CONFIG; - /// `CAP_MKNOD` - const MKNOD = 1 << linux_raw_sys::general::CAP_MKNOD; - /// `CAP_LEASE` - const LEASE = 1 << linux_raw_sys::general::CAP_LEASE; - /// `CAP_AUDIT_WRITE` - const AUDIT_WRITE = 1 << linux_raw_sys::general::CAP_AUDIT_WRITE; - /// `CAP_AUDIT_CONTROL` - const AUDIT_CONTROL = 1 << linux_raw_sys::general::CAP_AUDIT_CONTROL; - /// `CAP_SETFCAP` - const SETFCAP = 1 << linux_raw_sys::general::CAP_SETFCAP; - /// `CAP_MAC_OVERRIDE` - const MAC_OVERRIDE = 1 << linux_raw_sys::general::CAP_MAC_OVERRIDE; - /// `CAP_MAC_ADMIN` - const MAC_ADMIN = 1 << linux_raw_sys::general::CAP_MAC_ADMIN; - /// `CAP_SYSLOG` - const SYSLOG = 1 << linux_raw_sys::general::CAP_SYSLOG; - /// `CAP_WAKE_ALARM` - const WAKE_ALARM = 1 << linux_raw_sys::general::CAP_WAKE_ALARM; - /// `CAP_BLOCK_SUSPEND` - const BLOCK_SUSPEND = 1 << linux_raw_sys::general::CAP_BLOCK_SUSPEND; - /// `CAP_AUDIT_READ` - const AUDIT_READ = 1 << linux_raw_sys::general::CAP_AUDIT_READ; - /// `CAP_PERFMON` - const PERFMON = 1 << linux_raw_sys::general::CAP_PERFMON; - /// `CAP_BPF` - const BPF = 1 << linux_raw_sys::general::CAP_BPF; - /// `CAP_CHECKPOINT_RESTORE` - const CHECKPOINT_RESTORE = 1 << linux_raw_sys::general::CAP_CHECKPOINT_RESTORE; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `capget(_LINUX_CAPABILITY_VERSION_3, pid)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/capget.2.html -#[inline] -#[doc(alias = "capget")] -pub fn capabilities(pid: Option<Pid>) -> io::Result<CapabilitySets> { - capget(pid) -} - -/// `capset(_LINUX_CAPABILITY_VERSION_3, pid, effective, permitted, -/// inheritable)` -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/capget.2.html -#[inline] -#[doc(alias = "capset")] -pub fn set_capabilities(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> { - capset(pid, sets) -} - -#[inline] -#[allow(unsafe_code)] -fn capget(pid: Option<Pid>) -> io::Result<CapabilitySets> { - let mut data = [MaybeUninit::<linux_raw_sys::general::__user_cap_data_struct>::uninit(); 2]; - - let data = { - let mut header = linux_raw_sys::general::__user_cap_header_struct { - version: linux_raw_sys::general::_LINUX_CAPABILITY_VERSION_3, - pid: Pid::as_raw(pid) as backend::c::c_int, - }; - - backend::thread::syscalls::capget(&mut header, &mut data)?; - // SAFETY: v3 is a 64-bit implementation, so the kernel filled in both - // data structs. - unsafe { (data[0].assume_init(), data[1].assume_init()) } - }; - - let effective = u64::from(data.0.effective) | (u64::from(data.1.effective) << u32::BITS); - let permitted = u64::from(data.0.permitted) | (u64::from(data.1.permitted) << u32::BITS); - let inheritable = u64::from(data.0.inheritable) | (u64::from(data.1.inheritable) << u32::BITS); - - // The kernel returns a partitioned bitset that we just combined above. - Ok(CapabilitySets { - effective: CapabilityFlags::from_bits_retain(effective), - permitted: CapabilityFlags::from_bits_retain(permitted), - inheritable: CapabilityFlags::from_bits_retain(inheritable), - }) -} - -#[inline] -fn capset(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> { - let mut header = linux_raw_sys::general::__user_cap_header_struct { - version: linux_raw_sys::general::_LINUX_CAPABILITY_VERSION_3, - pid: Pid::as_raw(pid) as backend::c::c_int, - }; - let data = [ - linux_raw_sys::general::__user_cap_data_struct { - effective: sets.effective.bits() as u32, - permitted: sets.permitted.bits() as u32, - inheritable: sets.inheritable.bits() as u32, - }, - linux_raw_sys::general::__user_cap_data_struct { - effective: (sets.effective.bits() >> u32::BITS) as u32, - permitted: (sets.permitted.bits() >> u32::BITS) as u32, - inheritable: (sets.inheritable.bits() >> u32::BITS) as u32, - }, - ]; - - backend::thread::syscalls::capset(&mut header, &data) -} diff --git a/vendor/rustix/src/thread/membarrier.rs b/vendor/rustix/src/thread/membarrier.rs deleted file mode 100644 index b3e6508e..00000000 --- a/vendor/rustix/src/thread/membarrier.rs +++ /dev/null @@ -1,92 +0,0 @@ -//! The Linux `membarrier` syscall. - -use crate::thread::Cpuid; -use crate::{backend, io}; - -pub use backend::thread::types::MembarrierCommand; - -#[cfg(linux_kernel)] -bitflags::bitflags! { - /// A result from [`membarrier_query`]. - /// - /// These flags correspond to values of [`MembarrierCommand`] which are - /// supported in the OS. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct MembarrierQuery: u32 { - /// `MEMBARRIER_CMD_GLOBAL` (also known as `MEMBARRIER_CMD_SHARED`) - #[doc(alias = "SHARED")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - const GLOBAL = MembarrierCommand::Global as _; - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - const GLOBAL_EXPEDITED = MembarrierCommand::GlobalExpedited as _; - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - const REGISTER_GLOBAL_EXPEDITED = MembarrierCommand::RegisterGlobalExpedited as _; - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - const PRIVATE_EXPEDITED = MembarrierCommand::PrivateExpedited as _; - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - const REGISTER_PRIVATE_EXPEDITED = MembarrierCommand::RegisterPrivateExpedited as _; - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - const PRIVATE_EXPEDITED_SYNC_CORE = MembarrierCommand::PrivateExpeditedSyncCore as _; - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - const REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = MembarrierCommand::RegisterPrivateExpeditedSyncCore as _; - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - const PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::PrivateExpeditedRseq as _; - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - const REGISTER_PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::RegisterPrivateExpeditedRseq as _; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(linux_kernel)] -impl MembarrierQuery { - /// Test whether this query result contains the given command. - #[inline] - pub fn contains_command(self, cmd: MembarrierCommand) -> bool { - // `MembarrierCommand` is an enum that only contains values also valid - // in `MembarrierQuery`. - self.contains(Self::from_bits_retain(cmd as _)) - } -} - -/// `membarrier(MEMBARRIER_CMD_QUERY, 0, 0)`—Query the supported `membarrier` -/// commands. -/// -/// This function doesn't return a `Result` because it always succeeds; if the -/// underlying OS doesn't support the `membarrier` syscall, it returns an empty -/// `MembarrierQuery` value. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html -#[inline] -#[doc(alias = "MEMBARRIER_CMD_QUERY")] -pub fn membarrier_query() -> MembarrierQuery { - backend::thread::syscalls::membarrier_query() -} - -/// `membarrier(cmd, 0, 0)`—Perform a memory barrier. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html -#[inline] -pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - backend::thread::syscalls::membarrier(cmd) -} - -/// `membarrier(cmd, MEMBARRIER_CMD_FLAG_CPU, cpu)`—Perform a memory barrier -/// with a specific CPU. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html -#[inline] -pub fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - backend::thread::syscalls::membarrier_cpu(cmd, cpu) -} diff --git a/vendor/rustix/src/thread/mod.rs b/vendor/rustix/src/thread/mod.rs deleted file mode 100644 index e32b5945..00000000 --- a/vendor/rustix/src/thread/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Thread-associated operations. - -#[cfg(not(target_os = "redox"))] -mod clock; -#[cfg(linux_kernel)] -pub mod futex; -#[cfg(linux_kernel)] -mod id; -#[cfg(linux_kernel)] -mod libcap; -#[cfg(linux_kernel)] -mod membarrier; -#[cfg(linux_kernel)] -mod prctl; -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -mod sched; -mod sched_yield; -#[cfg(linux_kernel)] -mod setns; - -#[cfg(not(target_os = "redox"))] -pub use clock::*; -#[cfg(linux_kernel)] -pub use id::*; -#[cfg(linux_kernel)] -pub use libcap::{capabilities, set_capabilities, CapabilityFlags, CapabilitySets}; -#[cfg(linux_kernel)] -pub use membarrier::*; -#[cfg(linux_kernel)] -pub use prctl::*; -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -pub use sched::*; -pub use sched_yield::sched_yield; -#[cfg(linux_kernel)] -pub use setns::*; diff --git a/vendor/rustix/src/thread/prctl.rs b/vendor/rustix/src/thread/prctl.rs deleted file mode 100644 index 4719b1eb..00000000 --- a/vendor/rustix/src/thread/prctl.rs +++ /dev/null @@ -1,1014 +0,0 @@ -//! Linux `prctl` wrappers. -//! -//! Rustix wraps variadic/dynamic-dispatch functions like `prctl` in type-safe -//! wrappers. -//! -//! # Safety -//! -//! The inner `prctl` calls are dynamically typed and must be called correctly. -#![allow(unsafe_code)] - -use core::mem::MaybeUninit; -use core::num::NonZeroU64; -use core::ptr; -use core::ptr::NonNull; -use core::sync::atomic::AtomicU8; - -use bitflags::bitflags; - -use crate::backend::prctl::syscalls; -#[cfg(feature = "alloc")] -use crate::ffi::CString; -use crate::ffi::{c_int, c_uint, c_void, CStr}; -use crate::io; -use crate::pid::Pid; -use crate::prctl::{ - prctl_1arg, prctl_2args, prctl_3args, prctl_get_at_arg2_optional, PointerAuthenticationKeys, -}; -use crate::utils::as_ptr; - -// -// PR_GET_KEEPCAPS/PR_SET_KEEPCAPS -// - -const PR_GET_KEEPCAPS: c_int = 7; - -/// Get the current state of the calling thread's `keep capabilities` flag. -/// -/// # References -/// - [`prctl(PR_GET_KEEPCAPS,…)`] -/// -/// [`prctl(PR_GET_KEEPCAPS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn get_keep_capabilities() -> io::Result<bool> { - unsafe { prctl_1arg(PR_GET_KEEPCAPS) }.map(|r| r != 0) -} - -const PR_SET_KEEPCAPS: c_int = 8; - -/// Set the state of the calling thread's `keep capabilities` flag. -/// -/// # References -/// - [`prctl(PR_SET_KEEPCAPS,…)`] -/// -/// [`prctl(PR_SET_KEEPCAPS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn set_keep_capabilities(enable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_KEEPCAPS, usize::from(enable) as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_NAME/PR_SET_NAME -// - -#[cfg(feature = "alloc")] -const PR_GET_NAME: c_int = 16; - -/// Get the name of the calling thread. -/// -/// # References -/// - [`prctl(PR_GET_NAME,…)`] -/// -/// [`prctl(PR_GET_NAME,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn name() -> io::Result<CString> { - let mut buffer = [0_u8; 16]; - unsafe { prctl_2args(PR_GET_NAME, buffer.as_mut_ptr().cast())? }; - - let len = buffer.iter().position(|&x| x == 0_u8).unwrap_or(0); - CString::new(&buffer[..len]).map_err(|_r| io::Errno::ILSEQ) -} - -const PR_SET_NAME: c_int = 15; - -/// Set the name of the calling thread. -/// -/// Unlike `pthread_setname_np`, this function silently truncates the name to -/// 16 bytes, as the Linux syscall does. -/// -/// # References -/// - [`prctl(PR_SET_NAME,…)`] -/// -/// [`prctl(PR_SET_NAME,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn set_name(name: &CStr) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_NAME, name.as_ptr() as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_SECCOMP/PR_SET_SECCOMP -// - -const PR_GET_SECCOMP: c_int = 21; - -const SECCOMP_MODE_DISABLED: i32 = 0; -const SECCOMP_MODE_STRICT: i32 = 1; -const SECCOMP_MODE_FILTER: i32 = 2; - -/// `SECCOMP_MODE_*` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum SecureComputingMode { - /// Secure computing is not in use. - Disabled = SECCOMP_MODE_DISABLED, - /// Use hard-coded filter. - Strict = SECCOMP_MODE_STRICT, - /// Use user-supplied filter. - Filter = SECCOMP_MODE_FILTER, -} - -impl TryFrom<i32> for SecureComputingMode { - type Error = io::Errno; - - fn try_from(value: i32) -> Result<Self, Self::Error> { - match value { - SECCOMP_MODE_DISABLED => Ok(Self::Disabled), - SECCOMP_MODE_STRICT => Ok(Self::Strict), - SECCOMP_MODE_FILTER => Ok(Self::Filter), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the secure computing mode of the calling thread. -/// -/// If the caller is not in secure computing mode, this returns -/// [`SecureComputingMode::Disabled`]. If the caller is in strict secure -/// computing mode, then this call will cause a [`Signal::KILL`] signal to be -/// sent to the process. If the caller is in filter mode, and this system call -/// is allowed by the seccomp filters, it returns -/// [`SecureComputingMode::Filter`]; otherwise, the process is killed with a -/// [`Signal::KILL`] signal. -/// -/// Since Linux 3.8, the Seccomp field of the `/proc/[pid]/status` file -/// provides a method of obtaining the same information, without the risk that -/// the process is killed; see [the `proc` manual page]. -/// -/// # References -/// - [`prctl(PR_GET_SECCOMP,…)`] -/// -/// [`Signal::KILL`]: crate::signal::Signal::KILL -/// [`prctl(PR_GET_SECCOMP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [the `proc` manual page]: https://man7.org/linux/man-pages/man5/proc.5.html -#[inline] -pub fn secure_computing_mode() -> io::Result<SecureComputingMode> { - unsafe { prctl_1arg(PR_GET_SECCOMP) }.and_then(TryInto::try_into) -} - -const PR_SET_SECCOMP: c_int = 22; - -/// Set the secure computing mode for the calling thread, to limit the -/// available system calls. -/// -/// # References -/// - [`prctl(PR_SET_SECCOMP,…)`] -/// -/// [`prctl(PR_SET_SECCOMP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn set_secure_computing_mode(mode: SecureComputingMode) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_SECCOMP, mode as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_CAPBSET_READ/PR_CAPBSET_DROP -// - -const PR_CAPBSET_READ: c_int = 23; - -/// Linux per-thread capability. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -#[non_exhaustive] -pub enum Capability { - /// In a system with the `_POSIX_CHOWN_RESTRICTED` option defined, this - /// overrides the restriction of changing file ownership and group - /// ownership. - ChangeOwnership = linux_raw_sys::general::CAP_CHOWN, - /// Override all DAC access, including ACL execute access if `_POSIX_ACL` - /// is defined. Excluding DAC access covered by - /// [`Capability::LinuxImmutable`]. - DACOverride = linux_raw_sys::general::CAP_DAC_OVERRIDE, - /// Overrides all DAC restrictions regarding read and search on files and - /// directories, including ACL restrictions if `_POSIX_ACL` is defined. - /// Excluding DAC access covered by [`Capability::LinuxImmutable`]. - DACReadSearch = linux_raw_sys::general::CAP_DAC_READ_SEARCH, - /// Overrides all restrictions about allowed operations on files, where - /// file owner ID must be equal to the user ID, except where - /// [`Capability::FileSetID`] is applicable. It doesn't override MAC and - /// DAC restrictions. - FileOwner = linux_raw_sys::general::CAP_FOWNER, - /// Overrides the following restrictions that the effective user ID shall - /// match the file owner ID when setting the `S_ISUID` and `S_ISGID` bits - /// on that file; that the effective group ID (or one of the supplementary - /// group IDs) shall match the file owner ID when setting the `S_ISGID` bit - /// on that file; that the `S_ISUID` and `S_ISGID` bits are cleared on - /// successful return from `chown` (not implemented). - FileSetID = linux_raw_sys::general::CAP_FSETID, - /// Overrides the restriction that the real or effective user ID of a - /// process sending a signal must match the real or effective user ID of - /// the process receiving the signal. - Kill = linux_raw_sys::general::CAP_KILL, - /// Allows `setgid` manipulation. Allows `setgroups`. Allows forged gids on - /// socket credentials passing. - SetGroupID = linux_raw_sys::general::CAP_SETGID, - /// Allows `set*uid` manipulation (including fsuid). Allows forged pids on - /// socket credentials passing. - SetUserID = linux_raw_sys::general::CAP_SETUID, - /// Without VFS support for capabilities: - /// - Transfer any capability in your permitted set to any pid. - /// - remove any capability in your permitted set from any pid. With VFS - /// support for capabilities (neither of above, but) - /// - Add any capability from current's capability bounding set to the - /// current process' inheritable set. - /// - Allow taking bits out of capability bounding set. - /// - Allow modification of the securebits for a process. - SetPermittedCapabilities = linux_raw_sys::general::CAP_SETPCAP, - /// Allow modification of `S_IMMUTABLE` and `S_APPEND` file attributes. - LinuxImmutable = linux_raw_sys::general::CAP_LINUX_IMMUTABLE, - /// Allows binding to TCP/UDP sockets below 1024. Allows binding to ATM - /// VCIs below 32. - NetBindService = linux_raw_sys::general::CAP_NET_BIND_SERVICE, - /// Allow broadcasting, listen to multicast. - NetBroadcast = linux_raw_sys::general::CAP_NET_BROADCAST, - /// Allow interface configuration. Allow administration of IP firewall, - /// masquerading and accounting. Allow setting debug option on sockets. - /// Allow modification of routing tables. Allow setting arbitrary - /// process / process group ownership on sockets. Allow binding to any - /// address for transparent proxying (also via [`Capability::NetRaw`]). - /// Allow setting TOS (type of service). Allow setting promiscuous - /// mode. Allow clearing driver statistics. Allow multicasting. Allow - /// read/write of device-specific registers. Allow activation of ATM - /// control sockets. - NetAdmin = linux_raw_sys::general::CAP_NET_ADMIN, - /// Allow use of `RAW` sockets. Allow use of `PACKET` sockets. Allow - /// binding to any address for transparent proxying (also via - /// [`Capability::NetAdmin`]). - NetRaw = linux_raw_sys::general::CAP_NET_RAW, - /// Allow locking of shared memory segments. Allow mlock and mlockall - /// (which doesn't really have anything to do with IPC). - IPCLock = linux_raw_sys::general::CAP_IPC_LOCK, - /// Override IPC ownership checks. - IPCOwner = linux_raw_sys::general::CAP_IPC_OWNER, - /// Insert and remove kernel modules - modify kernel without limit. - SystemModule = linux_raw_sys::general::CAP_SYS_MODULE, - /// Allow ioperm/iopl access. Allow sending USB messages to any device via - /// `/dev/bus/usb`. - SystemRawIO = linux_raw_sys::general::CAP_SYS_RAWIO, - /// Allow use of `chroot`. - SystemChangeRoot = linux_raw_sys::general::CAP_SYS_CHROOT, - /// Allow `ptrace` of any process. - SystemProcessTrace = linux_raw_sys::general::CAP_SYS_PTRACE, - /// Allow configuration of process accounting. - SystemProcessAccounting = linux_raw_sys::general::CAP_SYS_PACCT, - /// Allow configuration of the secure attention key. Allow administration - /// of the random device. Allow examination and configuration of disk - /// quotas. Allow setting the domainname. Allow setting the hostname. - /// Allow `mount` and `umount`, setting up new smb connection. - /// Allow some autofs root ioctls. Allow nfsservctl. Allow - /// `VM86_REQUEST_IRQ`. Allow to read/write pci config on alpha. Allow - /// `irix_prctl` on mips (setstacksize). Allow flushing all cache on - /// m68k (`sys_cacheflush`). Allow removing semaphores. Used instead of - /// [`Capability::ChangeOwnership`] to "chown" IPC message queues, - /// semaphores and shared memory. Allow locking/unlocking of shared - /// memory segment. Allow turning swap on/off. Allow forged pids on - /// socket credentials passing. Allow setting readahead and - /// flushing buffers on block devices. Allow setting geometry in floppy - /// driver. Allow turning DMA on/off in `xd` driver. Allow - /// administration of md devices (mostly the above, but some - /// extra ioctls). Allow tuning the ide driver. Allow access to the nvram - /// device. Allow administration of `apm_bios`, serial and bttv (TV) - /// device. Allow manufacturer commands in isdn CAPI support driver. - /// Allow reading non-standardized portions of pci configuration space. - /// Allow DDI debug ioctl on sbpcd driver. Allow setting up serial ports. - /// Allow sending raw qic-117 commands. Allow enabling/disabling tagged - /// queuing on SCSI controllers and sending arbitrary SCSI commands. - /// Allow setting encryption key on loopback filesystem. Allow setting - /// zone reclaim policy. Allow everything under - /// [`Capability::BerkeleyPacketFilters`] and - /// [`Capability::PerformanceMonitoring`] for backward compatibility. - SystemAdmin = linux_raw_sys::general::CAP_SYS_ADMIN, - /// Allow use of `reboot`. - SystemBoot = linux_raw_sys::general::CAP_SYS_BOOT, - /// Allow raising priority and setting priority on other (different UID) - /// processes. Allow use of FIFO and round-robin (realtime) scheduling - /// on own processes and setting the scheduling algorithm used by - /// another process. Allow setting cpu affinity on other processes. - /// Allow setting realtime ioprio class. Allow setting ioprio class on - /// other processes. - SystemNice = linux_raw_sys::general::CAP_SYS_NICE, - /// Override resource limits. Set resource limits. Override quota limits. - /// Override reserved space on ext2 filesystem. Modify data journaling - /// mode on ext3 filesystem (uses journaling resources). NOTE: ext2 - /// honors fsuid when checking for resource overrides, so you can - /// override using fsuid too. Override size restrictions on IPC message - /// queues. Allow more than 64hz interrupts from the real-time clock. - /// Override max number of consoles on console allocation. Override max - /// number of keymaps. Control memory reclaim behavior. - SystemResource = linux_raw_sys::general::CAP_SYS_RESOURCE, - /// Allow manipulation of system clock. Allow `irix_stime` on mips. Allow - /// setting the real-time clock. - SystemTime = linux_raw_sys::general::CAP_SYS_TIME, - /// Allow configuration of tty devices. Allow `vhangup` of tty. - SystemTTYConfig = linux_raw_sys::general::CAP_SYS_TTY_CONFIG, - /// Allow the privileged aspects of `mknod`. - MakeNode = linux_raw_sys::general::CAP_MKNOD, - /// Allow taking of leases on files. - Lease = linux_raw_sys::general::CAP_LEASE, - /// Allow writing the audit log via unicast netlink socket. - AuditWrite = linux_raw_sys::general::CAP_AUDIT_WRITE, - /// Allow configuration of audit via unicast netlink socket. - AuditControl = linux_raw_sys::general::CAP_AUDIT_CONTROL, - /// Set or remove capabilities on files. Map `uid=0` into a child user - /// namespace. - SetFileCapabilities = linux_raw_sys::general::CAP_SETFCAP, - /// Override MAC access. The base kernel enforces no MAC policy. An LSM may - /// enforce a MAC policy, and if it does and it chooses to implement - /// capability based overrides of that policy, this is the capability it - /// should use to do so. - MACOverride = linux_raw_sys::general::CAP_MAC_OVERRIDE, - /// Allow MAC configuration or state changes. The base kernel requires no - /// MAC configuration. An LSM may enforce a MAC policy, and if it does and - /// it chooses to implement capability based checks on modifications to - /// that policy or the data required to maintain it, this is the capability - /// it should use to do so. - MACAdmin = linux_raw_sys::general::CAP_MAC_ADMIN, - /// Allow configuring the kernel's `syslog` (`printk` behaviour). - SystemLog = linux_raw_sys::general::CAP_SYSLOG, - /// Allow triggering something that will wake the system. - WakeAlarm = linux_raw_sys::general::CAP_WAKE_ALARM, - /// Allow preventing system suspends. - BlockSuspend = linux_raw_sys::general::CAP_BLOCK_SUSPEND, - /// Allow reading the audit log via multicast netlink socket. - AuditRead = linux_raw_sys::general::CAP_AUDIT_READ, - /// Allow system performance and observability privileged operations using - /// `perf_events`, `i915_perf` and other kernel subsystems. - PerformanceMonitoring = linux_raw_sys::general::CAP_PERFMON, - /// This capability allows the following BPF operations: - /// - Creating all types of BPF maps - /// - Advanced verifier features - /// - Indirect variable access - /// - Bounded loops - /// - BPF to BPF function calls - /// - Scalar precision tracking - /// - Larger complexity limits - /// - Dead code elimination - /// - And potentially other features - /// - Loading BPF Type Format (BTF) data - /// - Retrieve `xlated` and JITed code of BPF programs - /// - Use `bpf_spin_lock` helper - /// - /// [`Capability::PerformanceMonitoring`] relaxes the verifier checks - /// further: - /// - BPF progs can use of pointer-to-integer conversions - /// - speculation attack hardening measures are bypassed - /// - `bpf_probe_read` to read arbitrary kernel memory is allowed - /// - `bpf_trace_printk` to print kernel memory is allowed - /// - /// [`Capability::SystemAdmin`] is required to use `bpf_probe_write_user`. - /// - /// [`Capability::SystemAdmin`] is required to iterate system-wide loaded - /// programs, maps, links, and BTFs, and convert their IDs to file - /// descriptors. - /// - /// [`Capability::PerformanceMonitoring`] and - /// [`Capability::BerkeleyPacketFilters`] are required to load tracing - /// programs. [`Capability::NetAdmin`] and - /// [`Capability::BerkeleyPacketFilters`] are required to load - /// networking programs. - BerkeleyPacketFilters = linux_raw_sys::general::CAP_BPF, - /// Allow checkpoint/restore related operations. Allow PID selection during - /// `clone3`. Allow writing to `ns_last_pid`. - CheckpointRestore = linux_raw_sys::general::CAP_CHECKPOINT_RESTORE, -} - -/// Check if the specified capability is in the calling thread's capability -/// bounding set. -/// -/// # References -/// - [`prctl(PR_CAPBSET_READ,…)`] -/// -/// [`prctl(PR_CAPBSET_READ,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn capability_is_in_bounding_set(capability: Capability) -> io::Result<bool> { - unsafe { prctl_2args(PR_CAPBSET_READ, capability as usize as *mut _) }.map(|r| r != 0) -} - -const PR_CAPBSET_DROP: c_int = 24; - -/// If the calling thread has the [`Capability::SetPermittedCapabilities`] -/// capability within its user namespace, then drop the specified capability -/// from the thread's capability bounding set. -/// -/// # References -/// - [`prctl(PR_CAPBSET_DROP,…)`] -/// -/// [`prctl(PR_CAPBSET_DROP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn remove_capability_from_bounding_set(capability: Capability) -> io::Result<()> { - unsafe { prctl_2args(PR_CAPBSET_DROP, capability as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_SECUREBITS/PR_SET_SECUREBITS -// - -const PR_GET_SECUREBITS: c_int = 27; - -bitflags! { - /// `SECBIT_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct CapabilitiesSecureBits: u32 { - /// If this bit is set, then the kernel does not grant capabilities - /// when a `set-user-ID-root` program is executed, or when a process - /// with an effective or real UID of [`Uid::ROOT`] calls `execve`. - const NO_ROOT = 1_u32 << 0; - /// Set [`NO_ROOT`] irreversibly. - /// - /// [`NO_ROOT`]: Self::NO_ROOT - const NO_ROOT_LOCKED = 1_u32 << 1; - /// Setting this flag stops the kernel from adjusting the process' - /// permitted, effective, and ambient capability sets when the thread's - /// effective and filesystem UIDs are switched between zero and nonzero - /// values. - const NO_SETUID_FIXUP = 1_u32 << 2; - /// Set [`NO_SETUID_FIXUP`] irreversibly. - /// - /// [`NO_SETUID_FIXUP`]: Self::NO_SETUID_FIXUP - const NO_SETUID_FIXUP_LOCKED = 1_u32 << 3; - /// Setting this flag allows a thread that has one or more 0 UIDs to - /// retain capabilities in its permitted set when it switches all of - /// its UIDs to nonzero values. - const KEEP_CAPS = 1_u32 << 4; - /// Set [`KEEP_CAPS`] irreversibly. - /// - /// [`KEEP_CAPS`]: Self::KEEP_CAPS - const KEEP_CAPS_LOCKED = 1_u32 << 5; - /// Setting this flag disallows raising ambient capabilities via the - /// `prctl`'s `PR_CAP_AMBIENT_RAISE` operation. - const NO_CAP_AMBIENT_RAISE = 1_u32 << 6; - /// Set [`NO_CAP_AMBIENT_RAISE`] irreversibly. - /// - /// [`NO_CAP_AMBIENT_RAISE`]: Self::NO_CAP_AMBIENT_RAISE - const NO_CAP_AMBIENT_RAISE_LOCKED = 1_u32 << 7; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Get the `securebits` flags of the calling thread. -/// -/// # References -/// - [`prctl(PR_GET_SECUREBITS,…)`] -/// -/// [`prctl(PR_GET_SECUREBITS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn capabilities_secure_bits() -> io::Result<CapabilitiesSecureBits> { - let r = unsafe { prctl_1arg(PR_GET_SECUREBITS)? } as c_uint; - CapabilitiesSecureBits::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_SET_SECUREBITS: c_int = 28; - -/// Set the `securebits` flags of the calling thread. -/// -/// # References -/// - [`prctl(PR_SET_SECUREBITS,…)`] -/// -/// [`prctl(PR_SET_SECUREBITS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn set_capabilities_secure_bits(bits: CapabilitiesSecureBits) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_SECUREBITS, bits.bits() as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_TIMERSLACK/PR_SET_TIMERSLACK -// - -const PR_GET_TIMERSLACK: c_int = 30; - -/// Get the `current` timer slack value of the calling thread. -/// -/// # References -/// - [`prctl(PR_GET_TIMERSLACK,…)`] -/// -/// [`prctl(PR_GET_TIMERSLACK,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn current_timer_slack() -> io::Result<u64> { - unsafe { prctl_1arg(PR_GET_TIMERSLACK) }.map(|r| r as u64) -} - -const PR_SET_TIMERSLACK: c_int = 29; - -/// Sets the `current` timer slack value for the calling thread. -/// -/// # References -/// - [`prctl(PR_SET_TIMERSLACK,…)`] -/// -/// [`prctl(PR_SET_TIMERSLACK,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn set_current_timer_slack(value: Option<NonZeroU64>) -> io::Result<()> { - let value = usize::try_from(value.map_or(0, NonZeroU64::get)).map_err(|_r| io::Errno::RANGE)?; - unsafe { prctl_2args(PR_SET_TIMERSLACK, value as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_NO_NEW_PRIVS/PR_SET_NO_NEW_PRIVS -// - -const PR_GET_NO_NEW_PRIVS: c_int = 39; - -/// Get the value of the `no_new_privs` attribute for the calling thread. -/// -/// # References -/// - [`prctl(PR_GET_NO_NEW_PRIVS,…)`] -/// -/// [`prctl(PR_GET_NO_NEW_PRIVS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn no_new_privs() -> io::Result<bool> { - unsafe { prctl_1arg(PR_GET_NO_NEW_PRIVS) }.map(|r| r != 0) -} - -const PR_SET_NO_NEW_PRIVS: c_int = 38; - -/// Set the calling thread's `no_new_privs` attribute. -/// -/// # References -/// - [`prctl(PR_SET_NO_NEW_PRIVS,…)`] -/// -/// [`prctl(PR_SET_NO_NEW_PRIVS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn set_no_new_privs(no_new_privs: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_NO_NEW_PRIVS, usize::from(no_new_privs) as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_TID_ADDRESS -// - -const PR_GET_TID_ADDRESS: c_int = 40; - -/// Get the `clear_child_tid` address set by `set_tid_address` -/// and `clone`'s `CLONE_CHILD_CLEARTID` flag. -/// -/// # References -/// - [`prctl(PR_GET_TID_ADDRESS,…)`] -/// -/// [`prctl(PR_GET_TID_ADDRESS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn get_clear_child_tid_address() -> io::Result<Option<NonNull<c_void>>> { - unsafe { prctl_get_at_arg2_optional::<*mut c_void>(PR_GET_TID_ADDRESS) }.map(NonNull::new) -} - -// -// PR_GET_THP_DISABLE/PR_SET_THP_DISABLE -// - -const PR_GET_THP_DISABLE: c_int = 42; - -/// Get the current setting of the `THP disable` flag for the calling thread. -/// -/// # References -/// - [`prctl(PR_GET_THP_DISABLE,…)`] -/// -/// [`prctl(PR_GET_THP_DISABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn transparent_huge_pages_are_disabled() -> io::Result<bool> { - unsafe { prctl_1arg(PR_GET_THP_DISABLE) }.map(|r| r != 0) -} - -const PR_SET_THP_DISABLE: c_int = 41; - -/// Set the state of the `THP disable` flag for the calling thread. -/// -/// # References -/// - [`prctl(PR_SET_THP_DISABLE,…)`] -/// -/// [`prctl(PR_SET_THP_DISABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn disable_transparent_huge_pages(thp_disable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_THP_DISABLE, usize::from(thp_disable) as *mut _) }.map(|_r| ()) -} - -// -// PR_CAP_AMBIENT -// - -const PR_CAP_AMBIENT: c_int = 47; - -const PR_CAP_AMBIENT_IS_SET: usize = 1; - -/// Check if the specified capability is in the ambient set. -/// -/// # References -/// - [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,…)`] -/// -/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn capability_is_in_ambient_set(capability: Capability) -> io::Result<bool> { - let cap = capability as usize as *mut _; - unsafe { prctl_3args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET as *mut _, cap) }.map(|r| r != 0) -} - -const PR_CAP_AMBIENT_CLEAR_ALL: usize = 4; - -/// Remove all capabilities from the ambient set. -/// -/// # References -/// - [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,…)`] -/// -/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn clear_ambient_capability_set() -> io::Result<()> { - unsafe { prctl_2args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL as *mut _) }.map(|_r| ()) -} - -const PR_CAP_AMBIENT_RAISE: usize = 2; -const PR_CAP_AMBIENT_LOWER: usize = 3; - -/// Add or remove the specified capability to the ambient set. -/// -/// # References -/// - [`prctl(PR_CAP_AMBIENT,…)`] -/// -/// [`prctl(PR_CAP_AMBIENT,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn configure_capability_in_ambient_set(capability: Capability, enable: bool) -> io::Result<()> { - let sub_operation = if enable { - PR_CAP_AMBIENT_RAISE - } else { - PR_CAP_AMBIENT_LOWER - }; - let cap = capability as usize as *mut _; - - unsafe { prctl_3args(PR_CAP_AMBIENT, sub_operation as *mut _, cap) }.map(|_r| ()) -} - -// -// PR_SVE_GET_VL/PR_SVE_SET_VL -// - -const PR_SVE_GET_VL: c_int = 51; - -const PR_SVE_VL_LEN_MASK: u32 = 0xffff; -const PR_SVE_VL_INHERIT: u32 = 1_u32 << 17; - -/// Scalable Vector Extension vector length configuration. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct SVEVectorLengthConfig { - /// Vector length in bytes. - pub vector_length_in_bytes: u32, - /// Vector length inherited across `execve`. - pub vector_length_inherited_across_execve: bool, -} - -/// Get the thread's current SVE vector length configuration. -/// -/// # References -/// - [`prctl(PR_SVE_GET_VL,…)`] -/// -/// [`prctl(PR_SVE_GET_VL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn sve_vector_length_configuration() -> io::Result<SVEVectorLengthConfig> { - let bits = unsafe { prctl_1arg(PR_SVE_GET_VL)? } as c_uint; - Ok(SVEVectorLengthConfig { - vector_length_in_bytes: bits & PR_SVE_VL_LEN_MASK, - vector_length_inherited_across_execve: (bits & PR_SVE_VL_INHERIT) != 0, - }) -} - -const PR_SVE_SET_VL: c_int = 50; - -const PR_SVE_SET_VL_ONEXEC: u32 = 1_u32 << 18; - -/// Configure the thread's vector length of Scalable Vector Extension. -/// -/// # References -/// - [`prctl(PR_SVE_SET_VL,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. -/// -/// [`prctl(PR_SVE_SET_VL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub unsafe fn set_sve_vector_length_configuration( - vector_length_in_bytes: usize, - vector_length_inherited_across_execve: bool, - defer_change_to_next_execve: bool, -) -> io::Result<()> { - let vector_length_in_bytes = - u32::try_from(vector_length_in_bytes).map_err(|_r| io::Errno::RANGE)?; - - let mut bits = vector_length_in_bytes & PR_SVE_VL_LEN_MASK; - - if vector_length_inherited_across_execve { - bits |= PR_SVE_VL_INHERIT; - } - - if defer_change_to_next_execve { - bits |= PR_SVE_SET_VL_ONEXEC; - } - - prctl_2args(PR_SVE_SET_VL, bits as usize as *mut _).map(|_r| ()) -} - -// -// PR_PAC_RESET_KEYS -// - -const PR_PAC_RESET_KEYS: c_int = 54; - -/// Securely reset the thread's pointer authentication keys to fresh random -/// values generated by the kernel. -/// -/// # References -/// - [`prctl(PR_PAC_RESET_KEYS,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, -/// as detailed in the references above. -/// -/// [`prctl(PR_PAC_RESET_KEYS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub unsafe fn reset_pointer_authentication_keys( - keys: Option<PointerAuthenticationKeys>, -) -> io::Result<()> { - let keys = keys.as_ref().map_or(0_u32, PointerAuthenticationKeys::bits); - prctl_2args(PR_PAC_RESET_KEYS, keys as usize as *mut _).map(|_r| ()) -} - -// -// PR_GET_TAGGED_ADDR_CTRL/PR_SET_TAGGED_ADDR_CTRL -// - -const PR_GET_TAGGED_ADDR_CTRL: c_int = 56; - -const PR_MTE_TAG_SHIFT: u32 = 3; -const PR_MTE_TAG_MASK: u32 = 0xffff_u32 << PR_MTE_TAG_SHIFT; - -bitflags! { - /// Zero means addresses that are passed for the purpose of being - /// dereferenced by the kernel must be untagged. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct TaggedAddressMode: u32 { - /// Addresses that are passed for the purpose of being dereferenced by - /// the kernel may be tagged. - const ENABLED = 1_u32 << 0; - /// Synchronous tag check fault mode. - const TCF_SYNC = 1_u32 << 1; - /// Asynchronous tag check fault mode. - const TCF_ASYNC = 1_u32 << 2; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Get the current tagged address mode for the calling thread. -/// -/// # References -/// - [`prctl(PR_GET_TAGGED_ADDR_CTRL,…)`] -/// -/// [`prctl(PR_GET_TAGGED_ADDR_CTRL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub fn current_tagged_address_mode() -> io::Result<(Option<TaggedAddressMode>, u32)> { - let r = unsafe { prctl_1arg(PR_GET_TAGGED_ADDR_CTRL)? } as c_uint; - let mode = r & 0b111_u32; - let mte_tag = (r & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT; - Ok((TaggedAddressMode::from_bits(mode), mte_tag)) -} - -const PR_SET_TAGGED_ADDR_CTRL: c_int = 55; - -/// Controls support for passing tagged user-space addresses to the kernel. -/// -/// # References -/// - [`prctl(PR_SET_TAGGED_ADDR_CTRL,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_TAGGED_ADDR_CTRL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub unsafe fn set_current_tagged_address_mode( - mode: Option<TaggedAddressMode>, - mte_tag: u32, -) -> io::Result<()> { - let config = mode.as_ref().map_or(0_u32, TaggedAddressMode::bits) - | ((mte_tag << PR_MTE_TAG_SHIFT) & PR_MTE_TAG_MASK); - prctl_2args(PR_SET_TAGGED_ADDR_CTRL, config as usize as *mut _).map(|_r| ()) -} - -// -// PR_SET_SYSCALL_USER_DISPATCH -// - -const PR_SET_SYSCALL_USER_DISPATCH: c_int = 59; - -const PR_SYS_DISPATCH_OFF: usize = 0; - -/// Disable Syscall User Dispatch mechanism. -/// -/// # References -/// - [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub unsafe fn disable_syscall_user_dispatch() -> io::Result<()> { - prctl_2args(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_OFF as *mut _).map(|_r| ()) -} - -const PR_SYS_DISPATCH_ON: usize = 1; - -/// Allow system calls to be executed. -const SYSCALL_DISPATCH_FILTER_ALLOW: u8 = 0; -/// Block system calls from executing. -const SYSCALL_DISPATCH_FILTER_BLOCK: u8 = 1; - -/// Value of the fast switch flag controlling system calls user dispatch -/// mechanism without the need to issue a syscall. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u8)] -pub enum SysCallUserDispatchFastSwitch { - /// System calls are allowed to execute. - Allow = SYSCALL_DISPATCH_FILTER_ALLOW, - /// System calls are blocked from executing. - Block = SYSCALL_DISPATCH_FILTER_BLOCK, -} - -impl TryFrom<u8> for SysCallUserDispatchFastSwitch { - type Error = io::Errno; - - fn try_from(value: u8) -> Result<Self, Self::Error> { - match value { - SYSCALL_DISPATCH_FILTER_ALLOW => Ok(Self::Allow), - SYSCALL_DISPATCH_FILTER_BLOCK => Ok(Self::Block), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Enable Syscall User Dispatch mechanism. -/// -/// # References -/// - [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -pub unsafe fn enable_syscall_user_dispatch( - always_allowed_region: &[u8], - fast_switch_flag: &AtomicU8, -) -> io::Result<()> { - syscalls::prctl( - PR_SET_SYSCALL_USER_DISPATCH, - PR_SYS_DISPATCH_ON as *mut _, - always_allowed_region.as_ptr() as *mut _, - always_allowed_region.len() as *mut _, - as_ptr(fast_switch_flag) as *mut _, - ) - .map(|_r| ()) -} - -// -// PR_SCHED_CORE -// - -const PR_SCHED_CORE: c_int = 62; - -const PR_SCHED_CORE_GET: usize = 0; - -const PR_SCHED_CORE_SCOPE_THREAD: u32 = 0; -const PR_SCHED_CORE_SCOPE_THREAD_GROUP: u32 = 1; -const PR_SCHED_CORE_SCOPE_PROCESS_GROUP: u32 = 2; - -/// `PR_SCHED_CORE_SCOPE_*` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum CoreSchedulingScope { - /// Operation will be performed for the thread. - Thread = PR_SCHED_CORE_SCOPE_THREAD, - /// Operation will be performed for all tasks in the task group of the - /// process. - ThreadGroup = PR_SCHED_CORE_SCOPE_THREAD_GROUP, - /// Operation will be performed for all processes in the process group. - ProcessGroup = PR_SCHED_CORE_SCOPE_PROCESS_GROUP, -} - -impl TryFrom<u32> for CoreSchedulingScope { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_SCHED_CORE_SCOPE_THREAD => Ok(Self::Thread), - PR_SCHED_CORE_SCOPE_THREAD_GROUP => Ok(Self::ThreadGroup), - PR_SCHED_CORE_SCOPE_PROCESS_GROUP => Ok(Self::ProcessGroup), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get core scheduling cookie of a process. -/// -/// # References -/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_GET,…)`] -/// -/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_GET,…)`]: https://www.kernel.org/doc/html/v6.13/admin-guide/hw-vuln/core-scheduling.html -#[inline] -pub fn core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<u64> { - let mut value: MaybeUninit<u64> = MaybeUninit::uninit(); - unsafe { - syscalls::prctl( - PR_SCHED_CORE, - PR_SCHED_CORE_GET as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, - value.as_mut_ptr().cast(), - )?; - Ok(value.assume_init()) - } -} - -const PR_SCHED_CORE_CREATE: usize = 1; - -/// Create unique core scheduling cookie. -/// -/// # References -/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_CREATE,…)`] -/// -/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_CREATE,…)`]: https://www.kernel.org/doc/html/v6.13/admin-guide/hw-vuln/core-scheduling.html -#[inline] -pub fn create_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> { - unsafe { - syscalls::prctl( - PR_SCHED_CORE, - PR_SCHED_CORE_CREATE as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, - ptr::null_mut(), - ) - .map(|_r| ()) - } -} - -const PR_SCHED_CORE_SHARE_TO: usize = 2; - -/// Push core scheduling cookie to a process. -/// -/// # References -/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_TO,…)`] -/// -/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_TO,…)`]: https://www.kernel.org/doc/html/v6.13/admin-guide/hw-vuln/core-scheduling.html -#[inline] -pub fn push_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> { - unsafe { - syscalls::prctl( - PR_SCHED_CORE, - PR_SCHED_CORE_SHARE_TO as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, - ptr::null_mut(), - ) - .map(|_r| ()) - } -} - -const PR_SCHED_CORE_SHARE_FROM: usize = 3; - -/// Pull core scheduling cookie from a process. -/// -/// # References -/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_FROM,…)`] -/// -/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_FROM,…)`]: https://www.kernel.org/doc/html/v6.13/admin-guide/hw-vuln/core-scheduling.html -#[inline] -pub fn pull_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> { - unsafe { - syscalls::prctl( - PR_SCHED_CORE, - PR_SCHED_CORE_SHARE_FROM as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, - ptr::null_mut(), - ) - .map(|_r| ()) - } -} diff --git a/vendor/rustix/src/thread/sched.rs b/vendor/rustix/src/thread/sched.rs deleted file mode 100644 index 034b0261..00000000 --- a/vendor/rustix/src/thread/sched.rs +++ /dev/null @@ -1,161 +0,0 @@ -use crate::pid::Pid; -use crate::{backend, io}; -use core::{fmt, hash}; - -/// `CpuSet` represents a bit-mask of CPUs. -/// -/// `CpuSet`s are used by [`sched_setaffinity`] and [`sched_getaffinity`], for -/// example. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/CPU_SET.3.html -/// [`sched_setaffinity`]: crate::thread::sched_setaffinity -/// [`sched_getaffinity`]: crate::thread::sched_getaffinity -#[repr(transparent)] -#[derive(Clone, Copy)] -pub struct CpuSet { - cpu_set: backend::thread::types::RawCpuSet, -} - -impl CpuSet { - /// The maximum number of CPU in `CpuSet`. - pub const MAX_CPU: usize = backend::thread::types::CPU_SETSIZE; - - /// Create a new and empty `CpuSet`. - #[inline] - pub fn new() -> Self { - Self { - cpu_set: backend::thread::types::raw_cpu_set_new(), - } - } - - /// Test to see if a CPU is in the `CpuSet`. - /// - /// `field` is the CPU id to test. - #[inline] - pub fn is_set(&self, field: usize) -> bool { - backend::thread::cpu_set::CPU_ISSET(field, &self.cpu_set) - } - - /// Add a CPU to `CpuSet`. - /// - /// `field` is the CPU id to add. - #[inline] - pub fn set(&mut self, field: usize) { - backend::thread::cpu_set::CPU_SET(field, &mut self.cpu_set) - } - - /// Remove a CPU from `CpuSet`. - /// - /// `field` is the CPU id to remove. - #[inline] - pub fn unset(&mut self, field: usize) { - backend::thread::cpu_set::CPU_CLR(field, &mut self.cpu_set) - } - - /// Count the number of CPUs set in the `CpuSet`. - #[cfg(linux_kernel)] - #[inline] - pub fn count(&self) -> u32 { - backend::thread::cpu_set::CPU_COUNT(&self.cpu_set) - } - - /// Zeroes the `CpuSet`. - #[inline] - pub fn clear(&mut self) { - backend::thread::cpu_set::CPU_ZERO(&mut self.cpu_set) - } -} - -impl Default for CpuSet { - #[inline] - fn default() -> Self { - Self::new() - } -} - -impl fmt::Debug for CpuSet { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "CpuSet {{")?; - let mut first = true; - for i in 0..Self::MAX_CPU { - if self.is_set(i) { - if first { - write!(f, " ")?; - first = false; - } else { - write!(f, ", ")?; - } - write!(f, "cpu{}", i)?; - } - } - write!(f, " }}") - } -} - -impl hash::Hash for CpuSet { - fn hash<H: hash::Hasher>(&self, state: &mut H) { - for i in 0..Self::MAX_CPU { - self.is_set(i).hash(state); - } - } -} - -impl Eq for CpuSet {} - -impl PartialEq for CpuSet { - fn eq(&self, other: &Self) -> bool { - backend::thread::cpu_set::CPU_EQUAL(&self.cpu_set, &other.cpu_set) - } -} - -/// `sched_setaffinity(pid, cpuset)`—Set a thread's CPU affinity mask. -/// -/// `pid` is the thread ID to update. If pid is `None`, then the current thread -/// is updated. -/// -/// The `CpuSet` argument specifies the set of CPUs on which the thread will be -/// eligible to run. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html -#[inline] -pub fn sched_setaffinity(pid: Option<Pid>, cpuset: &CpuSet) -> io::Result<()> { - backend::thread::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) -} - -/// `sched_getaffinity(pid)`—Get a thread's CPU affinity mask. -/// -/// `pid` is the thread ID to check. If pid is `None`, then the current thread -/// is checked. -/// -/// Returns the set of CPUs on which the thread is eligible to run. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html -#[inline] -pub fn sched_getaffinity(pid: Option<Pid>) -> io::Result<CpuSet> { - let mut cpuset = CpuSet::new(); - backend::thread::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) -} - -/// `sched_getcpu()`—Get the CPU that the current thread is currently on. -/// -/// # References -/// - [Linux] -/// - [DragonFly BSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man3/sched_getcpu.3.html -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sched_getcpu§ion=2 -// FreeBSD added `sched_getcpu` in 13.0. -#[cfg(any(linux_kernel, target_os = "dragonfly"))] -#[inline] -pub fn sched_getcpu() -> usize { - backend::thread::syscalls::sched_getcpu() -} diff --git a/vendor/rustix/src/thread/sched_yield.rs b/vendor/rustix/src/thread/sched_yield.rs deleted file mode 100644 index e630a95c..00000000 --- a/vendor/rustix/src/thread/sched_yield.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::backend; - -/// `sched_yield()`—Hints to the OS that other processes should run. -/// -/// This function always succeeds. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sched_yield.html -/// [Linux]: https://man7.org/linux/man-pages/man2/sched_yield.2.html -#[inline] -pub fn sched_yield() { - backend::thread::syscalls::sched_yield() -} diff --git a/vendor/rustix/src/thread/setns.rs b/vendor/rustix/src/thread/setns.rs deleted file mode 100644 index 0eaee2f2..00000000 --- a/vendor/rustix/src/thread/setns.rs +++ /dev/null @@ -1,139 +0,0 @@ -use bitflags::bitflags; -use linux_raw_sys::general::{ - CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, - CLONE_NEWTIME, CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SYSVSEM, -}; - -use crate::backend::c::c_int; -use crate::backend::thread::syscalls; -use crate::fd::BorrowedFd; -use crate::io; - -bitflags! { - /// Thread name space type. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ThreadNameSpaceType: u32 { - /// Time name space. - const TIME = CLONE_NEWTIME; - /// Mount name space. - const MOUNT = CLONE_NEWNS; - /// Control group (CGroup) name space. - const CONTROL_GROUP = CLONE_NEWCGROUP; - /// `Host name` and `NIS domain name` (UTS) name space. - const HOST_NAME_AND_NIS_DOMAIN_NAME = CLONE_NEWUTS; - /// Inter-process communication (IPC) name space. - const INTER_PROCESS_COMMUNICATION = CLONE_NEWIPC; - /// User name space. - const USER = CLONE_NEWUSER; - /// Process ID name space. - const PROCESS_ID = CLONE_NEWPID; - /// Network name space. - const NETWORK = CLONE_NEWNET; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Type of name space referred to by a link. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum LinkNameSpaceType { - /// Time name space. - Time = CLONE_NEWTIME, - /// Mount name space. - Mount = CLONE_NEWNS, - /// Control group (CGroup) name space. - ControlGroup = CLONE_NEWCGROUP, - /// `Host name` and `NIS domain name` (UTS) name space. - HostNameAndNISDomainName = CLONE_NEWUTS, - /// Inter-process communication (IPC) name space. - InterProcessCommunication = CLONE_NEWIPC, - /// User name space. - User = CLONE_NEWUSER, - /// Process ID name space. - ProcessID = CLONE_NEWPID, - /// Network name space. - Network = CLONE_NEWNET, -} - -bitflags! { - /// `CLONE_*` for use with [`unshare`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UnshareFlags: u32 { - /// `CLONE_FILES` - const FILES = CLONE_FILES; - /// `CLONE_FS` - const FS = CLONE_FS; - /// `CLONE_NEWCGROUP` - const NEWCGROUP = CLONE_NEWCGROUP; - /// `CLONE_NEWIPC` - const NEWIPC = CLONE_NEWIPC; - /// `CLONE_NEWNET` - const NEWNET = CLONE_NEWNET; - /// `CLONE_NEWNS` - const NEWNS = CLONE_NEWNS; - /// `CLONE_NEWPID` - const NEWPID = CLONE_NEWPID; - /// `CLONE_NEWTIME` - const NEWTIME = CLONE_NEWTIME; - /// `CLONE_NEWUSER` - const NEWUSER = CLONE_NEWUSER; - /// `CLONE_NEWUTS` - const NEWUTS = CLONE_NEWUTS; - /// `CLONE_SYSVSEM` - const SYSVSEM = CLONE_SYSVSEM; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Reassociate the calling thread with the namespace associated with link -/// referred to by `fd`. -/// -/// `fd` must refer to one of the magic links in a `/proc/[pid]/ns/` directory, -/// or a bind mount to such a link. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html -#[doc(alias = "setns")] -pub fn move_into_link_name_space( - fd: BorrowedFd<'_>, - allowed_type: Option<LinkNameSpaceType>, -) -> io::Result<()> { - let allowed_type = allowed_type.map_or(0, |t| t as c_int); - syscalls::setns(fd, allowed_type).map(|_r| ()) -} - -/// Atomically move the calling thread into one or more of the same namespaces -/// as the thread referred to by `fd`. -/// -/// `fd` must refer to a thread ID. See: `pidfd_open` and `clone`. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/setns.2.html -#[doc(alias = "setns")] -pub fn move_into_thread_name_spaces( - fd: BorrowedFd<'_>, - allowed_types: ThreadNameSpaceType, -) -> io::Result<()> { - syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r| ()) -} - -/// `unshare(flags)`—Disassociate parts of the current thread's execution -/// context with other threads. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/unshare.2.html -pub fn unshare(flags: UnshareFlags) -> io::Result<()> { - syscalls::unshare(flags) -} diff --git a/vendor/rustix/src/time/clock.rs b/vendor/rustix/src/time/clock.rs deleted file mode 100644 index bdc2b11c..00000000 --- a/vendor/rustix/src/time/clock.rs +++ /dev/null @@ -1,108 +0,0 @@ -use crate::{backend, io}; - -pub use crate::timespec::{Nsecs, Secs, Timespec}; - -/// `clockid_t` -#[cfg(not(target_os = "wasi"))] -pub use crate::clockid::{ClockId, DynamicClockId}; - -/// `clock_getres(id)`—Returns the resolution of a clock. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_getres.html -/// [Linux]: https://man7.org/linux/man-pages/man2/clock_getres.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=clock_getres&sektion=2 -/// [NetBSD]: https://man.netbsd.org/clock_getres.2 -/// [OpenBSD]: https://man.openbsd.org/clock_getres.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=clock_getres§ion=2 -/// [illumos]: https://illumos.org/man/3C/clock_getres -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[inline] -#[must_use] -pub fn clock_getres(id: ClockId) -> Timespec { - backend::time::syscalls::clock_getres(id) -} - -/// `clock_gettime(id)`—Returns the current value of a clock. -/// -/// This function uses `ClockId` which only contains clocks which are known to -/// always be supported at runtime, allowing this function to be infallible. -/// For a greater set of clocks and dynamic clock support, see -/// [`clock_gettime_dynamic`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_gettime.html -/// [Linux]: https://man7.org/linux/man-pages/man2/clock_gettime.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=clock_getres&sektion=2 -/// [NetBSD]: https://man.netbsd.org/clock_getres.2 -/// [OpenBSD]: https://man.openbsd.org/clock_getres.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=clock_getres§ion=2 -/// [illumos]: https://illumos.org/man/3C/clock_gettime -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub fn clock_gettime(id: ClockId) -> Timespec { - backend::time::syscalls::clock_gettime(id) -} - -/// Like [`clock_gettime`] but with support for dynamic clocks. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_gettime.html -/// [Linux]: https://man7.org/linux/man-pages/man2/clock_gettime.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timespec> { - backend::time::syscalls::clock_gettime_dynamic(id) -} - -/// `clock_settime(id, timespec)`—Sets the current value of a settable clock. -/// -/// This fails with [`io::Errno::INVAL`] if the clock is not settable, and -/// [`io::Errno::ACCESS`] if the current process does not have permission to -/// set it. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// - [DragonFly BSD] -/// - [illumos] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_settime.html -/// [Linux]: https://man7.org/linux/man-pages/man2/clock_settime.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=clock_settime&sektion=2 -/// [NetBSD]: https://man.netbsd.org/clock_settime.2 -/// [OpenBSD]: https://man.openbsd.org/clock_settime.2 -/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=clock_settime§ion=2 -/// [illumos]: https://illumos.org/man/3C/clock_settime -#[cfg(not(any( - target_os = "redox", - target_os = "wasi", - all(apple, not(target_os = "macos")) -)))] -#[inline] -pub fn clock_settime(id: ClockId, timespec: Timespec) -> io::Result<()> { - backend::time::syscalls::clock_settime(id, timespec) -} diff --git a/vendor/rustix/src/time/mod.rs b/vendor/rustix/src/time/mod.rs deleted file mode 100644 index c633e767..00000000 --- a/vendor/rustix/src/time/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Time-related operations. - -mod clock; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -mod timerfd; - -// TODO: Convert WASI'S clock APIs to use handles rather than ambient clock -// identifiers, update `wasi-libc`, and then add support in `rustix`. -pub use clock::*; -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -pub use timerfd::*; diff --git a/vendor/rustix/src/time/timerfd.rs b/vendor/rustix/src/time/timerfd.rs deleted file mode 100644 index d1d2a17f..00000000 --- a/vendor/rustix/src/time/timerfd.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::fd::{AsFd, OwnedFd}; -use crate::timespec::Timespec; -use crate::{backend, io}; - -pub use backend::time::types::{TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; - -/// `struct itimerspec` for use with [`timerfd_gettime`] and -/// [`timerfd_settime`]. -/// -/// [`timerfd_gettime`]: crate::time::timerfd_gettime -/// [`timerfd_settime`]: crate::time::timerfd_settime -#[derive(Debug, Clone)] -pub struct Itimerspec { - /// Interval between times. - pub it_interval: Timespec, - /// Value of the time. - pub it_value: Timespec, -} - -/// `timerfd_create(clockid, flags)`—Create a timer. -/// -/// For a higher-level API to timerfd functionality, see the [timerfd] crate. -/// -/// [timerfd]: https://crates.io/crates/timerfd -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/timerfd_create.2.html -#[inline] -pub fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { - backend::time::syscalls::timerfd_create(clockid, flags) -} - -/// `timerfd_settime(clockid, flags, new_value)`—Set the time on a timer. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/timerfd_settime.2.html -#[inline] -pub fn timerfd_settime<Fd: AsFd>( - fd: Fd, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result<Itimerspec> { - backend::time::syscalls::timerfd_settime(fd.as_fd(), flags, new_value) -} - -/// `timerfd_gettime(clockid, flags)`—Query a timer. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/timerfd_gettime.2.html -#[inline] -pub fn timerfd_gettime<Fd: AsFd>(fd: Fd) -> io::Result<Itimerspec> { - backend::time::syscalls::timerfd_gettime(fd.as_fd()) -} diff --git a/vendor/rustix/src/timespec.rs b/vendor/rustix/src/timespec.rs deleted file mode 100644 index f5404ba4..00000000 --- a/vendor/rustix/src/timespec.rs +++ /dev/null @@ -1,428 +0,0 @@ -//! `Timespec` and related types, which are used by multiple public API -//! modules. - -#![allow(dead_code)] - -use core::num::TryFromIntError; -use core::ops::{Add, AddAssign, Neg, Sub, SubAssign}; -use core::time::Duration; - -use crate::backend::c; -#[allow(unused)] -use crate::ffi; -#[cfg(not(fix_y2038))] -use core::ptr::null; - -/// `struct timespec`—A quantity of time in seconds plus nanoseconds. -#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)] -#[repr(C)] -pub struct Timespec { - /// Seconds. - pub tv_sec: Secs, - - /// Nanoseconds. Must be less than 1_000_000_000. - /// - /// When passed to [`rustix::fs::utimensat`], this field may instead be - /// assigned the values [`UTIME_NOW`] or [`UTIME_OMIT`]. - /// - /// [`UTIME_NOW`]: crate::fs::UTIME_NOW - /// [`UTIME_OMIT`]: crate::fs::UTIME_OMIT - /// [`rustix::fs::utimensat`]: crate::fs::utimensat - pub tv_nsec: Nsecs, -} - -/// A type for the `tv_sec` field of [`Timespec`]. -pub type Secs = i64; - -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(any( - fix_y2038, - linux_raw, - all(libc, target_arch = "x86_64", target_pointer_width = "32") -))] -pub type Nsecs = i64; - -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(all( - not(fix_y2038), - libc, - not(all(target_arch = "x86_64", target_pointer_width = "32")) -))] -pub type Nsecs = ffi::c_long; - -impl Timespec { - /// Checked `Timespec` addition. Returns `None` if overflow occurred. - /// - /// # Panics - /// - /// If `0 <= .tv_nsec < 1_000_000_000` doesn't hold, this function may - /// panic or return unexpected results. - /// - /// # Example - /// - /// ``` - /// use rustix::event::Timespec; - /// - /// assert_eq!( - /// Timespec { - /// tv_sec: 1, - /// tv_nsec: 2 - /// } - /// .checked_add(Timespec { - /// tv_sec: 30, - /// tv_nsec: 40 - /// }), - /// Some(Timespec { - /// tv_sec: 31, - /// tv_nsec: 42 - /// }) - /// ); - /// assert_eq!( - /// Timespec { - /// tv_sec: 0, - /// tv_nsec: 999_999_999 - /// } - /// .checked_add(Timespec { - /// tv_sec: 0, - /// tv_nsec: 2 - /// }), - /// Some(Timespec { - /// tv_sec: 1, - /// tv_nsec: 1 - /// }) - /// ); - /// assert_eq!( - /// Timespec { - /// tv_sec: i64::MAX, - /// tv_nsec: 999_999_999 - /// } - /// .checked_add(Timespec { - /// tv_sec: 0, - /// tv_nsec: 1 - /// }), - /// None - /// ); - /// ``` - pub const fn checked_add(self, rhs: Self) -> Option<Self> { - if let Some(mut tv_sec) = self.tv_sec.checked_add(rhs.tv_sec) { - let mut tv_nsec = self.tv_nsec + rhs.tv_nsec; - if tv_nsec >= 1_000_000_000 { - tv_nsec -= 1_000_000_000; - if let Some(carried_sec) = tv_sec.checked_add(1) { - tv_sec = carried_sec; - } else { - return None; - } - } - Some(Self { tv_sec, tv_nsec }) - } else { - None - } - } - - /// Checked `Timespec` subtraction. Returns `None` if overflow occurred. - /// - /// # Panics - /// - /// If `0 <= .tv_nsec < 1_000_000_000` doesn't hold, this function may - /// panic or return unexpected results. - /// - /// # Example - /// - /// ``` - /// use rustix::event::Timespec; - /// - /// assert_eq!( - /// Timespec { - /// tv_sec: 31, - /// tv_nsec: 42 - /// } - /// .checked_sub(Timespec { - /// tv_sec: 30, - /// tv_nsec: 40 - /// }), - /// Some(Timespec { - /// tv_sec: 1, - /// tv_nsec: 2 - /// }) - /// ); - /// assert_eq!( - /// Timespec { - /// tv_sec: 1, - /// tv_nsec: 1 - /// } - /// .checked_sub(Timespec { - /// tv_sec: 0, - /// tv_nsec: 2 - /// }), - /// Some(Timespec { - /// tv_sec: 0, - /// tv_nsec: 999_999_999 - /// }) - /// ); - /// assert_eq!( - /// Timespec { - /// tv_sec: i64::MIN, - /// tv_nsec: 0 - /// } - /// .checked_sub(Timespec { - /// tv_sec: 0, - /// tv_nsec: 1 - /// }), - /// None - /// ); - /// ``` - pub const fn checked_sub(self, rhs: Self) -> Option<Self> { - if let Some(mut tv_sec) = self.tv_sec.checked_sub(rhs.tv_sec) { - let mut tv_nsec = self.tv_nsec - rhs.tv_nsec; - if tv_nsec < 0 { - tv_nsec += 1_000_000_000; - if let Some(borrowed_sec) = tv_sec.checked_sub(1) { - tv_sec = borrowed_sec; - } else { - return None; - } - } - Some(Self { tv_sec, tv_nsec }) - } else { - None - } - } - - /// Convert from `Timespec` to `c::c_int` milliseconds, rounded up. - pub(crate) fn as_c_int_millis(&self) -> Option<c::c_int> { - let secs = self.tv_sec; - if secs < 0 { - return None; - } - secs.checked_mul(1000) - .and_then(|millis| { - // Add the nanoseconds, converted to milliseconds, rounding up. - // With Rust 1.73.0 this can use `div_ceil`. - millis.checked_add((i64::from(self.tv_nsec) + 999_999) / 1_000_000) - }) - .and_then(|millis| c::c_int::try_from(millis).ok()) - } -} - -impl TryFrom<Timespec> for Duration { - type Error = TryFromIntError; - - fn try_from(ts: Timespec) -> Result<Self, Self::Error> { - Ok(Self::new(ts.tv_sec.try_into()?, ts.tv_nsec as _)) - } -} - -impl TryFrom<Duration> for Timespec { - type Error = TryFromIntError; - - fn try_from(dur: Duration) -> Result<Self, Self::Error> { - Ok(Self { - tv_sec: dur.as_secs().try_into()?, - tv_nsec: dur.subsec_nanos() as _, - }) - } -} - -impl Add for Timespec { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self.checked_add(rhs) - .expect("overflow when adding timespecs") - } -} - -impl AddAssign for Timespec { - fn add_assign(&mut self, rhs: Self) { - *self = *self + rhs; - } -} - -impl Sub for Timespec { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self.checked_sub(rhs) - .expect("overflow when subtracting timespecs") - } -} - -impl SubAssign for Timespec { - fn sub_assign(&mut self, rhs: Self) { - *self = *self - rhs; - } -} - -impl Neg for Timespec { - type Output = Self; - - fn neg(self) -> Self { - Self::default() - self - } -} - -/// On 32-bit glibc platforms, `timespec` has anonymous padding fields, which -/// Rust doesn't support yet (see `unnamed_fields`), so we define our own -/// struct with explicit padding, with bidirectional `From` impls. -#[cfg(fix_y2038)] -#[repr(C)] -#[derive(Debug, Clone)] -pub(crate) struct LibcTimespec { - pub(crate) tv_sec: Secs, - - #[cfg(target_endian = "big")] - padding: core::mem::MaybeUninit<u32>, - - pub(crate) tv_nsec: i32, - - #[cfg(target_endian = "little")] - padding: core::mem::MaybeUninit<u32>, -} - -#[cfg(fix_y2038)] -impl From<LibcTimespec> for Timespec { - #[inline] - fn from(t: LibcTimespec) -> Self { - Self { - tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec as _, - } - } -} - -#[cfg(fix_y2038)] -impl From<Timespec> for LibcTimespec { - #[inline] - fn from(t: Timespec) -> Self { - Self { - tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec as _, - padding: core::mem::MaybeUninit::uninit(), - } - } -} - -#[cfg(not(fix_y2038))] -pub(crate) fn as_libc_timespec_ptr(timespec: &Timespec) -> *const c::timespec { - #[cfg(test)] - { - assert_eq_size!(Timespec, c::timespec); - } - crate::utils::as_ptr(timespec).cast::<c::timespec>() -} - -#[cfg(not(fix_y2038))] -pub(crate) fn as_libc_timespec_mut_ptr( - timespec: &mut core::mem::MaybeUninit<Timespec>, -) -> *mut c::timespec { - #[cfg(test)] - { - assert_eq_size!(Timespec, c::timespec); - } - timespec.as_mut_ptr().cast::<c::timespec>() -} - -#[cfg(not(fix_y2038))] -pub(crate) fn option_as_libc_timespec_ptr(timespec: Option<&Timespec>) -> *const c::timespec { - match timespec { - None => null(), - Some(timespec) => as_libc_timespec_ptr(timespec), - } -} - -/// As described [here], Apple platforms may return a negative nanoseconds -/// value in some cases; adjust it so that nanoseconds is always in -/// `0..1_000_000_000`. -/// -/// [here]: https://github.com/rust-lang/rust/issues/108277#issuecomment-1787057158 -#[cfg(apple)] -#[inline] -pub(crate) fn fix_negative_nsecs( - mut secs: c::time_t, - mut nsecs: c::c_long, -) -> (c::time_t, c::c_long) { - #[cold] - fn adjust(secs: &mut c::time_t, nsecs: c::c_long) -> c::c_long { - assert!(nsecs >= -1_000_000_000); - assert!(*secs < 0); - assert!(*secs > c::time_t::MIN); - *secs -= 1; - nsecs + 1_000_000_000 - } - - if nsecs < 0 { - nsecs = adjust(&mut secs, nsecs); - } - (secs, nsecs) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[cfg(apple)] - #[test] - fn test_negative_timestamps() { - let mut secs = -59; - let mut nsecs = -900_000_000; - (secs, nsecs) = fix_negative_nsecs(secs, nsecs); - assert_eq!(secs, -60); - assert_eq!(nsecs, 100_000_000); - (secs, nsecs) = fix_negative_nsecs(secs, nsecs); - assert_eq!(secs, -60); - assert_eq!(nsecs, 100_000_000); - } - - #[test] - fn test_sizes() { - assert_eq_size!(Secs, u64); - const_assert!(core::mem::size_of::<Timespec>() >= core::mem::size_of::<(u64, u32)>()); - const_assert!(core::mem::size_of::<Nsecs>() >= 4); - - let mut t = Timespec { - tv_sec: 0, - tv_nsec: 0, - }; - - // `tv_nsec` needs to be able to hold nanoseconds up to a second. - t.tv_nsec = 999_999_999_u32 as _; - assert_eq!(t.tv_nsec as u64, 999_999_999_u64); - - // `tv_sec` needs to be able to hold more than 32-bits of seconds. - t.tv_sec = 0x1_0000_0000_u64 as _; - assert_eq!(t.tv_sec as u64, 0x1_0000_0000_u64); - } - - // Test that our workarounds are needed. - #[cfg(fix_y2038)] - #[test] - #[allow(deprecated)] - fn test_fix_y2038() { - assert_eq_size!(libc::time_t, u32); - } - - // Test that our workarounds are not needed. - #[cfg(not(fix_y2038))] - #[test] - fn timespec_layouts() { - use crate::backend::c; - check_renamed_struct!(Timespec, timespec, tv_sec, tv_nsec); - } - - // Test that `Timespec` matches Linux's `__kernel_timespec`. - #[cfg(linux_kernel)] - #[test] - fn test_against_kernel_timespec() { - assert_eq_size!(Timespec, linux_raw_sys::general::__kernel_timespec); - assert_eq_align!(Timespec, linux_raw_sys::general::__kernel_timespec); - assert_eq!( - memoffset::span_of!(Timespec, tv_sec), - memoffset::span_of!(linux_raw_sys::general::__kernel_timespec, tv_sec) - ); - assert_eq!( - memoffset::span_of!(Timespec, tv_nsec), - memoffset::span_of!(linux_raw_sys::general::__kernel_timespec, tv_nsec) - ); - } -} diff --git a/vendor/rustix/src/ugid.rs b/vendor/rustix/src/ugid.rs deleted file mode 100644 index 386ceb72..00000000 --- a/vendor/rustix/src/ugid.rs +++ /dev/null @@ -1,119 +0,0 @@ -//! User and Group ID types. - -use crate::backend::c; -use crate::ffi; - -/// A group identifier as a raw integer. -pub type RawGid = ffi::c_uint; -/// A user identifier as a raw integer. -pub type RawUid = ffi::c_uint; - -/// `uid_t`—A Unix user ID. -#[repr(transparent)] -#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] -pub struct Uid(RawUid); - -/// `gid_t`—A Unix group ID. -#[repr(transparent)] -#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] -pub struct Gid(RawGid); - -impl Uid { - /// A `Uid` corresponding to the root user (uid 0). - pub const ROOT: Self = Self(0); - - /// Converts a `RawUid` into a `Uid`. - /// - /// `raw` must be the value of a valid Unix user ID, and not `-1`. - #[inline] - pub fn from_raw(raw: RawUid) -> Self { - debug_assert_ne!(raw, !0); - Self(raw) - } - - /// Converts a `RawUid` into a `Uid`. - /// - /// `raw` must be the value of a valid Unix user ID, and not `-1`. - #[inline] - pub const fn from_raw_unchecked(raw: RawUid) -> Self { - Self(raw) - } - - /// Converts a `Uid` into a `RawUid`. - #[inline] - pub const fn as_raw(self) -> RawUid { - self.0 - } - - /// Test whether this uid represents the root user ([`Uid::ROOT`]). - #[inline] - pub const fn is_root(self) -> bool { - self.0 == Self::ROOT.0 - } -} - -impl Gid { - /// A `Gid` corresponding to the root group (gid 0). - pub const ROOT: Self = Self(0); - - /// Converts a `RawGid` into a `Gid`. - /// - /// `raw` must be the value of a valid Unix group ID, and not `-1`. - #[inline] - pub fn from_raw(raw: RawGid) -> Self { - debug_assert_ne!(raw, !0); - Self(raw) - } - - /// Converts a `RawGid` into a `Gid`. - /// - /// `raw` must be the value of a valid Unix group ID, and not `-1`. - #[inline] - pub const fn from_raw_unchecked(raw: RawGid) -> Self { - Self(raw) - } - - /// Converts a `Gid` into a `RawGid`. - #[inline] - pub const fn as_raw(self) -> RawGid { - self.0 - } - - /// Test whether this gid represents the root group ([`Gid::ROOT`]). - #[inline] - pub const fn is_root(self) -> bool { - self.0 == Self::ROOT.0 - } -} - -// Return the raw value of the IDs. In case of `None` it returns `!0` since it -// has the same bit pattern as `-1` indicating no change to the owner/group ID. -pub(crate) fn translate_fchown_args( - owner: Option<Uid>, - group: Option<Gid>, -) -> (c::uid_t, c::gid_t) { - let ow = match owner { - Some(o) => o.as_raw(), - None => !0, - }; - - let gr = match group { - Some(g) => g.as_raw(), - None => !0, - }; - - (ow as c::uid_t, gr as c::gid_t) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_sizes() { - assert_eq_size!(RawUid, u32); - assert_eq_size!(RawGid, u32); - assert_eq_size!(RawUid, libc::uid_t); - assert_eq_size!(RawGid, libc::gid_t); - } -} diff --git a/vendor/rustix/src/utils.rs b/vendor/rustix/src/utils.rs deleted file mode 100644 index 77eb26c1..00000000 --- a/vendor/rustix/src/utils.rs +++ /dev/null @@ -1,76 +0,0 @@ -//! Miscellaneous minor utilities. - -#![allow(dead_code)] -#![allow(unused_macros)] - -use core::ffi::c_void; -use core::mem::{align_of, size_of}; -use core::ptr::{null, null_mut, NonNull}; - -/// Convert a `&T` into a `*const T` without using an `as`. -#[inline] -pub(crate) const fn as_ptr<T>(t: &T) -> *const T { - t -} - -/// Convert a `&mut T` into a `*mut T` without using an `as`. -#[inline] -pub(crate) fn as_mut_ptr<T>(t: &mut T) -> *mut T { - t -} - -/// Convert an `Option<&T>` into a possibly-null `*const T`. -#[inline] -pub(crate) const fn option_as_ptr<T>(t: Option<&T>) -> *const T { - match t { - Some(t) => t, - None => null(), - } -} - -/// Convert an `Option<&mut T>` into a possibly-null `*mut T`. -#[inline] -pub(crate) fn option_as_mut_ptr<T>(t: Option<&mut T>) -> *mut T { - match t { - Some(t) => t, - None => null_mut(), - } -} - -/// Convert a `*mut c_void` to a `*mut T`, checking that it is not null, -/// misaligned, or pointing to a region of memory that wraps around the address -/// space. -pub(crate) fn check_raw_pointer<T>(value: *mut c_void) -> Option<NonNull<T>> { - if (value as usize).checked_add(size_of::<T>()).is_none() - || (value as usize) % align_of::<T>() != 0 - { - return None; - } - - NonNull::new(value.cast()) -} - -/// Create a union value containing a default value in one of its arms. -/// -/// The field names a union field which must have the same size as the union -/// itself. -macro_rules! default_union { - ($union:ident, $field:ident) => {{ - let u = $union { - $field: Default::default(), - }; - - // Assert that the given field initializes the whole union. - #[cfg(test)] - unsafe { - let field_value = u.$field; - assert_eq!( - core::mem::size_of_val(&u), - core::mem::size_of_val(&field_value) - ); - const_assert_eq!(memoffset::offset_of_union!($union, $field), 0); - } - - u - }}; -} diff --git a/vendor/rustix/src/weak.rs b/vendor/rustix/src/weak.rs deleted file mode 100644 index 036ddeea..00000000 --- a/vendor/rustix/src/weak.rs +++ /dev/null @@ -1,288 +0,0 @@ -// Implementation derived from `weak` in Rust's -// library/std/src/sys/unix/weak.rs at revision -// fd0cb0cdc21dd9c06025277d772108f8d42cb25f. -// -// Ideally we should update to a newer version which doesn't need `dlsym`, -// however that depends on the `extern_weak` feature which is currently -// unstable. - -#![cfg_attr(linux_raw, allow(unsafe_code))] - -//! Support for "weak linkage" to symbols on Unix -//! -//! Some I/O operations we do in libstd require newer versions of OSes but we -//! need to maintain binary compatibility with older releases for now. In order -//! to use the new functionality when available we use this module for -//! detection. -//! -//! One option to use here is weak linkage, but that is unfortunately only -//! really workable on Linux. Hence, use dlsym to get the symbol value at -//! runtime. This is also done for compatibility with older versions of glibc, -//! and to avoid creating dependencies on `GLIBC_PRIVATE` symbols. It assumes -//! that we've been dynamically linked to the library the symbol comes from, -//! but that is currently always the case for things like libpthread/libc. -//! -//! A long time ago this used weak linkage for the `__pthread_get_minstack` -//! symbol, but that caused Debian to detect an unnecessarily strict versioned -//! dependency on libc6 (#23628). - -// There are a variety of `#[cfg]`s controlling which targets are involved in -// each instance of `weak!` and `syscall!`. Rather than trying to unify all of -// that, we'll just allow that some unix targets don't use this module at all. -#![allow(dead_code, unused_macros)] -#![allow(clippy::doc_markdown)] - -use crate::ffi::CStr; -use core::ffi::c_void; -use core::ptr::null_mut; -use core::sync::atomic::{self, AtomicPtr, Ordering}; -use core::{marker, mem}; - -const NULL: *mut c_void = null_mut(); -const INVALID: *mut c_void = 1 as *mut c_void; - -macro_rules! weak { - ($vis:vis fn $name:ident($($t:ty),*) -> $ret:ty) => ( - #[allow(non_upper_case_globals)] - $vis static $name: $crate::weak::Weak<unsafe extern "C" fn($($t),*) -> $ret> = - $crate::weak::Weak::new(concat!(stringify!($name), '\0')); - ) -} - -pub(crate) struct Weak<F> { - name: &'static str, - addr: AtomicPtr<c_void>, - _marker: marker::PhantomData<F>, -} - -impl<F> Weak<F> { - pub(crate) const fn new(name: &'static str) -> Self { - Self { - name, - addr: AtomicPtr::new(INVALID), - _marker: marker::PhantomData, - } - } - - pub(crate) fn get(&self) -> Option<F> { - assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>()); - unsafe { - // Relaxed is fine here because we fence before reading through the - // pointer (see the comment below). - match self.addr.load(Ordering::Relaxed) { - INVALID => self.initialize(), - NULL => None, - addr => { - let func = mem::transmute_copy::<*mut c_void, F>(&addr); - // The caller is presumably going to read through this - // value (by calling the function we've dlsymed). This - // means we'd need to have loaded it with at least C11's - // consume ordering in order to be guaranteed that the data - // we read from the pointer isn't from before the pointer - // was stored. Rust has no equivalent to - // memory_order_consume, so we use an acquire fence (sorry, - // ARM). - // - // Now, in practice this likely isn't needed even on CPUs - // where relaxed and consume mean different things. The - // symbols we're loading are probably present (or not) at - // init, and even if they aren't the runtime dynamic loader - // is extremely likely have sufficient barriers internally - // (possibly implicitly, for example the ones provided by - // invoking `mprotect`). - // - // That said, none of that's *guaranteed*, and so we fence. - atomic::fence(Ordering::Acquire); - Some(func) - } - } - } - } - - // Cold because it should only happen during first-time initialization. - #[cold] - unsafe fn initialize(&self) -> Option<F> { - let val = fetch(self.name); - // This synchronizes with the acquire fence in `get`. - self.addr.store(val, Ordering::Release); - - match val { - NULL => None, - addr => Some(mem::transmute_copy::<*mut c_void, F>(&addr)), - } - } -} - -// To avoid having the `linux_raw` backend depend on the libc crate, just -// declare the few things we need in a module called `libc` so that `fetch` -// uses it. -#[cfg(linux_raw)] -mod libc { - use core::ptr; - use linux_raw_sys::ctypes::{c_char, c_void}; - - #[cfg(all(target_os = "android", target_pointer_width = "32"))] - pub(super) const RTLD_DEFAULT: *mut c_void = -1isize as *mut c_void; - #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] - pub(super) const RTLD_DEFAULT: *mut c_void = ptr::null_mut(); - - extern "C" { - pub(super) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void; - } - - #[test] - fn test_abi() { - assert_eq!(self::RTLD_DEFAULT, ::libc::RTLD_DEFAULT); - } -} - -unsafe fn fetch(name: &str) -> *mut c_void { - let name = match CStr::from_bytes_with_nul(name.as_bytes()) { - Ok(c_str) => c_str, - Err(..) => return null_mut(), - }; - libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr().cast()) -} - -#[cfg(not(linux_kernel))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) via $_sys_name:ident -> $ret:ty) => ( - unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - libc_errno::set_errno(libc_errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} - -#[cfg(linux_kernel)] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) via $sys_name:ident -> $ret:ty) => ( - unsafe fn $name($($arg_name:$t),*) -> $ret { - // This looks like a hack, but `concat_idents` only accepts idents - // (not paths). - use libc::*; - - #[allow(dead_code)] - trait AsSyscallArg { - type SyscallArgType; - fn into_syscall_arg(self) -> Self::SyscallArgType; - } - - // Pass pointer types as pointers, to preserve provenance. - impl<T> AsSyscallArg for *mut T { - type SyscallArgType = *mut T; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - impl<T> AsSyscallArg for *const T { - type SyscallArgType = *const T; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - - // Pass `BorrowedFd` values as the integer value. - impl AsSyscallArg for $crate::fd::BorrowedFd<'_> { - type SyscallArgType = ::libc::c_int; - fn into_syscall_arg(self) -> Self::SyscallArgType { - $crate::fd::AsRawFd::as_raw_fd(&self) as _ - } - } - - // Coerce integer values into `c_long`. - impl AsSyscallArg for i8 { - type SyscallArgType = ::libc::c_int; - fn into_syscall_arg(self) -> Self::SyscallArgType { self.into() } - } - impl AsSyscallArg for u8 { - type SyscallArgType = ::libc::c_int; - fn into_syscall_arg(self) -> Self::SyscallArgType { self.into() } - } - impl AsSyscallArg for i16 { - type SyscallArgType = ::libc::c_int; - fn into_syscall_arg(self) -> Self::SyscallArgType { self.into() } - } - impl AsSyscallArg for u16 { - type SyscallArgType = ::libc::c_int; - fn into_syscall_arg(self) -> Self::SyscallArgType { self.into() } - } - impl AsSyscallArg for i32 { - type SyscallArgType = ::libc::c_int; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - impl AsSyscallArg for u32 { - type SyscallArgType = ::libc::c_uint; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - impl AsSyscallArg for usize { - type SyscallArgType = ::libc::c_ulong; - fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - - // On 64-bit platforms, also coerce `i64` and `u64` since `c_long` - // is 64-bit and can hold those values. - #[cfg(target_pointer_width = "64")] - impl AsSyscallArg for i64 { - type SyscallArgType = ::libc::c_long; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - #[cfg(target_pointer_width = "64")] - impl AsSyscallArg for u64 { - type SyscallArgType = ::libc::c_ulong; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - - // `concat_idents` is [unstable], so we take an extra `sys_name` - // parameter and have our users do the concat for us for now. - // - // [unstable]: https://github.com/rust-lang/rust/issues/29599 - /* - syscall( - concat_idents!(SYS_, $name), - $($arg_name.into_syscall_arg()),* - ) as $ret - */ - - syscall($sys_name, $($arg_name.into_syscall_arg()),*) as $ret - } - ) -} - -macro_rules! weakcall { - ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - $vis unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` - // interposition, but if it's not found just fail. - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - libc_errno::set_errno(libc_errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} - -/// A combination of `weakcall` and `syscall`. Use the libc function if it's -/// available, and fall back to `libc::syscall` otherwise. -macro_rules! weak_or_syscall { - ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) via $sys_name:ident -> $ret:ty) => ( - $vis unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` - // interposition, but if it's not found just fail. - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - syscall! { fn $name($($arg_name: $t),*) via $sys_name -> $ret } - $name($($arg_name),*) - } - } - ) -} |
