diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/rustix/src/backend/libc | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rustix/src/backend/libc')
64 files changed, 3460 insertions, 4146 deletions
diff --git a/vendor/rustix/src/backend/libc/c.rs b/vendor/rustix/src/backend/libc/c.rs index 35d24d893..90d3c26f3 100644 --- a/vendor/rustix/src/backend/libc/c.rs +++ b/vendor/rustix/src/backend/libc/c.rs @@ -1,9 +1,504 @@ +#![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(any(target_os = "android", target_os = "linux"), target_env = "musl"))] +#[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(any(target_os = "android", target_os = "linux"), target_env = "musl"))] +#[cfg(all(linux_kernel, target_env = "musl"))] pub(crate) const NFS_SUPER_MAGIC: u32 = 0x0000_6969; + +// Submitted upstream in <https://github.com/rust-lang/libc/pull/3272>. +#[cfg(all(linux_kernel, feature = "net"))] +pub(crate) const IPPROTO_ETHERNET: c_int = linux_raw_sys::net::IPPROTO_ETHERNET as _; + +// 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 = "mips64", + 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 _; + +// On PowerPC, the regular `termios` has the `termios2` fields and there is no +// `termios2`. linux-raw-sys has aliases `termios2` to `termios` to cover this +// difference, but we still need to manually import it since `libc` doesn't +// have this. +#[cfg(all( + linux_kernel, + feature = "termios", + any(target_arch = "powerpc", target_arch = "powerpc64") +))] +pub(crate) use { + linux_raw_sys::general::{termios2, CIBAUD}, + linux_raw_sys::ioctl::{TCGETS2, TCSETS2, TCSETSF2, TCSETSW2}, +}; + +// Automatically enable “large file” support (LFS) features. + +#[cfg(target_os = "vxworks")] +pub(super) use libc::_Vx_ticks64_t as _Vx_ticks_t; +#[cfg(target_os = "aix")] +pub(super) use libc::blksize64_t as blksize_t; +#[cfg(linux_kernel)] +pub(super) use libc::fallocate64 as fallocate; +#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] +#[cfg(any(linux_like, target_os = "aix"))] +pub(super) use libc::open64 as open; +#[cfg(any(linux_kernel, target_os = "aix", target_os = "l4re"))] +pub(super) use libc::posix_fallocate64 as posix_fallocate; +#[cfg(any(all(linux_like, not(target_os = "android")), target_os = "aix"))] +pub(super) use libc::{blkcnt64_t as blkcnt_t, rlim64_t as rlim_t}; +#[cfg(any(linux_like, target_os = "aix"))] +pub(super) use libc::{ + 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 libc::{ + 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"))))] +#[cfg(any(linux_like, target_os = "aix"))] +pub(super) use libc::{lstat64 as lstat, stat64 as stat}; +#[cfg(any(linux_kernel, target_os = "aix", target_os = "emscripten"))] +pub(super) use libc::{pread64 as pread, pwrite64 as pwrite}; +#[cfg(any(target_os = "aix", target_os = "linux", target_os = "emscripten"))] +pub(super) use libc::{preadv64 as preadv, pwritev64 as pwritev}; + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub(super) unsafe fn prlimit( + pid: libc::pid_t, + resource: libc::__rlimit_resource_t, + new_limit: *const libc::rlimit64, + old_limit: *mut libc::rlimit64, +) -> libc::c_int { + // `prlimit64` wasn't supported in glibc until 2.13. + weak_or_syscall! { + fn prlimit64( + pid: libc::pid_t, + resource: libc::__rlimit_resource_t, + new_limit: *const libc::rlimit64, + old_limit: *mut libc::rlimit64 + ) via SYS_prlimit64 -> libc::c_int + } + + prlimit64(pid, resource, new_limit, old_limit) +} + +#[cfg(all(target_os = "linux", target_env = "musl"))] +pub(super) unsafe fn prlimit( + pid: libc::pid_t, + resource: libc::c_int, + new_limit: *const libc::rlimit64, + old_limit: *mut libc::rlimit64, +) -> libc::c_int { + weak_or_syscall! { + fn prlimit64( + pid: libc::pid_t, + resource: libc::c_int, + new_limit: *const libc::rlimit64, + old_limit: *mut libc::rlimit64 + ) via SYS_prlimit64 -> libc::c_int + } + + prlimit64(pid, resource, new_limit, old_limit) +} + +#[cfg(target_os = "android")] +pub(super) unsafe fn prlimit( + pid: libc::pid_t, + resource: libc::c_int, + new_limit: *const libc::rlimit64, + old_limit: *mut libc::rlimit64, +) -> libc::c_int { + weak_or_syscall! { + fn prlimit64( + pid: libc::pid_t, + resource: libc::c_int, + new_limit: *const libc::rlimit64, + old_limit: *mut libc::rlimit64 + ) via SYS_prlimit64 -> libc::c_int + } + + prlimit64(pid, resource, new_limit, old_limit) +} + +// 64-bit offsets on 32-bit platforms are passed in endianness-specific +// lo/hi pairs. See src/backend/linux_raw/conv.rs for details. +#[cfg(all(linux_kernel, target_endian = "little", target_pointer_width = "32"))] +fn lo(x: i64) -> usize { + (x >> 32) as usize +} +#[cfg(all(linux_kernel, target_endian = "little", target_pointer_width = "32"))] +fn hi(x: i64) -> usize { + x as usize +} +#[cfg(all(linux_kernel, target_endian = "big", target_pointer_width = "32"))] +fn lo(x: i64) -> usize { + x as usize +} +#[cfg(all(linux_kernel, target_endian = "big", target_pointer_width = "32"))] +fn hi(x: i64) -> usize { + (x >> 32) as usize +} + +#[cfg(target_os = "android")] +mod readwrite_pv64 { + use super::*; + + pub(in super::super) unsafe fn preadv64( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off64_t, + ) -> libc::ssize_t { + // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to + // test for it, and call back to `libc::syscall`. We don't use + // `weak_or_syscall` here because we need to pass the 64-bit offset + // specially. + weak! { + fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t) -> libc::ssize_t + } + if let Some(fun) = preadv64.get() { + fun(fd, iov, iovcnt, offset) + } else { + #[cfg(target_pointer_width = "32")] + { + syscall! { + fn preadv( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_hi: usize, + offset_lo: usize + ) via SYS_preadv -> libc::ssize_t + } + preadv(fd, iov, iovcnt, hi(offset), lo(offset)) + } + #[cfg(target_pointer_width = "64")] + { + syscall! { + fn preadv( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t + ) via SYS_preadv -> libc::ssize_t + } + preadv(fd, iov, iovcnt, offset) + } + } + } + pub(in super::super) unsafe fn pwritev64( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off64_t, + ) -> libc::ssize_t { + // See the comments in `preadv64`. + weak! { + fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t) -> libc::ssize_t + } + if let Some(fun) = pwritev64.get() { + fun(fd, iov, iovcnt, offset) + } else { + #[cfg(target_pointer_width = "32")] + { + syscall! { + fn pwritev( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_hi: usize, + offset_lo: usize + ) via SYS_pwritev -> libc::ssize_t + } + pwritev(fd, iov, iovcnt, hi(offset), lo(offset)) + } + #[cfg(target_pointer_width = "64")] + { + syscall! { + fn pwritev( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t + ) via SYS_pwritev -> libc::ssize_t + } + pwritev(fd, iov, iovcnt, offset) + } + } + } +} +#[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 { + weakcall! { + pub(in super::super) fn preadv( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t + ) -> libc::ssize_t + } + weakcall! { + pub(in super::super) fn pwritev( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, offset: libc::off_t + ) -> libc::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: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off64_t, + flags: libc::c_int, + ) -> libc::ssize_t { + // Older glibc lacks `preadv64v2`, so use the `weak!` mechanism to + // test for it, and call back to `libc::syscall`. We don't use + // `weak_or_syscall` here because we need to pass the 64-bit offset + // specially. + weak! { + fn preadv64v2(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t, libc::c_int) -> libc::ssize_t + } + if let Some(fun) = preadv64v2.get() { + fun(fd, iov, iovcnt, offset, flags) + } else { + #[cfg(target_pointer_width = "32")] + { + syscall! { + fn preadv2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_hi: usize, + offset_lo: usize, + flags: libc::c_int + ) via SYS_preadv2 -> libc::ssize_t + } + preadv2(fd, iov, iovcnt, hi(offset), lo(offset), flags) + } + #[cfg(target_pointer_width = "64")] + { + syscall! { + fn preadv2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t, + flags: libc::c_int + ) via SYS_preadv2 -> libc::ssize_t + } + preadv2(fd, iov, iovcnt, offset, flags) + } + } + } + pub(in super::super) unsafe fn pwritev64v2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off64_t, + flags: libc::c_int, + ) -> libc::ssize_t { + // See the comments in `preadv64v2`. + weak! { + fn pwritev64v2(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t, libc::c_int) -> libc::ssize_t + } + if let Some(fun) = pwritev64v2.get() { + fun(fd, iov, iovcnt, offset, flags) + } else { + #[cfg(target_pointer_width = "32")] + { + syscall! { + fn pwritev2( + fd: libc::c_int, + iov: *const libc::iovec, + iovec: libc::c_int, + offset_hi: usize, + offset_lo: usize, + flags: libc::c_int + ) via SYS_pwritev2 -> libc::ssize_t + } + pwritev2(fd, iov, iovcnt, hi(offset), lo(offset), flags) + } + #[cfg(target_pointer_width = "64")] + { + syscall! { + fn pwritev2( + fd: libc::c_int, + iov:*const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t, + flags: libc::c_int + ) via SYS_pwritev2 -> libc::ssize_t + } + pwritev2(fd, iov, iovcnt, offset, 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: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off64_t, + flags: libc::c_int, + ) -> libc::ssize_t { + #[cfg(target_pointer_width = "32")] + { + syscall! { + fn preadv2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_hi: usize, + offset_lo: usize, + flags: libc::c_int + ) via SYS_preadv2 -> libc::ssize_t + } + preadv2(fd, iov, iovcnt, hi(offset), lo(offset), flags) + } + #[cfg(target_pointer_width = "64")] + { + syscall! { + fn preadv2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t, + flags: libc::c_int + ) via SYS_preadv2 -> libc::ssize_t + } + preadv2(fd, iov, iovcnt, offset, flags) + } + } + pub(in super::super) unsafe fn pwritev64v2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off64_t, + flags: libc::c_int, + ) -> libc::ssize_t { + #[cfg(target_pointer_width = "32")] + { + syscall! { + fn pwritev2( + fd: libc::c_int, + iov: *const libc::iovec, + iovcnt: libc::c_int, + offset_hi: usize, + offset_lo: usize, + flags: libc::c_int + ) via SYS_pwritev2 -> libc::ssize_t + } + pwritev2(fd, iov, iovcnt, hi(offset), lo(offset), flags) + } + #[cfg(target_pointer_width = "64")] + { + syscall! { + fn pwritev2( + fd: libc::c_int, + iov:*const libc::iovec, + iovcnt: libc::c_int, + offset: libc::off_t, + flags: libc::c_int + ) via SYS_pwritev2 -> libc::ssize_t + } + pwritev2(fd, iov, iovcnt, offset, 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}; diff --git a/vendor/rustix/src/backend/libc/conv.rs b/vendor/rustix/src/backend/libc/conv.rs index b827d0bbc..d6bcc16ee 100644 --- a/vendor/rustix/src/backend/libc/conv.rs +++ b/vendor/rustix/src/backend/libc/conv.rs @@ -7,13 +7,8 @@ use super::c; use super::fd::{AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, LibcFd, OwnedFd, RawFd}; #[cfg(not(windows))] -#[cfg(feature = "fs")] -use super::offset::libc_off_t; -#[cfg(not(windows))] use crate::ffi::CStr; use crate::io; -#[cfg(windows)] -use core::convert::TryInto; #[cfg(not(windows))] #[inline] @@ -47,15 +42,6 @@ pub(super) fn ret(raw: c::c_int) -> io::Result<()> { } #[inline] -pub(super) fn syscall_ret(raw: c::c_long) -> io::Result<()> { - if raw == 0 { - Ok(()) - } else { - Err(io::Errno::last_os_error()) - } -} - -#[inline] pub(super) fn nonnegative_ret(raw: c::c_int) -> io::Result<()> { if raw >= 0 { Ok(()) @@ -97,35 +83,10 @@ pub(super) fn ret_usize(raw: c::ssize_t) -> io::Result<usize> { } } -#[inline] -pub(super) fn syscall_ret_usize(raw: c::c_long) -> io::Result<usize> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - debug_assert!(raw >= 0); - Ok(raw as c::ssize_t as usize) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(super) fn syscall_ret_u32(raw: c::c_long) -> io::Result<u32> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - let r32 = raw as u32; - - // Converting `raw` to `u32` should be lossless. - debug_assert_eq!(r32 as c::c_long, raw); - - Ok(r32) - } -} - #[cfg(not(windows))] #[cfg(feature = "fs")] #[inline] -pub(super) fn ret_off_t(raw: libc_off_t) -> io::Result<libc_off_t> { +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 { @@ -176,22 +137,6 @@ pub(super) fn ret_discarded_char_ptr(raw: *mut c::c_char) -> io::Result<()> { } } -/// Convert a `c_long` returned from `syscall` to an `OwnedFd`, if valid. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a `syscall` call -/// which returns an owned file descriptor. -#[cfg(not(windows))] -#[inline] -pub(super) unsafe fn syscall_ret_owned_fd(raw: c::c_long) -> io::Result<OwnedFd> { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(OwnedFd::from_raw_fd(raw as RawFd)) - } -} - /// Convert the buffer-length argument value of a `send` or `recv` call. #[cfg(not(windows))] #[inline] @@ -222,3 +167,59 @@ pub(super) fn ret_send_recv(len: isize) -> io::Result<usize> { pub(super) fn ret_send_recv(len: i32) -> io::Result<usize> { ret_usize(len as isize) } + +/// Convert the value to the `msg_iovlen` field of a `msghdr` struct. +#[cfg(all( + not(any(windows, target_os = "wasi")), + any( + target_os = "android", + all(target_os = "linux", not(target_env = "musl")) + ) +))] +#[inline] +pub(super) 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 = "wasi")), + not(any( + target_os = "android", + all(target_os = "linux", not(target_env = "musl")) + )) +))] +#[inline] +pub(crate) 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 = "emscripten", + target_os = "haiku", + target_os = "fuchsia" +))] +#[inline] +pub(crate) 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, + target_env = "musl", + target_os = "emscripten", + target_os = "haiku", + target_os = "fuchsia", + windows, + target_os = "wasi" +)))] +#[inline] +pub(crate) fn msg_control_len(len: usize) -> c::size_t { + len +} diff --git a/vendor/rustix/src/backend/libc/io/epoll.rs b/vendor/rustix/src/backend/libc/event/epoll.rs index 62a3c742b..c59a38cd4 100644 --- a/vendor/rustix/src/backend/libc/io/epoll.rs +++ b/vendor/rustix/src/backend/libc/event/epoll.rs @@ -7,45 +7,50 @@ //! # Examples //! //! ```no_run -//! # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] //! # #[cfg(feature = "net")] //! # fn main() -> std::io::Result<()> { -//! use io_lifetimes::AsFd; -//! use rustix::io::{epoll, ioctl_fionbio, read, write}; +//! use rustix::event::epoll; +//! use rustix::fd::AsFd; +//! use rustix::io::{ioctl_fionbio, read, write}; //! use rustix::net::{ -//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4, -//! SocketType, +//! accept, bind_v4, 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, Protocol::default())?; +//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, None)?; //! bind_v4(&listen_sock, &SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?; //! listen(&listen_sock, 1)?; //! //! // Create an epoll object. Using `Owning` here means the epoll object will //! // take ownership of the file descriptors registered with it. -//! let epoll = epoll::epoll_create(epoll::CreateFlags::CLOEXEC)?; +//! let epoll = epoll::create(epoll::CreateFlags::CLOEXEC)?; //! //! // Register the socket with the epoll object. -//! epoll::epoll_add(&epoll, &listen_sock, 1, epoll::EventFlags::IN)?; +//! 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 = 2; +//! let mut next_id = epoll::EventData::new_u64(2); //! let mut sockets = HashMap::new(); //! //! // Process events. //! let mut event_list = epoll::EventVec::with_capacity(4); //! loop { -//! epoll::epoll_wait(&epoll, &mut event_list, -1)?; -//! for (_event_flags, target) in &event_list { -//! if target == 1 { +//! epoll::wait(&epoll, &mut event_list, -1)?; +//! for event in &event_list { +//! 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::epoll_add( +//! epoll::add( //! &epoll, //! &conn_sock, //! next_id, @@ -54,12 +59,12 @@ //! //! // Keep track of the socket. //! sockets.insert(next_id, conn_sock); -//! next_id += 1; +//! 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::epoll_del(&epoll, &target)?; +//! let _ = epoll::delete(&epoll, &target)?; //! } //! } //! } @@ -68,151 +73,166 @@ //! # fn main() {} //! ``` -use super::super::c; -use super::super::conv::{ret, ret_owned_fd, ret_u32}; +use crate::backend::c; +use crate::backend::conv::{ret, ret_owned_fd, ret_u32}; use crate::fd::{AsFd, AsRawFd, OwnedFd}; use crate::io; +use crate::utils::as_mut_ptr; use alloc::vec::Vec; use bitflags::bitflags; -use core::convert::TryInto; +use core::ffi::c_void; +use core::hash::{Hash, Hasher}; use core::ptr::null_mut; +use core::slice; bitflags! { - /// `EPOLL_*` for use with [`Epoll::new`]. - pub struct CreateFlags: c::c_int { + /// `EPOLL_*` for use with [`new`]. + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct CreateFlags: u32 { /// `EPOLL_CLOEXEC` - const CLOEXEC = c::EPOLL_CLOEXEC; + const CLOEXEC = bitcast!(c::EPOLL_CLOEXEC); } } bitflags! { - /// `EPOLL*` for use with [`Epoll::add`]. - #[derive(Default)] + /// `EPOLL*` for use with [`add`]. + #[repr(transparent)] + #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct EventFlags: u32 { /// `EPOLLIN` - const IN = c::EPOLLIN as u32; + const IN = bitcast!(c::EPOLLIN); /// `EPOLLOUT` - const OUT = c::EPOLLOUT as u32; + const OUT = bitcast!(c::EPOLLOUT); /// `EPOLLPRI` - const PRI = c::EPOLLPRI as u32; + const PRI = bitcast!(c::EPOLLPRI); /// `EPOLLERR` - const ERR = c::EPOLLERR as u32; + const ERR = bitcast!(c::EPOLLERR); /// `EPOLLHUP` - const HUP = c::EPOLLHUP as u32; + const HUP = bitcast!(c::EPOLLHUP); /// `EPOLLRDNORM` - const RDNORM = c::EPOLLRDNORM as u32; + const RDNORM = bitcast!(c::EPOLLRDNORM); /// `EPOLLRDBAND` - const RDBAND = c::EPOLLRDBAND as u32; + const RDBAND = bitcast!(c::EPOLLRDBAND); /// `EPOLLWRNORM` - const WRNORM = c::EPOLLWRNORM as u32; + const WRNORM = bitcast!(c::EPOLLWRNORM); /// `EPOLLWRBAND` - const WRBAND = c::EPOLLWRBAND as u32; + const WRBAND = bitcast!(c::EPOLLWRBAND); /// `EPOLLMSG` - const MSG = c::EPOLLMSG as u32; + const MSG = bitcast!(c::EPOLLMSG); /// `EPOLLRDHUP` - const RDHUP = c::EPOLLRDHUP as u32; + const RDHUP = bitcast!(c::EPOLLRDHUP); /// `EPOLLET` - const ET = c::EPOLLET as u32; + const ET = bitcast!(c::EPOLLET); /// `EPOLLONESHOT` - const ONESHOT = c::EPOLLONESHOT as u32; + const ONESHOT = bitcast!(c::EPOLLONESHOT); /// `EPOLLWAKEUP` - const WAKEUP = c::EPOLLWAKEUP as u32; + const WAKEUP = bitcast!(c::EPOLLWAKEUP); /// `EPOLLEXCLUSIVE` #[cfg(not(target_os = "android"))] - const EXCLUSIVE = c::EPOLLEXCLUSIVE as u32; + const EXCLUSIVE = bitcast!(c::EPOLLEXCLUSIVE); } } -/// `epoll_create1(flags)`—Creates a new `Epoll`. +/// `epoll_create1(flags)`—Creates a new epoll object. /// /// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file /// descriptor from being implicitly passed across `exec` boundaries. #[inline] #[doc(alias = "epoll_create1")] -pub fn epoll_create(flags: CreateFlags) -> io::Result<OwnedFd> { +pub fn create(flags: CreateFlags) -> io::Result<OwnedFd> { // SAFETY: We're calling `epoll_create1` via FFI and we know how it // behaves. - unsafe { ret_owned_fd(c::epoll_create1(flags.bits())) } + unsafe { ret_owned_fd(c::epoll_create1(bitflags_bits!(flags))) } } /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an -/// `Epoll`. +/// epoll object. /// -/// Note that if `epoll_del` is not called on the I/O source passed into -/// this function before the I/O source is `close`d, then the `epoll` will -/// act as if the I/O source is still registered with it. This 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. +/// This registers interest in any of the events set in `events` occurring +/// on the file descriptor associated with `data`. +/// +/// If [`delete`] is not called on the I/O source passed into this function +/// before the I/O source is `close`d, then the `epoll` will act as if the I/O +/// source is still registered with it. This can lead to spurious events being +/// returned from [`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. #[doc(alias = "epoll_ctl")] -pub fn epoll_add( +pub fn add( epoll: impl AsFd, source: impl AsFd, - data: u64, + data: EventData, event_flags: EventFlags, ) -> io::Result<()> { // SAFETY: We're calling `epoll_ctl` via FFI and we know how it - // behaves. + // behaves. 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 elsehwere for layout equivalence. unsafe { let raw_fd = source.as_fd().as_raw_fd(); ret(c::epoll_ctl( epoll.as_fd().as_raw_fd(), c::EPOLL_CTL_ADD, raw_fd, - &mut c::epoll_event { - events: event_flags.bits(), - r#u64: data, - }, + as_mut_ptr(&mut Event { + flags: event_flags, + data, + }) + .cast(), )) } } /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in -/// this `Epoll`. +/// a given epoll object. /// /// This sets the events of interest with `target` to `events`. #[doc(alias = "epoll_ctl")] -pub fn epoll_mod( +pub fn modify( epoll: impl AsFd, source: impl AsFd, - data: u64, + data: EventData, event_flags: EventFlags, ) -> io::Result<()> { let raw_fd = source.as_fd().as_raw_fd(); // SAFETY: We're calling `epoll_ctl` via FFI and we know how it - // behaves. + // behaves. 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 elsehwere for layout equivalence. unsafe { ret(c::epoll_ctl( epoll.as_fd().as_raw_fd(), c::EPOLL_CTL_MOD, raw_fd, - &mut c::epoll_event { - events: event_flags.bits(), - r#u64: data, - }, + as_mut_ptr(&mut Event { + flags: event_flags, + data, + }) + .cast(), )) } } /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in -/// this `Epoll`. +/// a given epoll object. #[doc(alias = "epoll_ctl")] -pub fn epoll_del(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { +pub fn delete(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { // SAFETY: We're calling `epoll_ctl` via FFI and we know how it // behaves. unsafe { @@ -231,11 +251,7 @@ pub fn epoll_del(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { /// /// For each event of interest, an element is written to `events`. On /// success, this returns the number of written elements. -pub fn epoll_wait( - epoll: impl AsFd, - event_list: &mut EventVec, - timeout: c::c_int, -) -> io::Result<()> { +pub fn wait(epoll: impl AsFd, event_list: &mut EventVec, timeout: c::c_int) -> io::Result<()> { // SAFETY: We're calling `epoll_wait` via FFI and we know how it // behaves. unsafe { @@ -254,19 +270,18 @@ pub fn epoll_wait( /// An iterator over the `Event`s in an `EventVec`. pub struct Iter<'a> { - iter: core::slice::Iter<'a, Event>, + /// Use `Copied` to copy the struct, since `Event` is `packed` on some + /// platforms, and it's common for users to directly destructure it, + /// which would lead to errors about forming references to packed fields. + iter: core::iter::Copied<slice::Iter<'a, Event>>, } impl<'a> Iterator for Iter<'a> { - type Item = (EventFlags, u64); + type Item = Event; + #[inline] fn next(&mut self) -> Option<Self::Item> { - // SAFETY: `self.context` is guaranteed to be valid because we hold - // `'context` for it. And we know this event is associated with this - // context because `wait` sets both. - self.iter - .next() - .map(|event| (event.event_flags, event.data)) + self.iter.next() } } @@ -283,11 +298,94 @@ impl<'a> Iterator for Iter<'a> { ), repr(packed) )] -struct Event { - // Match the layout of `c::epoll_event`. We just use a `u64` instead of - // the full union. - event_flags: EventFlags, - data: u64, +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct Event { + /// Which specific event(s) occurred. + pub flags: EventFlags, + /// User data. + pub data: EventData, +} + +/// Data assocated with an [`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, } /// A vector of `Event`s, plus context for interpreting them. @@ -296,6 +394,20 @@ pub struct EventVec { } impl EventVec { + /// Constructs an `EventVec` from raw pointer, length, and capacity. + /// + /// # Safety + /// + /// This function calls [`Vec::from_raw_parts`] with its arguments. + /// + /// [`Vec::from_raw_parts`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.from_raw_parts + #[inline] + pub unsafe fn from_raw_parts(ptr: *mut Event, len: usize, capacity: usize) -> Self { + Self { + events: Vec::from_raw_parts(ptr, len, capacity), + } + } + /// Constructs an `EventVec` with memory for `capacity` `Event`s. #[inline] pub fn with_capacity(capacity: usize) -> Self { @@ -338,7 +450,7 @@ impl EventVec { #[inline] pub fn iter(&self) -> Iter<'_> { Iter { - iter: self.events.iter(), + iter: self.events.iter().copied(), } } @@ -357,10 +469,18 @@ impl EventVec { impl<'a> IntoIterator for &'a EventVec { type IntoIter = Iter<'a>; - type Item = (EventFlags, u64); + type Item = Event; #[inline] fn into_iter(self) -> Self::IntoIter { self.iter() } } + +#[test] +fn test_epoll_layouts() { + check_renamed_type!(Event, epoll_event); + check_renamed_type!(Event, epoll_event); + check_renamed_struct_renamed_field!(Event, epoll_event, flags, events); + check_renamed_struct_renamed_field!(Event, epoll_event, data, u64); +} diff --git a/vendor/rustix/src/backend/libc/event/mod.rs b/vendor/rustix/src/backend/libc/event/mod.rs new file mode 100644 index 000000000..6aed4612a --- /dev/null +++ b/vendor/rustix/src/backend/libc/event/mod.rs @@ -0,0 +1,9 @@ +pub(crate) mod poll_fd; +#[cfg(not(windows))] +pub(crate) mod types; + +#[cfg_attr(windows, path = "windows_syscalls.rs")] +pub(crate) mod syscalls; + +#[cfg(linux_kernel)] +pub mod epoll; diff --git a/vendor/rustix/src/backend/libc/io/poll_fd.rs b/vendor/rustix/src/backend/libc/event/poll_fd.rs index a0568c60a..49a6d1126 100644 --- a/vendor/rustix/src/backend/libc/io/poll_fd.rs +++ b/vendor/rustix/src/backend/libc/event/poll_fd.rs @@ -1,17 +1,20 @@ -use super::super::c; -use super::super::conv::borrowed_fd; -#[cfg(windows)] -use super::super::fd::RawFd; -use super::super::fd::{AsFd, AsRawFd, BorrowedFd, LibcFd}; +use crate::backend::c; +use crate::backend::conv::borrowed_fd; +use crate::backend::fd::{AsFd, AsRawFd, BorrowedFd, LibcFd}; use bitflags::bitflags; use core::marker::PhantomData; #[cfg(windows)] -use std::fmt; +use { + crate::backend::fd::{AsSocket, RawFd}, + core::fmt, +}; bitflags! { /// `POLL*` flags for use with [`poll`]. /// /// [`poll`]: crate::io::poll + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PollFlags: c::c_short { /// `POLLIN` const IN = c::POLLIN; @@ -21,16 +24,14 @@ bitflags! { /// `POLLOUT` const OUT = c::POLLOUT; /// `POLLRDNORM` - #[cfg(not(target_os = "redox"))] const RDNORM = c::POLLRDNORM; /// `POLLWRNORM` - #[cfg(not(target_os = "redox"))] const WRNORM = c::POLLWRNORM; /// `POLLRDBAND` - #[cfg(not(any(target_os = "redox", target_os = "wasi")))] + #[cfg(not(target_os = "wasi"))] const RDBAND = c::POLLRDBAND; /// `POLLWRBAND` - #[cfg(not(any(target_os = "redox", target_os = "wasi")))] + #[cfg(not(target_os = "wasi"))] const WRBAND = c::POLLWRBAND; /// `POLLERR` const ERR = c::POLLERR; @@ -40,7 +41,7 @@ bitflags! { const NVAL = c::POLLNVAL; /// `POLLRDHUP` #[cfg(all( - any(target_os = "android", target_os = "linux"), + linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))), )] const RDHUP = c::POLLRDHUP; @@ -49,7 +50,7 @@ bitflags! { /// `struct pollfd`—File descriptor and flags for use with [`poll`]. /// -/// [`poll`]: crate::io::poll +/// [`poll`]: crate::event::poll #[doc(alias = "pollfd")] #[derive(Clone)] #[cfg_attr(not(windows), derive(Debug))] @@ -126,7 +127,7 @@ impl<'fd> AsFd for PollFd<'fd> { } #[cfg(windows)] -impl<'fd> io_lifetimes::AsSocket for PollFd<'fd> { +impl<'fd> AsSocket for PollFd<'fd> { #[inline] fn as_socket(&self) -> BorrowedFd<'_> { // SAFETY: Our constructors and `set_fd` require `pollfd.fd` to be diff --git a/vendor/rustix/src/backend/libc/event/syscalls.rs b/vendor/rustix/src/backend/libc/event/syscalls.rs new file mode 100644 index 000000000..11f6af83e --- /dev/null +++ b/vendor/rustix/src/backend/libc/event/syscalls.rs @@ -0,0 +1,161 @@ +//! libc syscalls supporting `rustix::event`. + +use crate::backend::c; +use crate::backend::conv::ret_c_int; +#[cfg(any(apple, netbsdlike, target_os = "dragonfly", target_os = "solaris"))] +use crate::backend::conv::ret_owned_fd; +use crate::event::PollFd; +#[cfg(any(linux_kernel, bsd, solarish))] +use crate::fd::OwnedFd; +use crate::io; +#[cfg(any(bsd, solarish))] +use {crate::backend::conv::borrowed_fd, crate::fd::BorrowedFd, core::mem::MaybeUninit}; +#[cfg(solarish)] +use { + crate::backend::conv::ret, crate::event::port::Event, crate::utils::as_mut_ptr, + core::ptr::null_mut, +}; +#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "illumos"))] +use {crate::backend::conv::ret_owned_fd, crate::event::EventfdFlags}; +#[cfg(bsd)] +use {crate::event::kqueue::Event, crate::utils::as_ptr, core::ptr::null}; + +#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "illumos"))] +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))) + } + + #[cfg(any(target_os = "freebsd", target_os = "illumos"))] + 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 [MaybeUninit<Event>], + timeout: Option<&c::timespec>, +) -> io::Result<c::c_int> { + ret_c_int(c::kevent( + borrowed_fd(kq), + changelist.as_ptr().cast(), + changelist + .len() + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + eventlist.as_mut_ptr().cast(), + eventlist + .len() + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + timeout.map_or(null(), as_ptr), + )) +} + +#[inline] +pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> { + let nfds = fds + .len() + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + + ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) + .map(|nready| nready as usize) +} + +#[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<&mut c::timespec>, +) -> io::Result<Event> { + let mut event = MaybeUninit::<c::port_event>::uninit(); + let timeout = timeout.map_or(null_mut(), as_mut_ptr); + + unsafe { + ret(c::port_get(borrowed_fd(port), event.as_mut_ptr(), timeout))?; + } + + // If we're done, initialize the event and return it. + Ok(Event(unsafe { event.assume_init() })) +} + +#[cfg(solarish)] +pub(crate) fn port_getn( + port: BorrowedFd<'_>, + timeout: Option<&mut c::timespec>, + events: &mut Vec<Event>, + mut nget: u32, +) -> io::Result<()> { + let timeout = timeout.map_or(null_mut(), as_mut_ptr); + unsafe { + ret(c::port_getn( + borrowed_fd(port), + events.as_mut_ptr().cast(), + events.len().try_into().unwrap(), + &mut nget, + timeout, + ))?; + } + + // Update the vector length. + unsafe { + events.set_len(nget.try_into().unwrap()); + } + + Ok(()) +} + +#[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)) } +} diff --git a/vendor/rustix/src/backend/libc/event/types.rs b/vendor/rustix/src/backend/libc/event/types.rs new file mode 100644 index 000000000..632b1be63 --- /dev/null +++ b/vendor/rustix/src/backend/libc/event/types.rs @@ -0,0 +1,19 @@ +#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "illumos"))] +use {crate::backend::c, bitflags::bitflags}; + +#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "illumos"))] +bitflags! { + /// `EFD_*` flags for use with [`eventfd`]. + /// + /// [`eventfd`]: crate::io::eventfd + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct EventfdFlags: u32 { + /// `EFD_CLOEXEC` + const CLOEXEC = bitcast!(c::EFD_CLOEXEC); + /// `EFD_NONBLOCK` + const NONBLOCK = bitcast!(c::EFD_NONBLOCK); + /// `EFD_SEMAPHORE` + const SEMAPHORE = bitcast!(c::EFD_SEMAPHORE); + } +} diff --git a/vendor/rustix/src/backend/libc/event/windows_syscalls.rs b/vendor/rustix/src/backend/libc/event/windows_syscalls.rs new file mode 100644 index 000000000..8ccad4794 --- /dev/null +++ b/vendor/rustix/src/backend/libc/event/windows_syscalls.rs @@ -0,0 +1,16 @@ +//! Windows system calls in the `event` module. + +use crate::backend::c; +use crate::backend::conv::ret_c_int; +use crate::event::PollFd; +use crate::io; + +pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> { + let nfds = fds + .len() + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + + ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) + .map(|nready| nready as usize) +} diff --git a/vendor/rustix/src/backend/libc/fs/dir.rs b/vendor/rustix/src/backend/libc/fs/dir.rs index b6eb32580..c8a4d77c9 100644 --- a/vendor/rustix/src/backend/libc/fs/dir.rs +++ b/vendor/rustix/src/backend/libc/fs/dir.rs @@ -1,8 +1,7 @@ -use super::super::c; -use super::super::conv::owned_fd; -use super::super::offset::libc_ino_t; #[cfg(not(any(solarish, target_os = "haiku")))] use super::types::FileType; +use crate::backend::c; +use crate::backend::conv::owned_fd; use crate::fd::{AsFd, BorrowedFd}; use crate::ffi::{CStr, CString}; use crate::fs::{fcntl_getfl, fstat, openat, Mode, OFlags, Stat}; @@ -18,8 +17,8 @@ use crate::fs::{fstatfs, StatFs}; use crate::fs::{fstatvfs, StatVfs}; use crate::io; #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +#[cfg(feature = "process")] use crate::process::fchdir; -#[cfg(target_os = "wasi")] use alloc::borrow::ToOwned; #[cfg(not(linux_like))] use c::readdir as libc_readdir; @@ -139,7 +138,9 @@ impl Dir { } /// `fchdir(self)` + #[cfg(feature = "process")] #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] + #[cfg_attr(doc_cfg, doc(cfg(feature = "process")))] #[inline] pub fn chdir(&self) -> io::Result<()> { fchdir(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) @@ -183,10 +184,10 @@ pub struct DirEntry { d_type: u8, #[cfg(not(any(freebsdlike, netbsdlike)))] - d_ino: libc_ino_t, + d_ino: c::ino_t, #[cfg(any(freebsdlike, netbsdlike))] - d_fileno: libc_ino_t, + d_fileno: c::ino_t, name: CString, } diff --git a/vendor/rustix/src/backend/libc/fs/inotify.rs b/vendor/rustix/src/backend/libc/fs/inotify.rs index 8a42e0583..05d4d904f 100644 --- a/vendor/rustix/src/backend/libc/fs/inotify.rs +++ b/vendor/rustix/src/backend/libc/fs/inotify.rs @@ -1,7 +1,7 @@ //! inotify support for working with inotifies -use super::super::c; -use super::super::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_owned_fd}; +use crate::backend::c; +use crate::backend::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_owned_fd}; use crate::fd::{BorrowedFd, OwnedFd}; use crate::io; use bitflags::bitflags; @@ -10,11 +10,13 @@ bitflags! { /// `IN_*` for use with [`inotify_init`]. /// /// [`inotify_init`]: crate::fs::inotify::inotify_init - pub struct CreateFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct CreateFlags: u32 { /// `IN_CLOEXEC` - const CLOEXEC = c::IN_CLOEXEC; + const CLOEXEC = bitcast!(c::IN_CLOEXEC); /// `IN_NONBLOCK` - const NONBLOCK = c::IN_NONBLOCK; + const NONBLOCK = bitcast!(c::IN_NONBLOCK); } } @@ -22,7 +24,8 @@ bitflags! { /// `IN*` for use with [`inotify_add_watch`]. /// /// [`inotify_add_watch`]: crate::fs::inotify::inotify_add_watch - #[derive(Default)] + #[repr(transparent)] + #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct WatchFlags: u32 { /// `IN_ACCESS` const ACCESS = c::IN_ACCESS; @@ -78,7 +81,7 @@ bitflags! { #[doc(alias = "inotify_init1")] pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> { // SAFETY: `inotify_init1` has no safety preconditions. - unsafe { ret_owned_fd(c::inotify_init1(flags.bits())) } + unsafe { ret_owned_fd(c::inotify_init1(bitflags_bits!(flags))) } } /// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify @@ -113,7 +116,8 @@ pub fn inotify_add_watch<P: crate::path::Arg>( /// by [`inotify_add_watch`] and not previously have been removed. #[doc(alias = "inotify_rm_watch")] pub fn inotify_remove_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> { - // Android's `inotify_rm_watch` takes u32 despite `inotify_add_watch` is i32. + // 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. diff --git a/vendor/rustix/src/backend/libc/fs/makedev.rs b/vendor/rustix/src/backend/libc/fs/makedev.rs index afe942a59..640d5005b 100644 --- a/vendor/rustix/src/backend/libc/fs/makedev.rs +++ b/vendor/rustix/src/backend/libc/fs/makedev.rs @@ -1,9 +1,10 @@ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -use super::super::c; +use crate::backend::c; use crate::fs::Dev; #[cfg(not(any( apple, + solarish, target_os = "aix", target_os = "android", target_os = "emscripten", @@ -13,6 +14,13 @@ 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 { @@ -54,19 +62,24 @@ pub(crate) fn makedev(maj: u32, min: u32) -> Dev { #[cfg(not(any( apple, freebsdlike, - netbsdlike, target_os = "android", target_os = "emscripten", + target_os = "netbsd" )))] #[inline] pub(crate) fn major(dev: Dev) -> u32 { unsafe { c::major(dev) } } -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] +#[cfg(any( + apple, + freebsdlike, + target_os = "netbsd", + all(target_os = "android", not(target_pointer_width = "32")), +))] #[inline] pub(crate) fn major(dev: Dev) -> u32 { - // Android's `major` oddly has signed return types. + // On some platforms `major` oddly has signed return types. (unsafe { c::major(dev) }) as u32 } @@ -88,19 +101,24 @@ pub(crate) fn major(dev: Dev) -> u32 { #[cfg(not(any( apple, freebsdlike, - netbsdlike, target_os = "android", target_os = "emscripten", + target_os = "netbsd" )))] #[inline] pub(crate) fn minor(dev: Dev) -> u32 { unsafe { c::minor(dev) } } -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] +#[cfg(any( + apple, + freebsdlike, + target_os = "netbsd", + all(target_os = "android", not(target_pointer_width = "32")) +))] #[inline] pub(crate) fn minor(dev: Dev) -> u32 { - // Android's `minor` oddly has signed return types. + // On some platforms, `minor` oddly has signed return types. (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 index 54a48103c..28579c993 100644 --- a/vendor/rustix/src/backend/libc/fs/mod.rs +++ b/vendor/rustix/src/backend/libc/fs/mod.rs @@ -1,8 +1,8 @@ #[cfg(not(target_os = "redox"))] pub(crate) mod dir; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub mod inotify; -#[cfg(not(any(solarish, target_os = "haiku", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] pub(crate) mod makedev; #[cfg(not(windows))] pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/fs/syscalls.rs b/vendor/rustix/src/backend/libc/fs/syscalls.rs index 40c160182..bdba777e9 100644 --- a/vendor/rustix/src/backend/libc/fs/syscalls.rs +++ b/vendor/rustix/src/backend/libc/fs/syscalls.rs @@ -1,48 +1,9 @@ //! libc syscalls supporting `rustix::fs`. -use super::super::c; -use super::super::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd, ret_usize}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::{syscall_ret, syscall_ret_owned_fd, syscall_ret_usize}; -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -use super::super::offset::libc_fallocate; -#[cfg(not(any( - apple, - netbsdlike, - solarish, - target_os = "dragonfly", - target_os = "haiku", - target_os = "redox", -)))] -use super::super::offset::libc_posix_fadvise; -#[cfg(not(any( - apple, - netbsdlike, - solarish, - target_os = "aix", - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", - target_os = "redox", -)))] -use super::super::offset::libc_posix_fallocate; -use super::super::offset::{libc_fstat, libc_fstatat, libc_ftruncate, libc_lseek, libc_off_t}; -#[cfg(not(any( - solarish, - target_os = "haiku", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -use super::super::offset::{libc_fstatfs, libc_statfs}; -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -use super::super::offset::{libc_fstatvfs, libc_statvfs}; -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -use super::super::time::types::LibcTimespec; +use crate::backend::c; +use crate::backend::conv::{ + borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd, ret_usize, +}; use crate::fd::{BorrowedFd, OwnedFd}; use crate::ffi::CStr; #[cfg(apple)] @@ -56,6 +17,8 @@ use crate::ffi::CString; target_os = "redox", )))] use crate::fs::Advice; +#[cfg(not(target_os = "redox"))] +use crate::fs::AtFlags; #[cfg(not(any( netbsdlike, solarish, @@ -66,14 +29,9 @@ use crate::fs::Advice; use crate::fs::FallocateFlags; #[cfg(not(target_os = "wasi"))] use crate::fs::FlockOperation; -#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "freebsd"))] use crate::fs::MemfdFlags; -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] use crate::fs::SealFlags; #[cfg(not(any( solarish, @@ -83,38 +41,39 @@ use crate::fs::SealFlags; target_os = "wasi", )))] use crate::fs::StatFs; -#[cfg(any(apple, target_os = "android", target_os = "linux"))] -use crate::fs::XattrFlags; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::fs::{cwd, RenameFlags, ResolveFlags, Statx, StatxFlags}; -use crate::fs::{Access, Mode, OFlags, Stat, Timestamps}; +use crate::fs::{Access, Mode, OFlags, SeekFrom, Stat, Timestamps}; #[cfg(not(any(apple, target_os = "redox", target_os = "wasi")))] use crate::fs::{Dev, FileType}; #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] use crate::fs::{StatVfs, StatVfsMountFlags}; -use crate::io::{self, SeekFrom}; +use crate::io; +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +use crate::timespec::LibcTimespec; #[cfg(not(target_os = "wasi"))] -use crate::process::{Gid, Uid}; +use crate::ugid::{Gid, Uid}; #[cfg(not(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", )))] use crate::utils::as_ptr; -use core::convert::TryInto; -#[cfg(any(apple, target_os = "android", target_os = "linux"))] -use core::mem::size_of; +#[cfg(apple)] +use alloc::vec; use core::mem::MaybeUninit; -#[cfg(any(target_os = "android", target_os = "linux"))] -use core::ptr::null; -#[cfg(any(apple, target_os = "android", target_os = "linux"))] -use core::ptr::null_mut; #[cfg(apple)] use { - super::super::conv::nonnegative_ret, + crate::backend::conv::nonnegative_ret, crate::fs::{copyfile_state_t, CloneFlags, CopyfileFlags}, }; -#[cfg(not(target_os = "redox"))] -use {super::super::offset::libc_openat, crate::fs::AtFlags}; +#[cfg(any(apple, linux_kernel))] +use {crate::fs::XattrFlags, core::mem::size_of, core::ptr::null_mut}; +#[cfg(linux_kernel)] +use { + crate::fs::{RenameFlags, ResolveFlags, Statx, StatxFlags, CWD}, + core::ptr::null, +}; #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), @@ -127,6 +86,64 @@ weak!(fn __utimensat64(c::c_int, *const c::c_char, *const LibcTimespec, c::c_int ))] 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 and riscv64 has no `open` syscall so use `openat`. + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + { + openat_via_syscall(CWD, path, oflags, mode) + } + + // Use the `open` syscall. + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + unsafe { + syscall! { + fn open( + pathname: *const c::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"))] + 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. @@ -137,18 +154,22 @@ fn openat_via_syscall( oflags: OFlags, mode: Mode, ) -> io::Result<OwnedFd> { + syscall! { + fn openat( + base_dirfd: c::c_int, + pathname: *const c::c_char, + oflags: c::c_int, + mode: c::mode_t + ) via SYS_openat -> c::c_int + } + unsafe { - let dirfd = borrowed_fd(dirfd); - let path = c_str(path); - let oflags = oflags.bits(); - let mode = c::c_uint::from(mode.bits()); - ret_owned_fd(c::syscall( - c::SYS_openat, - c::c_long::from(dirfd), - path, - c::c_long::from(oflags), - mode as c::c_long, - ) as c::c_int) + ret_owned_fd(openat( + borrowed_fd(dirfd), + c_str(path), + bitflags_bits!(oflags), + bitflags_bits!(mode), + )) } } @@ -165,15 +186,30 @@ pub(crate) fn openat( 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 { - // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since - // `libc_openat` is declared as a variadic function and narrower - // arguments are promoted. - ret_owned_fd(libc_openat( + ret_owned_fd(c::openat( borrowed_fd(dirfd), c_str(path), - oflags.bits(), - c::c_uint::from(mode.bits()), + bitflags_bits!(oflags), + mode, )) } } @@ -189,7 +225,7 @@ pub(crate) fn openat( pub(crate) fn statfs(filename: &CStr) -> io::Result<StatFs> { unsafe { let mut result = MaybeUninit::<StatFs>::uninit(); - ret(libc_statfs(c_str(filename), result.as_mut_ptr()))?; + ret(c::statfs(c_str(filename), result.as_mut_ptr()))?; Ok(result.assume_init()) } } @@ -198,15 +234,30 @@ pub(crate) fn statfs(filename: &CStr) -> io::Result<StatFs> { #[inline] pub(crate) fn statvfs(filename: &CStr) -> io::Result<StatVfs> { unsafe { - let mut result = MaybeUninit::<libc_statvfs>::uninit(); - ret(libc_statvfs(c_str(filename), result.as_mut_ptr()))?; + 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())) } } +#[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::<c::c_char>(), + buf.len(), + )) + } +} + #[cfg(not(target_os = "redox"))] #[inline] -pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result<usize> { +pub(crate) fn readlinkat( + dirfd: BorrowedFd<'_>, + path: &CStr, + buf: &mut [MaybeUninit<u8>], +) -> io::Result<usize> { unsafe { ret_usize(c::readlinkat( borrowed_fd(dirfd), @@ -217,6 +268,10 @@ pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> } } +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 { @@ -228,21 +283,31 @@ pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Res } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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 { - syscall_ret_usize(c::syscall( - c::SYS_getdents64, - fd, - buf.as_mut_ptr().cast::<c::c_char>(), + 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(target_os = "redox"))] pub(crate) fn linkat( old_dirfd: BorrowedFd<'_>, @@ -251,20 +316,107 @@ pub(crate) fn linkat( new_path: &CStr, flags: AtFlags, ) -> io::Result<()> { + // macOS <= 10.9 lacks `linkat`. + #[cfg(target_os = "macos")] + unsafe { + weak! { + fn linkat( + c::c_int, + *const c::c_char, + c::c_int, + *const c::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), - flags.bits(), + 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(target_os = "redox"))] pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { - unsafe { ret(c::unlinkat(borrowed_fd(dirfd), c_str(path), flags.bits())) } + // macOS <= 10.9 lacks `unlinkat`. + #[cfg(target_os = "macos")] + unsafe { + weak! { + fn unlinkat( + c::c_int, + *const c::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"))] @@ -274,6 +426,34 @@ pub(crate) fn renameat( 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 c::c_char, + c::c_int, + *const c::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), @@ -292,7 +472,7 @@ pub(crate) fn renameat2( new_path: &CStr, flags: RenameFlags, ) -> io::Result<()> { - // `getrandom` wasn't supported in glibc until 2.28. + // `renameat2` wasn't supported in glibc until 2.28. weak_or_syscall! { fn renameat2( olddirfd: c::c_int, @@ -332,6 +512,10 @@ pub(crate) fn renameat2( renameat(old_dirfd, old_path, new_dirfd, 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, @@ -347,16 +531,64 @@ pub(crate) fn symlinkat( } } +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")))] + { + match crate::fs::statx( + crate::fs::CWD, + path, + AtFlags::empty(), + StatxFlags::BASIC_STATS, + ) { + Ok(x) => statx_to_stat(x), + Err(io::Errno::NOSYS) => statat_old(crate::fs::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"))))] + unsafe { + let mut stat = MaybeUninit::<Stat>::uninit(); + ret(c::stat(c_str(path), stat.as_mut_ptr()))?; + Ok(stat.assume_init()) + } +} + +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")))] + { + match crate::fs::statx( + crate::fs::CWD, + path, + AtFlags::SYMLINK_NOFOLLOW, + StatxFlags::BASIC_STATS, + ) { + Ok(x) => statx_to_stat(x), + Err(io::Errno::NOSYS) => statat_old(crate::fs::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"))))] + unsafe { + let mut stat = MaybeUninit::<Stat>::uninit(); + ret(c::lstat(c_str(path), stat.as_mut_ptr()))?; + Ok(stat.assume_init()) + } +} + #[cfg(not(target_os = "redox"))] pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { - // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use - // `statx`. - #[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - ))] + // See the comments in `fstat` about using `crate::fs::statx` here. + #[cfg(all(linux_kernel, any(target_pointer_width = "32", target_arch = "mips64")))] { - match statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { + 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), @@ -365,39 +597,38 @@ pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io:: // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and // there's nothing practical we can do. - #[cfg(not(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - )))] + #[cfg(not(all(linux_kernel, any(target_pointer_width = "32", target_arch = "mips64"))))] unsafe { let mut stat = MaybeUninit::<Stat>::uninit(); - ret(libc_fstatat( + ret(c::fstatat( borrowed_fd(dirfd), c_str(path), stat.as_mut_ptr(), - flags.bits(), + bitflags_bits!(flags), ))?; Ok(stat.assume_init()) } } -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), -))] +#[cfg(all(linux_kernel, any(target_pointer_width = "32", target_arch = "mips64")))] fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { unsafe { let mut result = MaybeUninit::<c::stat64>::uninit(); - ret(libc_fstatat( + ret(c::fstatat( borrowed_fd(dirfd), c_str(path), result.as_mut_ptr(), - flags.bits(), + bitflags_bits!(flags), ))?; stat64_to_stat(result.assume_init()) } } +#[cfg(not(target_os = "emscripten"))] +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 = "redox")))] pub(crate) fn accessat( dirfd: BorrowedFd<'_>, @@ -405,17 +636,56 @@ pub(crate) fn accessat( access: Access, flags: AtFlags, ) -> io::Result<()> { + // macOS <= 10.9 lacks `faccessat`. + #[cfg(target_os = "macos")] + unsafe { + weak! { + fn faccessat( + c::c_int, + *const c::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), - access.bits(), - flags.bits(), + 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, @@ -449,7 +719,7 @@ pub(crate) fn utimensat( borrowed_fd(dirfd), c_str(path), libc_times.as_ptr(), - flags.bits(), + bitflags_bits!(flags), )) } else { utimensat_old(dirfd, path, times, flags) @@ -473,7 +743,7 @@ pub(crate) fn utimensat( borrowed_fd(dirfd), c_str(path), as_ptr(times).cast(), - flags.bits(), + bitflags_bits!(flags), )) } @@ -509,7 +779,7 @@ pub(crate) fn utimensat( borrowed_fd(dirfd), c_str(path), as_ptr(times).cast(), - flags.bits(), + bitflags_bits!(flags), )); } @@ -625,16 +895,16 @@ unsafe fn utimensat_old( borrowed_fd(dirfd), c_str(path), old_times.as_ptr(), - flags.bits(), + bitflags_bits!(flags), )) } -#[cfg(not(any( - target_os = "android", - target_os = "linux", - target_os = "redox", - target_os = "wasi", -)))] +#[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 = "redox", target_os = "wasi")))] pub(crate) fn chmodat( dirfd: BorrowedFd<'_>, path: &CStr, @@ -646,12 +916,12 @@ pub(crate) fn chmodat( borrowed_fd(dirfd), c_str(path), mode.bits() as c::mode_t, - flags.bits(), + bitflags_bits!(flags), )) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn chmodat( dirfd: BorrowedFd<'_>, path: &CStr, @@ -664,6 +934,13 @@ pub(crate) fn chmodat( // 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 c::c_char, + mode: c::mode_t + ) via SYS_fchmodat -> c::c_int + } if flags == AtFlags::SYMLINK_NOFOLLOW { return Err(io::Errno::OPNOTSUPP); } @@ -671,14 +948,10 @@ pub(crate) fn chmodat( return Err(io::Errno::INVAL); } unsafe { - // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since - // `libc_openat` is declared as a variadic function and narrower - // arguments are promoted. - syscall_ret(c::syscall( - c::SYS_fchmodat, + ret(fchmodat( borrowed_fd(dirfd), c_str(path), - c::c_uint::from(mode.bits()), + mode.bits() as c::mode_t, )) } } @@ -699,7 +972,14 @@ pub(crate) fn fclonefileat( ) via SYS_fclonefileat -> c::c_int } - unsafe { ret(fclonefileat(srcfd, dst_dirfd, c_str(dst), flags.bits())) } + unsafe { + ret(fclonefileat( + srcfd, + dst_dirfd, + c_str(dst), + bitflags_bits!(flags), + )) + } } #[cfg(not(any(target_os = "redox", target_os = "wasi")))] @@ -711,13 +991,13 @@ pub(crate) fn chownat( flags: AtFlags, ) -> io::Result<()> { unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); + let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); ret(c::fchownat( borrowed_fd(dirfd), c_str(path), ow, gr, - flags.bits(), + bitflags_bits!(flags), )) } } @@ -740,7 +1020,7 @@ pub(crate) fn mknodat( } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn copy_file_range( fd_in: BorrowedFd<'_>, off_in: Option<&mut u64>, @@ -748,26 +1028,36 @@ pub(crate) fn copy_file_range( 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 + } + assert_eq!(size_of::<c::loff_t>(), size_of::<u64>()); 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; + 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; + off_out_val = **off_out as i64; &mut off_out_val } else { null_mut() }; let copied = unsafe { - syscall_ret_usize(c::syscall( - c::SYS_copy_file_range, + ret_usize(copy_file_range( borrowed_fd(fd_in), off_in_ptr, borrowed_fd(fd_out), @@ -813,7 +1103,7 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, offset: u64, len: u64, advice: Advice) len }; - let err = unsafe { libc_posix_fadvise(borrowed_fd(fd), offset, len, advice as c::c_int) }; + 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 { @@ -824,32 +1114,21 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, offset: u64, len: u64, advice: Advice) } pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result<OFlags> { - unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFL)).map(OFlags::from_bits_truncate) } + 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( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result<SealFlags> { - unsafe { - ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GET_SEALS)) - .map(|flags| SealFlags::from_bits_unchecked(flags)) - } + let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GET_SEALS))? }; + Ok(SealFlags::from_bits_retain(bitcast!(flags))) } -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] +#[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())) } } @@ -889,7 +1168,7 @@ pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::R } pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result<u64> { - let (whence, offset): (c::c_int, libc_off_t) = match pos { + let (whence, offset): (c::c_int, c::off_t) = match pos { SeekFrom::Start(pos) => { let pos: u64 = pos; // Silently cast; we'll get `EINVAL` if the value is negative. @@ -902,51 +1181,58 @@ pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result<u64> { #[cfg(any(freebsdlike, target_os = "linux", target_os = "solaris"))] SeekFrom::Hole(offset) => (c::SEEK_HOLE, offset), }; - let offset = unsafe { ret_off_t(libc_lseek(borrowed_fd(fd), offset, whence))? }; + 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(libc_lseek(borrowed_fd(fd), 0, c::SEEK_CUR))? }; + let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), 0, c::SEEK_CUR))? }; Ok(offset as u64) } -#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))] +#[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), mode.bits())) } + unsafe { ret(c::fchmod(borrowed_fd(fd), bitflags_bits!(mode))) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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`. - unsafe { - syscall_ret(c::syscall( - c::SYS_fchmod, - borrowed_fd(fd), - c::c_uint::from(mode.bits()), - )) + 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(any(target_os = "android", target_os = "linux"))] +#[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::process::translate_fchown_args(owner, group); - syscall_ret(c::syscall(c::SYS_fchown, borrowed_fd(fd), ow, gr)) + let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); + ret(fchown(borrowed_fd(fd), ow, gr)) } } -#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))] +#[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::process::translate_fchown_args(owner, group); + let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); ret(c::fchown(borrowed_fd(fd), ow, gr)) } } @@ -956,18 +1242,21 @@ pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn syncfs(fd: BorrowedFd<'_>) -> io::Result<()> { // Some versions of Android libc lack a `syncfs` function. #[cfg(target_os = "android")] - unsafe { - syscall_ret(c::syscall(c::SYS_syncfs, borrowed_fd(fd))) + 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"))] - unsafe { - ret(c::syncfs(borrowed_fd(fd))) + 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 = "redox", target_os = "wasi")))] @@ -978,12 +1267,13 @@ pub(crate) fn sync() { pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> { // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use // `statx`. - #[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - ))] + // + // 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")))] { - match statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { + 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), @@ -992,25 +1282,19 @@ pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> { // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and // there's nothing practical we can do. - #[cfg(not(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - )))] + #[cfg(not(all(linux_kernel, any(target_pointer_width = "32", target_arch = "mips64"))))] unsafe { let mut stat = MaybeUninit::<Stat>::uninit(); - ret(libc_fstat(borrowed_fd(fd), stat.as_mut_ptr()))?; + ret(c::fstat(borrowed_fd(fd), stat.as_mut_ptr()))?; Ok(stat.assume_init()) } } -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), -))] +#[cfg(all(linux_kernel, any(target_pointer_width = "32", target_arch = "mips64")))] fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { unsafe { let mut result = MaybeUninit::<c::stat64>::uninit(); - ret(libc_fstat(borrowed_fd(fd), result.as_mut_ptr()))?; + ret(c::fstat(borrowed_fd(fd), result.as_mut_ptr()))?; stat64_to_stat(result.assume_init()) } } @@ -1025,22 +1309,22 @@ fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result<StatFs> { let mut statfs = MaybeUninit::<StatFs>::uninit(); unsafe { - ret(libc_fstatfs(borrowed_fd(fd), statfs.as_mut_ptr()))?; + 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::<libc_statvfs>::uninit(); + let mut statvfs = MaybeUninit::<c::statvfs>::uninit(); unsafe { - ret(libc_fstatvfs(borrowed_fd(fd), statvfs.as_mut_ptr()))?; + 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: libc_statvfs) -> StatVfs { +fn libc_statvfs_to_statvfs(from: c::statvfs) -> StatVfs { StatVfs { f_bsize: from.f_bsize as u64, f_frsize: from.f_frsize as u64, @@ -1051,7 +1335,7 @@ fn libc_statvfs_to_statvfs(from: libc_statvfs) -> StatVfs { f_ffree: from.f_ffree as u64, f_favail: from.f_ffree as u64, f_fsid: from.f_fsid as u64, - f_flag: unsafe { StatVfsMountFlags::from_bits_unchecked(from.f_flag as u64) }, + f_flag: StatVfsMountFlags::from_bits_retain(from.f_flag as u64), f_namemax: from.f_namemax as u64, } } @@ -1174,15 +1458,20 @@ pub(crate) fn fallocate( let offset = offset as i64; let len = len as i64; - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "fuchsia"))] unsafe { - ret(libc_fallocate(borrowed_fd(fd), mode.bits(), offset, len)) + ret(c::fallocate( + borrowed_fd(fd), + bitflags_bits!(mode), + offset, + len, + )) } - #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))] + #[cfg(not(any(linux_kernel, target_os = "fuchsia")))] { assert!(mode.is_empty()); - let err = unsafe { libc_posix_fallocate(borrowed_fd(fd), offset, len) }; + let err = unsafe { c::posix_fallocate(borrowed_fd(fd), offset, len) }; // `posix_fallocate` returns its error status rather than using `errno`. if err == 0 { @@ -1240,10 +1529,10 @@ pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { let length = length.try_into().map_err(|_overflow_err| io::Errno::FBIG)?; - unsafe { ret(libc_ftruncate(borrowed_fd(fd), length)) } + unsafe { ret(c::ftruncate(borrowed_fd(fd), length)) } } -#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "freebsd"))] pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd> { #[cfg(target_os = "freebsd")] weakcall! { @@ -1253,7 +1542,7 @@ pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd ) -> c::c_int } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] weak_or_syscall! { fn memfd_create( name: *const c::c_char, @@ -1261,10 +1550,10 @@ pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd ) via SYS_memfd_create -> c::c_int } - unsafe { ret_owned_fd(memfd_create(c_str(path), flags.bits())) } + unsafe { ret_owned_fd(memfd_create(c_str(path), bitflags_bits!(flags))) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn openat2( dirfd: BorrowedFd<'_>, path: &CStr, @@ -1272,45 +1561,38 @@ pub(crate) fn openat2( mode: Mode, resolve: ResolveFlags, ) -> io::Result<OwnedFd> { - let oflags: i32 = oflags.bits(); - let open_how = OpenHow { - oflag: u64::from(oflags as u32), + use linux_raw_sys::general::open_how; + + syscall! { + fn openat2( + base_dirfd: c::c_int, + pathname: *const c::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 { - syscall_ret_owned_fd(c::syscall( - SYS_OPENAT2, + ret_owned_fd(openat2( borrowed_fd(dirfd), c_str(path), - &open_how, - SIZEOF_OPEN_HOW, + &mut open_how, + size_of::<open_how>(), )) } } -#[cfg(all( - target_pointer_width = "32", - any(target_os = "android", target_os = "linux"), -))] +#[cfg(all(linux_kernel, target_pointer_width = "32"))] const SYS_OPENAT2: i32 = 437; -#[cfg(all( - target_pointer_width = "64", - any(target_os = "android", target_os = "linux"), -))] +#[cfg(all(linux_kernel, target_pointer_width = "64"))] const SYS_OPENAT2: i64 = 437; -#[cfg(any(target_os = "android", target_os = "linux"))] -#[repr(C)] -#[derive(Debug)] -struct OpenHow { - oflag: u64, - mode: u64, - resolve: u64, -} -#[cfg(any(target_os = "android", target_os = "linux"))] -const SIZEOF_OPEN_HOW: usize = size_of::<OpenHow>(); - #[cfg(target_os = "linux")] pub(crate) fn sendfile( out_fd: BorrowedFd<'_>, @@ -1329,10 +1611,7 @@ pub(crate) fn sendfile( } /// Convert from a Linux `statx` value to rustix's `Stat`. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "32", -))] +#[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(), @@ -1369,10 +1648,7 @@ fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { /// Convert from a Linux `statx` value to rustix's `Stat`. /// /// mips64' `struct stat64` in libc has private fields, and `stx_blocks` -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_arch = "mips64", -))] +#[cfg(all(linux_kernel, target_arch = "mips64"))] fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { let mut result: Stat = unsafe { core::mem::zeroed() }; @@ -1409,10 +1685,7 @@ fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { } /// Convert from a Linux `stat64` value to rustix's `Stat`. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "32", -))] +#[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)?, @@ -1447,10 +1720,7 @@ fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { /// /// mips64' `struct stat64` in libc has private fields, and `st_blocks` has /// type `i64`. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_arch = "mips64", -))] +#[cfg(all(linux_kernel, target_arch = "mips64"))] fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { let mut result: Stat = unsafe { core::mem::zeroed() }; @@ -1483,7 +1753,7 @@ fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { Ok(result) } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[allow(non_upper_case_globals)] mod sys { use super::{c, BorrowedFd, Statx}; @@ -1499,7 +1769,7 @@ mod sys { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[allow(non_upper_case_globals)] pub(crate) fn statx( dirfd: BorrowedFd<'_>, @@ -1534,7 +1804,7 @@ pub(crate) fn statx( ret(sys::statx( dirfd, c_str(path), - flags.bits(), + bitflags_bits!(flags), mask.bits(), statx_buf.as_mut_ptr(), ))?; @@ -1542,14 +1812,14 @@ pub(crate) fn statx( } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[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())), + ret(sys::statx(CWD, null(), 0, 0, null_mut())), Err(io::Errno::FAULT) ) } @@ -1575,7 +1845,7 @@ pub(crate) unsafe fn fcopyfile( borrowed_fd(from), borrowed_fd(to), state, - flags.bits(), + bitflags_bits!(flags), )) } @@ -1632,7 +1902,7 @@ pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result<CString> { // `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 = alloc::vec![0; c::PATH_MAX as usize]; + 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 @@ -1645,9 +1915,6 @@ pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result<CString> { let l = buf.iter().position(|&c| c == 0).unwrap(); buf.truncate(l); - - // TODO: On Rust 1.56, we can use `shrink_to` here. - //buf.shrink_to(l + 1); buf.shrink_to_fit(); Ok(CString::new(buf).unwrap()) @@ -1781,7 +2048,7 @@ struct Attrlist { forkattr: Attrgroup, } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn mount( source: Option<&CStr>, target: &CStr, @@ -1800,12 +2067,12 @@ pub(crate) fn mount( } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn unmount(target: &CStr, flags: super::types::UnmountFlags) -> io::Result<()> { - unsafe { ret(c::umount2(target.as_ptr(), flags.bits())) } + unsafe { ret(c::umount2(target.as_ptr(), bitflags_bits!(flags))) } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn getxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result<usize> { let value_ptr = value.as_mut_ptr(); @@ -1832,7 +2099,7 @@ pub(crate) fn getxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn lgetxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result<usize> { let value_ptr = value.as_mut_ptr(); @@ -1859,7 +2126,7 @@ pub(crate) fn lgetxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Resul } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn fgetxattr(fd: BorrowedFd<'_>, name: &CStr, value: &mut [u8]) -> io::Result<usize> { let value_ptr = value.as_mut_ptr(); @@ -1886,7 +2153,7 @@ pub(crate) fn fgetxattr(fd: BorrowedFd<'_>, name: &CStr, value: &mut [u8]) -> io } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn setxattr( path: &CStr, name: &CStr, @@ -1917,7 +2184,7 @@ pub(crate) fn setxattr( } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn lsetxattr( path: &CStr, name: &CStr, @@ -1948,7 +2215,7 @@ pub(crate) fn lsetxattr( } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn fsetxattr( fd: BorrowedFd<'_>, name: &CStr, @@ -1979,7 +2246,7 @@ pub(crate) fn fsetxattr( } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn listxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize> { #[cfg(not(apple))] unsafe { @@ -1997,7 +2264,7 @@ pub(crate) fn listxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn llistxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize> { #[cfg(not(apple))] unsafe { @@ -2015,7 +2282,7 @@ pub(crate) fn llistxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usiz } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn flistxattr(fd: BorrowedFd<'_>, list: &mut [c::c_char]) -> io::Result<usize> { let fd = borrowed_fd(fd); @@ -2030,7 +2297,7 @@ pub(crate) fn flistxattr(fd: BorrowedFd<'_>, list: &mut [c::c_char]) -> io::Resu } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> { #[cfg(not(apple))] unsafe { @@ -2043,7 +2310,7 @@ pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> { } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> { #[cfg(not(apple))] unsafe { @@ -2060,7 +2327,7 @@ pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> { } } -#[cfg(any(apple, target_os = "android", target_os = "linux"))] +#[cfg(any(apple, linux_kernel))] pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> { let fd = borrowed_fd(fd); @@ -2074,3 +2341,52 @@ pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> { ret(c::fremovexattr(fd, name.as_ptr(), 0)) } } + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result<u32> { + let mut result = MaybeUninit::<c::c_uint>::uninit(); + unsafe { + ret(c::ioctl(borrowed_fd(fd), c::BLKSSZGET, result.as_mut_ptr()))?; + Ok(result.assume_init() as u32) + } +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> { + let mut result = MaybeUninit::<c::c_uint>::uninit(); + unsafe { + ret(c::ioctl( + borrowed_fd(fd), + c::BLKPBSZGET, + result.as_mut_ptr(), + ))?; + Ok(result.assume_init() as u32) + } +} + +// Sparc lacks `FICLONE`. +#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] +pub(crate) fn ioctl_ficlone(fd: BorrowedFd<'_>, src_fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { + ret(c::ioctl( + borrowed_fd(fd), + c::FICLONE as _, + borrowed_fd(src_fd), + )) + } +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn ext4_ioc_resize_fs(fd: BorrowedFd<'_>, blocks: u64) -> io::Result<()> { + // TODO: Fix linux-raw-sys to define ioctl codes for sparc. + #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] + const EXT4_IOC_RESIZE_FS: u32 = 0x8008_6610; + + #[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] + use linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS; + + unsafe { ret(c::ioctl(borrowed_fd(fd), EXT4_IOC_RESIZE_FS as _, &blocks)) } +} diff --git a/vendor/rustix/src/backend/libc/fs/types.rs b/vendor/rustix/src/backend/libc/fs/types.rs index 0cf7fe8ff..b52f0e210 100644 --- a/vendor/rustix/src/backend/libc/fs/types.rs +++ b/vendor/rustix/src/backend/libc/fs/types.rs @@ -1,10 +1,12 @@ -use super::super::c; +use crate::backend::c; 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: c::c_int { /// `R_OK` const READ_OK = c::R_OK; @@ -27,44 +29,49 @@ bitflags! { /// /// [`openat`]: crate::fs::openat /// [`statat`]: crate::fs::statat - pub struct AtFlags: c::c_int { + #[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(any(target_os = "emscripten", target_os = "android")))] + const EACCESS = bitcast!(c::AT_EACCESS); + /// `AT_REMOVEDIR` - const REMOVEDIR = c::AT_REMOVEDIR; + const REMOVEDIR = bitcast!(c::AT_REMOVEDIR); /// `AT_SYMLINK_FOLLOW` - const SYMLINK_FOLLOW = c::AT_SYMLINK_FOLLOW; + const SYMLINK_FOLLOW = bitcast!(c::AT_SYMLINK_FOLLOW); - /// `AT_SYMLINK_NOFOLLOW` - const SYMLINK_NOFOLLOW = c::AT_SYMLINK_NOFOLLOW; + /// `AT_NO_AUTOMOUNT` + #[cfg(any(linux_like, target_os = "fuchsia"))] + const NO_AUTOMOUNT = bitcast!(c::AT_NO_AUTOMOUNT); /// `AT_EMPTY_PATH` #[cfg(any( - target_os = "android", + linux_kernel, target_os = "freebsd", target_os = "fuchsia", - target_os = "linux", ))] - const EMPTY_PATH = c::AT_EMPTY_PATH; + const EMPTY_PATH = bitcast!(c::AT_EMPTY_PATH); /// `AT_RESOLVE_BENEATH` #[cfg(target_os = "freebsd")] - const RESOLVE_BENEATH = c::AT_RESOLVE_BENEATH; - - /// `AT_EACCESS` - #[cfg(not(any(target_os = "emscripten", target_os = "android")))] - const EACCESS = c::AT_EACCESS; + 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 = c::AT_STATX_SYNC_AS_STAT; + 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 = c::AT_STATX_FORCE_SYNC; + 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 = c::AT_STATX_DONT_SYNC; + const STATX_DONT_SYNC = bitcast!(c::AT_STATX_DONT_SYNC); } } @@ -74,6 +81,8 @@ bitflags! { /// [`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(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. @@ -166,7 +175,7 @@ impl From<RawMode> for Mode { } impl From<Mode> for RawMode { - /// Support conversions from `Mode to raw mode values. + /// Support conversions from `Mode` to raw mode values. /// /// ``` /// use rustix::fs::{Mode, RawMode}; @@ -182,9 +191,11 @@ bitflags! { /// `O_*` constants for use with [`openat`]. /// /// [`openat`]: crate::fs::openat - pub struct OFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct OFlags: u32 { /// `O_ACCMODE` - const ACCMODE = c::O_ACCMODE; + const ACCMODE = bitcast!(c::O_ACCMODE); /// Similar to `ACCMODE`, but just includes the read/write flags, and /// no other flags. @@ -193,117 +204,112 @@ bitflags! { /// sometimes we really just want the read/write bits. Caution is /// indicated, as the presence of `O_PATH` may mean that the read/write /// bits don't have their usual meaning. - const RWMODE = c::O_RDONLY | c::O_WRONLY | c::O_RDWR; + const RWMODE = bitcast!(c::O_RDONLY | c::O_WRONLY | c::O_RDWR); /// `O_APPEND` - const APPEND = c::O_APPEND; + const APPEND = bitcast!(c::O_APPEND); /// `O_CREAT` #[doc(alias = "CREAT")] - const CREATE = c::O_CREAT; + const CREATE = bitcast!(c::O_CREAT); /// `O_DIRECTORY` - const DIRECTORY = c::O_DIRECTORY; + const DIRECTORY = bitcast!(c::O_DIRECTORY); /// `O_DSYNC` #[cfg(not(any(target_os = "dragonfly", target_os = "redox")))] - const DSYNC = c::O_DSYNC; + const DSYNC = bitcast!(c::O_DSYNC); /// `O_EXCL` - const EXCL = c::O_EXCL; + const EXCL = bitcast!(c::O_EXCL); /// `O_FSYNC` #[cfg(any( bsd, all(target_os = "linux", not(target_env = "musl")), ))] - const FSYNC = c::O_FSYNC; + const FSYNC = bitcast!(c::O_FSYNC); /// `O_NOFOLLOW` - const NOFOLLOW = c::O_NOFOLLOW; + const NOFOLLOW = bitcast!(c::O_NOFOLLOW); /// `O_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; + const NONBLOCK = bitcast!(c::O_NONBLOCK); /// `O_RDONLY` - const RDONLY = c::O_RDONLY; + const RDONLY = bitcast!(c::O_RDONLY); /// `O_WRONLY` - const WRONLY = c::O_WRONLY; + const WRONLY = bitcast!(c::O_WRONLY); /// `O_RDWR` - const RDWR = c::O_RDWR; + const RDWR = bitcast!(c::O_RDWR); /// `O_NOCTTY` #[cfg(not(target_os = "redox"))] - const NOCTTY = c::O_NOCTTY; + const NOCTTY = bitcast!(c::O_NOCTTY); /// `O_RSYNC` #[cfg(any( + linux_kernel, netbsdlike, - target_os = "android", target_os = "emscripten", - target_os = "linux", target_os = "wasi", ))] - const RSYNC = c::O_RSYNC; + const RSYNC = bitcast!(c::O_RSYNC); /// `O_SYNC` #[cfg(not(target_os = "redox"))] - const SYNC = c::O_SYNC; + const SYNC = bitcast!(c::O_SYNC); /// `O_TRUNC` - const TRUNC = c::O_TRUNC; + const TRUNC = bitcast!(c::O_TRUNC); /// `O_PATH` #[cfg(any( - target_os = "android", + linux_kernel, target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", - target_os = "linux", target_os = "redox", ))] - const PATH = c::O_PATH; + const PATH = bitcast!(c::O_PATH); /// `O_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; + const CLOEXEC = bitcast!(c::O_CLOEXEC); /// `O_TMPFILE` #[cfg(any( - target_os = "android", + linux_kernel, target_os = "emscripten", target_os = "fuchsia", - target_os = "linux", ))] - const TMPFILE = c::O_TMPFILE; + const TMPFILE = bitcast!(c::O_TMPFILE); /// `O_NOATIME` #[cfg(any( - target_os = "android", + linux_kernel, target_os = "fuchsia", - target_os = "linux", ))] - const NOATIME = c::O_NOATIME; + const NOATIME = bitcast!(c::O_NOATIME); /// `O_DIRECT` #[cfg(any( - target_os = "android", + linux_kernel, target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", - target_os = "linux", target_os = "netbsd", ))] - const DIRECT = c::O_DIRECT; + const DIRECT = bitcast!(c::O_DIRECT); /// `O_RESOLVE_BENEATH` #[cfg(target_os = "freebsd")] - const RESOLVE_BENEATH = c::O_RESOLVE_BENEATH; + const RESOLVE_BENEATH = bitcast!(c::O_RESOLVE_BENEATH); /// `O_EMPTY_PATH` #[cfg(target_os = "freebsd")] - const EMPTY_PATH = c::O_EMPTY_PATH; + const EMPTY_PATH = bitcast!(c::O_EMPTY_PATH); } } @@ -312,7 +318,9 @@ bitflags! { /// `CLONE_*` constants for use with [`fclonefileat`]. /// /// [`fclonefileat`]: crate::fs::fclonefileat - pub struct CloneFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct CloneFlags: u32 { /// `CLONE_NOFOLLOW` const NOFOLLOW = 1; @@ -337,6 +345,8 @@ bitflags! { /// `COPYFILE_*` constants for use with [`fcopyfile`]. /// /// [`fcopyfile`]: crate::fs::fcopyfile + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct CopyfileFlags: c::c_uint { /// `COPYFILE_ACL` const ACL = copyfile::ACL; @@ -361,12 +371,13 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `RESOLVE_*` constants for use with [`openat2`]. /// /// [`openat2`]: crate::fs::openat2 - #[derive(Default)] + #[repr(transparent)] + #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ResolveFlags: u64 { /// `RESOLVE_NO_XDEV` const NO_XDEV = 0x01; @@ -388,20 +399,22 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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: c::c_uint { /// `RENAME_EXCHANGE` - const EXCHANGE = c::RENAME_EXCHANGE as _; + const EXCHANGE = bitcast!(c::RENAME_EXCHANGE); /// `RENAME_NOREPLACE` - const NOREPLACE = c::RENAME_NOREPLACE as _; + const NOREPLACE = bitcast!(c::RENAME_NOREPLACE); /// `RENAME_WHITEOUT` - const WHITEOUT = c::RENAME_WHITEOUT as _; + const WHITEOUT = bitcast!(c::RENAME_WHITEOUT); } } @@ -528,11 +541,13 @@ pub enum Advice { DontNeed = c::POSIX_FADV_DONTNEED as c::c_uint, } -#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +#[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: c::c_uint { /// `MFD_CLOEXEC` const CLOEXEC = c::MFD_CLOEXEC; @@ -570,30 +585,27 @@ bitflags! { } } -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] +#[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 - pub struct SealFlags: i32 { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct SealFlags: u32 { /// `F_SEAL_SEAL`. - const SEAL = c::F_SEAL_SEAL; + const SEAL = bitcast!(c::F_SEAL_SEAL); /// `F_SEAL_SHRINK`. - const SHRINK = c::F_SEAL_SHRINK; + const SHRINK = bitcast!(c::F_SEAL_SHRINK); /// `F_SEAL_GROW`. - const GROW = c::F_SEAL_GROW; + const GROW = bitcast!(c::F_SEAL_GROW); /// `F_SEAL_WRITE`. - const WRITE = c::F_SEAL_WRITE; + const WRITE = bitcast!(c::F_SEAL_WRITE); /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) - #[cfg(any(target_os = "android", target_os = "linux"))] - const FUTURE_WRITE = c::F_SEAL_FUTURE_WRITE; + #[cfg(linux_kernel)] + const FUTURE_WRITE = bitcast!(c::F_SEAL_FUTURE_WRITE); } } @@ -602,6 +614,8 @@ 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; @@ -645,6 +659,9 @@ bitflags! { /// `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; } @@ -658,6 +675,8 @@ 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 = 0x0001; @@ -711,7 +730,9 @@ bitflags! { /// `FALLOC_FL_*` constants for use with [`fallocate`]. /// /// [`fallocate`]: crate::fs::fallocate - pub struct FallocateFlags: i32 { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct FallocateFlags: u32 { /// `FALLOC_FL_KEEP_SIZE` #[cfg(not(any( bsd, @@ -719,7 +740,7 @@ bitflags! { target_os = "haiku", target_os = "wasi", )))] - const KEEP_SIZE = c::FALLOC_FL_KEEP_SIZE; + const KEEP_SIZE = bitcast!(c::FALLOC_FL_KEEP_SIZE); /// `FALLOC_FL_PUNCH_HOLE` #[cfg(not(any( bsd, @@ -727,7 +748,7 @@ bitflags! { target_os = "haiku", target_os = "wasi", )))] - const PUNCH_HOLE = c::FALLOC_FL_PUNCH_HOLE; + const PUNCH_HOLE = bitcast!(c::FALLOC_FL_PUNCH_HOLE); /// `FALLOC_FL_NO_HIDE_STALE` #[cfg(not(any( bsd, @@ -738,7 +759,7 @@ bitflags! { target_os = "fuchsia", target_os = "wasi", )))] - const NO_HIDE_STALE = c::FALLOC_FL_NO_HIDE_STALE; + const NO_HIDE_STALE = bitcast!(c::FALLOC_FL_NO_HIDE_STALE); /// `FALLOC_FL_COLLAPSE_RANGE` #[cfg(not(any( bsd, @@ -747,7 +768,7 @@ bitflags! { target_os = "emscripten", target_os = "wasi", )))] - const COLLAPSE_RANGE = c::FALLOC_FL_COLLAPSE_RANGE; + const COLLAPSE_RANGE = bitcast!(c::FALLOC_FL_COLLAPSE_RANGE); /// `FALLOC_FL_ZERO_RANGE` #[cfg(not(any( bsd, @@ -756,7 +777,7 @@ bitflags! { target_os = "emscripten", target_os = "wasi", )))] - const ZERO_RANGE = c::FALLOC_FL_ZERO_RANGE; + const ZERO_RANGE = bitcast!(c::FALLOC_FL_ZERO_RANGE); /// `FALLOC_FL_INSERT_RANGE` #[cfg(not(any( bsd, @@ -765,7 +786,7 @@ bitflags! { target_os = "emscripten", target_os = "wasi", )))] - const INSERT_RANGE = c::FALLOC_FL_INSERT_RANGE; + const INSERT_RANGE = bitcast!(c::FALLOC_FL_INSERT_RANGE); /// `FALLOC_FL_UNSHARE_RANGE` #[cfg(not(any( bsd, @@ -774,32 +795,39 @@ bitflags! { target_os = "emscripten", target_os = "wasi", )))] - const UNSHARE_RANGE = c::FALLOC_FL_UNSHARE_RANGE; + const UNSHARE_RANGE = bitcast!(c::FALLOC_FL_UNSHARE_RANGE); } } #[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(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] const MANDLOCK = c::ST_MANDLOCK as u64; /// `ST_NOATIME` - #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] const NOATIME = c::ST_NOATIME as u64; /// `ST_NODEV` - #[cfg(any(target_os = "aix", target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any( + linux_kernel, + target_os = "aix", + target_os = "emscripten", + target_os = "fuchsia" + ))] const NODEV = c::ST_NODEV as u64; /// `ST_NODIRATIME` - #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] const NODIRATIME = c::ST_NODIRATIME as u64; /// `ST_NOEXEC` - #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] const NOEXEC = c::ST_NOEXEC as u64; /// `ST_NOSUID` @@ -813,7 +841,7 @@ bitflags! { const RELATIME = c::ST_RELATIME as u64; /// `ST_SYNCHRONOUS` - #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] const SYNCHRONOUS = c::ST_SYNCHRONOUS as u64; } } @@ -824,20 +852,20 @@ bitflags! { /// [`fcntl_lock`]: crate::fs::fcntl_lock #[cfg(not(target_os = "wasi"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(i32)] +#[repr(u32)] pub enum FlockOperation { /// `LOCK_SH` - LockShared = c::LOCK_SH, + LockShared = bitcast!(c::LOCK_SH), /// `LOCK_EX` - LockExclusive = c::LOCK_EX, + LockExclusive = bitcast!(c::LOCK_EX), /// `LOCK_UN` - Unlock = c::LOCK_UN, + Unlock = bitcast!(c::LOCK_UN), /// `LOCK_SH | LOCK_NB` - NonBlockingLockShared = c::LOCK_SH | c::LOCK_NB, + NonBlockingLockShared = bitcast!(c::LOCK_SH | c::LOCK_NB), /// `LOCK_EX | LOCK_NB` - NonBlockingLockExclusive = c::LOCK_EX | c::LOCK_NB, + NonBlockingLockExclusive = bitcast!(c::LOCK_EX | c::LOCK_NB), /// `LOCK_UN | LOCK_NB` - NonBlockingUnlock = c::LOCK_UN | c::LOCK_NB, + NonBlockingUnlock = bitcast!(c::LOCK_UN | c::LOCK_NB), } /// `struct stat` for use with [`statat`] and [`fstat`]. @@ -852,10 +880,7 @@ pub type Stat = c::stat; /// [`statat`]: crate::fs::statat /// [`fstat`]: crate::fs::fstat #[cfg(any( - all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "64", - ), + all(linux_kernel, target_pointer_width = "64"), target_os = "emscripten", target_os = "l4re", ))] @@ -868,10 +893,7 @@ pub type Stat = c::stat64; // 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( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "32", -))] +#[cfg(all(linux_kernel, target_pointer_width = "32"))] #[repr(C)] #[derive(Debug, Copy, Clone)] #[allow(missing_docs)] @@ -1053,11 +1075,13 @@ pub type FsWord = u32; #[derive(Copy, Clone)] pub struct copyfile_state_t(pub(crate) *mut c::c_void); -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `MS_*` constants for use with [`mount`]. /// /// [`mount`]: crate::fs::mount + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountFlags: c::c_ulong { /// `MS_BIND` const BIND = c::MS_BIND; @@ -1107,11 +1131,13 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `MS_*` constants for use with [`change_mount`]. /// /// [`change_mount`]: crate::fs::mount::change_mount + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountPropagationFlags: c::c_ulong { /// `MS_SHARED` const SHARED = c::MS_SHARED; @@ -1126,30 +1152,34 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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; } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) struct MountFlagsArg(pub(crate) c::c_ulong); -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `MNT_*` constants for use with [`unmount`]. /// /// [`unmount`]: crate::fs::mount::unmount - pub struct UnmountFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct UnmountFlags: u32 { /// `MNT_FORCE` - const FORCE = c::MNT_FORCE; + const FORCE = bitcast!(c::MNT_FORCE); /// `MNT_DETACH` - const DETACH = c::MNT_DETACH; + const DETACH = bitcast!(c::MNT_DETACH); /// `MNT_EXPIRE` - const EXPIRE = c::MNT_EXPIRE; + const EXPIRE = bitcast!(c::MNT_EXPIRE); /// `UMOUNT_NOFOLLOW` - const NOFOLLOW = c::UMOUNT_NOFOLLOW; + const NOFOLLOW = bitcast!(c::UMOUNT_NOFOLLOW); } } diff --git a/vendor/rustix/src/backend/libc/io/errno.rs b/vendor/rustix/src/backend/libc/io/errno.rs index 9e808c0b4..71fba49e9 100644 --- a/vendor/rustix/src/backend/libc/io/errno.rs +++ b/vendor/rustix/src/backend/libc/io/errno.rs @@ -3,7 +3,7 @@ //! This type holds an OS error code, which conceptually corresponds to an //! `errno` value. -use super::super::c; +use crate::backend::c; use libc_errno::errno; /// The error type for `rustix` APIs. diff --git a/vendor/rustix/src/backend/libc/io/io_slice.rs b/vendor/rustix/src/backend/libc/io/io_slice.rs deleted file mode 100644 index de1ef434c..000000000 --- a/vendor/rustix/src/backend/libc/io/io_slice.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/sys/unix/io.rs -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. - -#![allow(missing_docs)] - -use super::super::c; -use core::marker::PhantomData; -use core::slice; - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: c::iovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - IoSlice { - vec: c::iovec { - iov_base: buf.as_ptr() as *mut u8 as *mut c::c_void, - iov_len: buf.len(), - }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.iov_len -= n; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } -} - -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: c::iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - IoSliceMut { - vec: c::iovec { - iov_base: buf.as_mut_ptr() as *mut c::c_void, - iov_len: buf.len(), - }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n { - panic!("advancing IoSliceMut beyond its length"); - } - - unsafe { - self.vec.iov_len -= n; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } - - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } -} diff --git a/vendor/rustix/src/backend/libc/io/mod.rs b/vendor/rustix/src/backend/libc/io/mod.rs index 1378adf3d..487388576 100644 --- a/vendor/rustix/src/backend/libc/io/mod.rs +++ b/vendor/rustix/src/backend/libc/io/mod.rs @@ -1,13 +1,6 @@ pub(crate) mod errno; #[cfg(not(windows))] -#[cfg(not(feature = "std"))] -pub(crate) mod io_slice; -pub(crate) mod poll_fd; -#[cfg(not(windows))] pub(crate) mod types; #[cfg_attr(windows, path = "windows_syscalls.rs")] pub(crate) mod syscalls; - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub mod epoll; diff --git a/vendor/rustix/src/backend/libc/io/syscalls.rs b/vendor/rustix/src/backend/libc/io/syscalls.rs index b74a63fa3..6ac1fa593 100644 --- a/vendor/rustix/src/backend/libc/io/syscalls.rs +++ b/vendor/rustix/src/backend/libc/io/syscalls.rs @@ -1,43 +1,17 @@ //! libc syscalls supporting `rustix::io`. -use super::super::c; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::syscall_ret_owned_fd; -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -use super::super::conv::syscall_ret_usize; -use super::super::conv::{borrowed_fd, ret, ret_c_int, ret_discarded_fd, ret_owned_fd, ret_usize}; -use super::super::offset::{libc_pread, libc_pwrite}; -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))] -use super::super::offset::{libc_preadv, libc_pwritev}; -#[cfg(all(target_os = "linux", target_env = "gnu"))] -use super::super::offset::{libc_preadv2, libc_pwritev2}; +use crate::backend::conv::{ + borrowed_fd, ret, ret_c_int, ret_discarded_fd, ret_owned_fd, ret_usize, +}; +use crate::backend::{c, MAX_IOV}; use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; -#[cfg(bsd)] -use crate::io::kqueue::Event; -#[cfg(solarish)] -use crate::io::port::Event; #[cfg(not(any(target_os = "aix", target_os = "wasi")))] use crate::io::DupFlags; -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux" -))] -use crate::io::EventfdFlags; -#[cfg(not(any(apple, target_os = "aix", target_os = "haiku", target_os = "wasi")))] -use crate::io::PipeFlags; -use crate::io::{self, FdFlags, IoSlice, IoSliceMut, PollFd}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::io::{IoSliceRaw, ReadWriteFlags, SpliceFlags}; +#[cfg(linux_kernel)] +use crate::io::ReadWriteFlags; +use crate::io::{self, FdFlags, IoSlice, IoSliceMut}; use core::cmp::min; -use core::convert::TryInto; use core::mem::MaybeUninit; -#[cfg(any(target_os = "android", target_os = "linux"))] -use core::ptr; #[cfg(all(feature = "fs", feature = "net"))] use libc_errno::errno; @@ -68,7 +42,7 @@ pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Resu let offset = offset as i64; unsafe { - ret_usize(libc_pread( + ret_usize(c::pread( borrowed_fd(fd), buf.as_mut_ptr().cast(), len, @@ -83,14 +57,7 @@ pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result< // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; - unsafe { - ret_usize(libc_pwrite( - borrowed_fd(fd), - buf.as_ptr().cast(), - len, - offset, - )) - } + unsafe { ret_usize(c::pwrite(borrowed_fd(fd), buf.as_ptr().cast(), len, offset)) } } pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut]) -> io::Result<usize> { @@ -98,7 +65,7 @@ pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut]) -> io::Result<u ret_usize(c::readv( borrowed_fd(fd), bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, + min(bufs.len(), MAX_IOV) as c::c_int, )) } } @@ -108,7 +75,7 @@ pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice]) -> io::Result<usize> ret_usize(c::writev( borrowed_fd(fd), bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, + min(bufs.len(), MAX_IOV) as c::c_int, )) } } @@ -122,10 +89,10 @@ pub(crate) fn preadv( // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; unsafe { - ret_usize(libc_preadv( + ret_usize(c::preadv( borrowed_fd(fd), bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, + min(bufs.len(), MAX_IOV) as c::c_int, offset, )) } @@ -136,42 +103,16 @@ pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice], offset: u64) -> io:: // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; unsafe { - ret_usize(libc_pwritev( - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, - offset, - )) - } -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(crate) fn preadv2( - fd: BorrowedFd<'_>, - bufs: &mut [IoSliceMut], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result<usize> { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - unsafe { - ret_usize(libc_preadv2( + ret_usize(c::pwritev( borrowed_fd(fd), bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, + min(bufs.len(), MAX_IOV) as c::c_int, offset, - flags.bits(), )) } } -/// At present, `libc` only has `preadv2` defined for glibc. On other -/// ABIs, use `c::syscall`. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] +#[cfg(linux_kernel)] pub(crate) fn preadv2( fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut], @@ -181,18 +122,17 @@ pub(crate) fn preadv2( // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; unsafe { - syscall_ret_usize(c::syscall( - c::SYS_preadv2, + ret_usize(c::preadv2( borrowed_fd(fd), bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, + min(bufs.len(), MAX_IOV) as c::c_int, offset, - flags.bits(), + bitflags_bits!(flags), )) } } -#[cfg(all(target_os = "linux", target_env = "gnu"))] +#[cfg(linux_kernel)] pub(crate) fn pwritev2( fd: BorrowedFd<'_>, bufs: &[IoSlice], @@ -202,39 +142,12 @@ pub(crate) fn pwritev2( // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; unsafe { - ret_usize(libc_pwritev2( + ret_usize(c::pwritev2( borrowed_fd(fd), bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, + min(bufs.len(), MAX_IOV) as c::c_int, offset, - flags.bits(), - )) - } -} - -/// At present, `libc` only has `pwritev2` defined for glibc. On other -/// ABIs, use `c::syscall`. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] -pub(crate) fn pwritev2( - fd: BorrowedFd<'_>, - bufs: &[IoSlice], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result<usize> { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - unsafe { - syscall_ret_usize(c::syscall( - c::SYS_pwritev2, - borrowed_fd(fd), - bufs.as_ptr().cast::<c::iovec>(), - min(bufs.len(), max_iov()) as c::c_int, - offset, - flags.bits(), + bitflags_bits!(flags), )) } } @@ -255,72 +168,10 @@ const READ_LIMIT: usize = c::c_int::MAX as usize - 1; #[cfg(not(target_os = "macos"))] const READ_LIMIT: usize = c::ssize_t::MAX as usize; -#[cfg(bsd)] -const fn max_iov() -> usize { - c::IOV_MAX as usize -} - -#[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "linux", - target_os = "nto" -))] -const fn max_iov() -> usize { - c::UIO_MAXIOV as usize -} - -#[cfg(not(any( - bsd, - target_os = "android", - target_os = "emscripten", - target_os = "linux", - target_os = "nto", - target_os = "horizon", -)))] -const fn max_iov() -> usize { - 16 // The minimum value required by POSIX. -} - pub(crate) unsafe fn close(raw_fd: RawFd) { let _ = c::close(raw_fd as c::c_int); } -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { - unsafe { syscall_ret_owned_fd(c::syscall(c::SYS_eventfd2, initval, flags.bits())) } -} - -#[cfg(any(target_os = "freebsd", target_os = "illumos"))] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::eventfd(initval, flags.bits())) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result<u32> { - let mut result = MaybeUninit::<c::c_uint>::uninit(); - unsafe { - ret(c::ioctl(borrowed_fd(fd), c::BLKSSZGET, result.as_mut_ptr()))?; - Ok(result.assume_init() as u32) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> { - let mut result = MaybeUninit::<c::c_uint>::uninit(); - unsafe { - ret(c::ioctl( - borrowed_fd(fd), - c::BLKPBSZGET, - result.as_mut_ptr(), - ))?; - Ok(result.assume_init() as u32) - } -} - -#[cfg(not(target_os = "redox"))] pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> { let mut nread = MaybeUninit::<c::c_int>::uninit(); unsafe { @@ -339,40 +190,6 @@ pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { } } -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn ioctl_ficlone(fd: BorrowedFd<'_>, src_fd: BorrowedFd<'_>) -> io::Result<()> { - // TODO: Enable this on mips and power once libc is updated. - #[cfg(not(any( - target_arch = "mips", - target_arch = "mips64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "sparc", - target_arch = "sparc64" - )))] - unsafe { - ret(c::ioctl( - borrowed_fd(fd), - c::FICLONE as _, - borrowed_fd(src_fd), - )) - } - - #[cfg(any( - target_arch = "mips", - target_arch = "mips64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "sparc", - target_arch = "sparc64" - ))] - { - let _ = fd; - let _ = src_fd; - Err(io::Errno::NOSYS) - } -} - #[cfg(not(any(target_os = "redox", target_os = "wasi")))] #[cfg(all(feature = "fs", feature = "net"))] pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { @@ -410,8 +227,7 @@ pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { if unsafe { c::send(borrowed_fd(fd), [].as_ptr(), 0, c::MSG_DONTWAIT) } == -1 { #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` match errno().0 { - c::EAGAIN | c::EWOULDBLOCK => (), - c::ENOTSOCK => (), + c::EAGAIN | c::EWOULDBLOCK | c::ENOTSOCK => (), c::EPIPE => write = false, err => return Err(io::Errno(err)), } @@ -427,7 +243,8 @@ pub(crate) fn is_read_write(_fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { } pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result<FdFlags> { - unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFD)).map(FdFlags::from_bits_truncate) } + 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<()> { @@ -463,7 +280,7 @@ pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io ret_discarded_fd(c::dup3( borrowed_fd(fd), borrowed_fd(new.as_fd()), - flags.bits(), + bitflags_bits!(flags), )) } } @@ -493,199 +310,3 @@ pub(crate) fn ioctl_fioclex(fd: BorrowedFd<'_>) -> io::Result<()> { )) } } - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCEXCL as _)) } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCNXCL as _)) } -} - -#[cfg(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 [MaybeUninit<Event>], - timeout: Option<&c::timespec>, -) -> io::Result<c::c_int> { - ret_c_int(c::kevent( - borrowed_fd(kq), - changelist.as_ptr() as *const _, - changelist - .len() - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - eventlist.as_mut_ptr() as *mut _, - eventlist - .len() - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - timeout.map_or(core::ptr::null(), |t| t as *const _), - )) -} - -#[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 = "haiku", target_os = "wasi")))] -pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(c::pipe2(result.as_mut_ptr().cast::<i32>(), flags.bits()))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[inline] -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> { - let nfds = fds - .len() - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - - ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) - .map(|nready| nready as usize) -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub 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 = off_in - .map(|off| (off as *mut u64).cast()) - .unwrap_or(ptr::null_mut()); - - let off_out = off_out - .map(|off| (off as *mut u64).cast()) - .unwrap_or(ptr::null_mut()); - - unsafe { - ret_usize(c::splice( - borrowed_fd(fd_in), - off_in, - borrowed_fd(fd_out), - off_out, - len, - flags.bits(), - )) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub 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(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<&mut c::timespec>, -) -> io::Result<Event> { - let mut event = MaybeUninit::<c::port_event>::uninit(); - let timeout = timeout.map_or(core::ptr::null_mut(), |t| t as *mut _); - - unsafe { - ret(c::port_get(borrowed_fd(port), event.as_mut_ptr(), timeout))?; - } - - // If we're done, initialize the event and return it. - Ok(Event(unsafe { event.assume_init() })) -} - -#[cfg(solarish)] -pub(crate) fn port_getn( - port: BorrowedFd<'_>, - timeout: Option<&mut c::timespec>, - events: &mut Vec<Event>, - mut nget: u32, -) -> io::Result<()> { - let timeout = timeout.map_or(core::ptr::null_mut(), |t| t as *mut _); - unsafe { - ret(c::port_getn( - borrowed_fd(port), - events.as_mut_ptr().cast(), - events.len().try_into().unwrap(), - &mut nget, - timeout, - ))?; - } - - // Update the vector length. - unsafe { - events.set_len(nget.try_into().unwrap()); - } - - Ok(()) -} - -#[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)) } -} diff --git a/vendor/rustix/src/backend/libc/io/types.rs b/vendor/rustix/src/backend/libc/io/types.rs index 90a5e15b5..8743336f2 100644 --- a/vendor/rustix/src/backend/libc/io/types.rs +++ b/vendor/rustix/src/backend/libc/io/types.rs @@ -1,51 +1,38 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; -#[cfg(any(target_os = "android", target_os = "linux"))] -use core::marker::PhantomData; bitflags! { /// `FD_*` constants for use with [`fcntl_getfd`] and [`fcntl_setfd`]. /// /// [`fcntl_getfd`]: crate::io::fcntl_getfd /// [`fcntl_setfd`]: crate::io::fcntl_setfd - pub struct FdFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct FdFlags: u32 { /// `FD_CLOEXEC` - const CLOEXEC = c::FD_CLOEXEC; + const CLOEXEC = bitcast!(c::FD_CLOEXEC); } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`]. /// /// [`preadv2`]: crate::io::preadv2 /// [`pwritev2`]: crate::io::pwritev - pub struct ReadWriteFlags: c::c_int { + #[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 as c::c_int; + const DSYNC = linux_raw_sys::general::RWF_DSYNC; /// `RWF_HIPRI` (since Linux 4.6) - const HIPRI = linux_raw_sys::general::RWF_HIPRI as c::c_int; + const HIPRI = linux_raw_sys::general::RWF_HIPRI; /// `RWF_SYNC` (since Linux 4.7) - const SYNC = linux_raw_sys::general::RWF_SYNC as c::c_int; + const SYNC = linux_raw_sys::general::RWF_SYNC; /// `RWF_NOWAIT` (since Linux 4.14) - const NOWAIT = linux_raw_sys::general::RWF_NOWAIT as c::c_int; + const NOWAIT = linux_raw_sys::general::RWF_NOWAIT; /// `RWF_APPEND` (since Linux 4.16) - const APPEND = linux_raw_sys::general::RWF_APPEND as c::c_int; - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `SPLICE_F_*` constants for use with [`splice`] and [`vmsplice`]. - pub struct SpliceFlags: c::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; + const APPEND = linux_raw_sys::general::RWF_APPEND; } } @@ -54,7 +41,9 @@ bitflags! { /// `O_*` constants for use with [`dup2`]. /// /// [`dup2`]: crate::io::dup2 - pub struct DupFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct DupFlags: u32 { /// `O_CLOEXEC` #[cfg(not(any( apple, @@ -62,97 +51,6 @@ bitflags! { target_os = "android", target_os = "redox", )))] // Android 5.0 has dup3, but libc doesn't have bindings - const CLOEXEC = c::O_CLOEXEC; - } -} - -#[cfg(not(any(apple, target_os = "wasi")))] -bitflags! { - /// `O_*` constants for use with [`pipe_with`]. - /// - /// [`pipe_with`]: crate::io::pipe_with - pub struct PipeFlags: c::c_int { - /// `O_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - /// `O_DIRECT` - #[cfg(not(any( - solarish, - target_os = "haiku", - target_os = "openbsd", - target_os = "redox", - )))] - const DIRECT = c::O_DIRECT; - /// `O_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - } -} - -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux" -))] -bitflags! { - /// `EFD_*` flags for use with [`eventfd`]. - /// - /// [`eventfd`]: crate::io::eventfd - pub struct EventfdFlags: c::c_int { - /// `EFD_CLOEXEC` - const CLOEXEC = c::EFD_CLOEXEC; - /// `EFD_NONBLOCK` - const NONBLOCK = c::EFD_NONBLOCK; - /// `EFD_SEMAPHORE` - const SEMAPHORE = c::EFD_SEMAPHORE; - } -} - -/// `PIPE_BUF`—The maximum size of a write to a pipe guaranteed to be atomic. -#[cfg(not(any(solarish, target_os = "haiku", target_os = "redox", target_os = "wasi")))] -pub const PIPE_BUF: usize = c::PIPE_BUF; - -#[cfg(not(any(windows, target_os = "redox")))] -pub(crate) const AT_FDCWD: c::c_int = c::AT_FDCWD; -#[cfg(not(windows))] -pub(crate) const STDIN_FILENO: c::c_int = c::STDIN_FILENO; -#[cfg(not(windows))] -pub(crate) const STDOUT_FILENO: c::c_int = c::STDOUT_FILENO; -#[cfg(not(windows))] -pub(crate) const STDERR_FILENO: c::c_int = c::STDERR_FILENO; - -/// A buffer type used 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. -#[cfg(any(target_os = "android", target_os = "linux"))] -#[repr(transparent)] -pub struct IoSliceRaw<'a> { - _buf: c::iovec, - _lifetime: PhantomData<&'a ()>, -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -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 as *mut 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() as *mut c::c_void, - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } + const CLOEXEC = bitcast!(c::O_CLOEXEC); } } diff --git a/vendor/rustix/src/backend/libc/io/windows_syscalls.rs b/vendor/rustix/src/backend/libc/io/windows_syscalls.rs index 4c6e86f94..c87a2a247 100644 --- a/vendor/rustix/src/backend/libc/io/windows_syscalls.rs +++ b/vendor/rustix/src/backend/libc/io/windows_syscalls.rs @@ -1,12 +1,10 @@ //! Windows system calls in the `io` module. -use super::super::c; -use super::super::conv::{borrowed_fd, ret, ret_c_int}; -use super::super::fd::LibcFd; +use crate::backend::c; +use crate::backend::conv::{borrowed_fd, ret}; +use crate::backend::fd::LibcFd; use crate::fd::{BorrowedFd, RawFd}; use crate::io; -use crate::io::PollFd; -use core::convert::TryInto; use core::mem::MaybeUninit; pub(crate) unsafe fn close(raw_fd: RawFd) { @@ -27,13 +25,3 @@ pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &mut data)) } } - -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> { - let nfds = fds - .len() - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - - ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) - .map(|nready| nready as usize) -} diff --git a/vendor/rustix/src/backend/libc/io_lifetimes.rs b/vendor/rustix/src/backend/libc/io_lifetimes.rs deleted file mode 100644 index 993365c0c..000000000 --- a/vendor/rustix/src/backend/libc/io_lifetimes.rs +++ /dev/null @@ -1,82 +0,0 @@ -//! `io_lifetimes` types for Windows assuming that Fd is Socket. -//! -//! We can make this assumption since `rustix` supports only `rustix::net` on -//! Windows. - -pub use io_lifetimes::{BorrowedSocket as BorrowedFd, OwnedSocket as OwnedFd}; -#[cfg(feature = "std")] -pub use std::os::windows::io::RawSocket as RawFd; -pub(crate) use windows_sys::Win32::Networking::WinSock::SOCKET as LibcFd; - -// Re-export the `Socket` traits so that users can implement them. -pub use io_lifetimes::AsSocket; - -/// A version of [`AsRawFd`] for use with Winsock2 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 Winsock2 API. - /// - /// [`as_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#tymethod.as_raw_fd - fn as_raw_fd(&self) -> RawFd; -} -#[cfg(feature = "std")] -impl<T: std::os::windows::io::AsRawSocket> AsRawFd for T { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.as_raw_socket() - } -} - -/// A version of [`IntoRawFd`] for use with Winsock2 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 Winsock2 API. - /// - /// [`into_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#tymethod.into_raw_fd - fn into_raw_fd(self) -> RawFd; -} -#[cfg(feature = "std")] -impl<T: std::os::windows::io::IntoRawSocket> IntoRawFd for T { - #[inline] - fn into_raw_fd(self) -> RawFd { - self.into_raw_socket() - } -} - -/// A version of [`FromRawFd`] for use with Winsock2 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 Winsock2 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; -} -#[cfg(feature = "std")] -impl<T: std::os::windows::io::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 Winsock2 API. -/// -/// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsFd.html -pub trait AsFd { - /// An `as_fd` function for Winsock2, where a `Fd` is a `Socket`. - fn as_fd(&self) -> BorrowedFd; -} -impl<T: AsSocket> AsFd for T { - #[inline] - fn as_fd(&self) -> BorrowedFd { - self.as_socket() - } -} diff --git a/vendor/rustix/src/backend/libc/io_uring/syscalls.rs b/vendor/rustix/src/backend/libc/io_uring/syscalls.rs index 17d3eb10c..8e8182401 100644 --- a/vendor/rustix/src/backend/libc/io_uring/syscalls.rs +++ b/vendor/rustix/src/backend/libc/io_uring/syscalls.rs @@ -1,21 +1,20 @@ //! libc syscalls supporting `rustix::io_uring`. -use super::super::c; -use super::super::conv::{borrowed_fd, syscall_ret_owned_fd, syscall_ret_u32}; +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, IoringRegisterOp}; -use linux_raw_sys::general::{__NR_io_uring_enter, __NR_io_uring_register, __NR_io_uring_setup}; #[inline] pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result<OwnedFd> { - unsafe { - syscall_ret_owned_fd(c::syscall( - __NR_io_uring_setup as _, - entries as usize, - params, - )) + 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] @@ -25,12 +24,19 @@ pub(crate) unsafe fn io_uring_register( arg: *const c::c_void, nr_args: u32, ) -> io::Result<u32> { - syscall_ret_u32(c::syscall( - __NR_io_uring_register as _, - borrowed_fd(fd), - opcode as u32 as usize, + 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 as usize, + nr_args, )) } @@ -43,12 +49,21 @@ pub(crate) unsafe fn io_uring_enter( arg: *const c::c_void, size: usize, ) -> io::Result<u32> { - syscall_ret_u32(c::syscall( - __NR_io_uring_enter as _, - borrowed_fd(fd), - to_submit as usize, - min_complete as usize, - flags.bits() as usize, + 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/syscalls.rs b/vendor/rustix/src/backend/libc/mm/syscalls.rs index 16636f1b9..4b23a58b7 100644 --- a/vendor/rustix/src/backend/libc/mm/syscalls.rs +++ b/vendor/rustix/src/backend/libc/mm/syscalls.rs @@ -1,19 +1,18 @@ //! libc syscalls supporting `rustix::mm`. -use super::super::c; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::syscall_ret_owned_fd; -use super::super::conv::{borrowed_fd, no_fd, ret}; -use super::super::offset::libc_mmap; #[cfg(not(target_os = "redox"))] use super::types::Advice; #[cfg(any(target_os = "emscripten", target_os = "linux"))] use super::types::MremapFlags; use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] use crate::fd::OwnedFd; use crate::io; @@ -52,7 +51,7 @@ pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::R } pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - let err = c::msync(addr, len, flags.bits()); + let err = c::msync(addr, len, bitflags_bits!(flags)); // `msync` returns its error status rather than using `errno`. if err == 0 { @@ -74,11 +73,11 @@ pub(crate) unsafe fn mmap( fd: BorrowedFd<'_>, offset: u64, ) -> io::Result<*mut c::c_void> { - let res = libc_mmap( + let res = c::mmap( ptr, len, - prot.bits(), - flags.bits(), + bitflags_bits!(prot), + bitflags_bits!(flags), borrowed_fd(fd), offset as i64, ); @@ -99,11 +98,11 @@ pub(crate) unsafe fn mmap_anonymous( prot: ProtFlags, flags: MapFlags, ) -> io::Result<*mut c::c_void> { - let res = libc_mmap( + let res = c::mmap( ptr, len, - prot.bits(), - flags.bits() | c::MAP_ANONYMOUS, + bitflags_bits!(prot), + bitflags_bits!(flags | MapFlags::from_bits_retain(bitcast!(c::MAP_ANONYMOUS))), no_fd(), 0, ); @@ -119,7 +118,7 @@ pub(crate) unsafe fn mprotect( len: usize, flags: MprotectFlags, ) -> io::Result<()> { - ret(c::mprotect(ptr, len, flags.bits())) + ret(c::mprotect(ptr, len, bitflags_bits!(flags))) } pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> { @@ -137,7 +136,7 @@ pub(crate) unsafe fn mremap( new_size: usize, flags: MremapFlags, ) -> io::Result<*mut c::c_void> { - let res = c::mremap(old_address, old_size, new_size, flags.bits()); + 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 { @@ -162,7 +161,7 @@ pub(crate) unsafe fn mremap_fixed( old_address, old_size, new_size, - flags.bits() | c::MAP_FIXED, + bitflags_bits!(flags | MremapFlags::from_bits_retain(bitcast!(c::MAP_FIXED))), new_address, ); if res == c::MAP_FAILED { @@ -185,7 +184,7 @@ pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<() /// /// `mlock_with` operates on raw pointers and may round out to the nearest page /// boundaries. -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] pub(crate) unsafe fn mlock_with( addr: *mut c::c_void, @@ -200,7 +199,7 @@ pub(crate) unsafe fn mlock_with( ) via SYS_mlock2 -> c::c_int } - ret(mlock2(addr, length, flags.bits())) + ret(mlock2(addr, length, bitflags_bits!(flags))) } /// # Safety @@ -212,7 +211,12 @@ pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result< ret(c::munlock(addr, length)) } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> { - syscall_ret_owned_fd(c::syscall(c::SYS_userfaultfd, flags.bits())) + syscall! { + fn userfaultfd( + flags: c::c_int + ) via SYS_userfaultfd -> c::c_int + } + ret_owned_fd(userfaultfd(bitflags_bits!(flags))) } diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs index 798fda86b..e4fecfccd 100644 --- a/vendor/rustix/src/backend/libc/mm/types.rs +++ b/vendor/rustix/src/backend/libc/mm/types.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; bitflags! { @@ -7,13 +7,15 @@ bitflags! { /// For `PROT_NONE`, use `ProtFlags::empty()`. /// /// [`mmap`]: crate::io::mmap - pub struct ProtFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct ProtFlags: u32 { /// `PROT_READ` - const READ = c::PROT_READ; + const READ = bitcast!(c::PROT_READ); /// `PROT_WRITE` - const WRITE = c::PROT_WRITE; + const WRITE = bitcast!(c::PROT_WRITE); /// `PROT_EXEC` - const EXEC = c::PROT_EXEC; + const EXEC = bitcast!(c::PROT_EXEC); } } @@ -23,19 +25,21 @@ bitflags! { /// For `PROT_NONE`, use `MprotectFlags::empty()`. /// /// [`mprotect`]: crate::io::mprotect - pub struct MprotectFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MprotectFlags: u32 { /// `PROT_READ` - const READ = c::PROT_READ; + const READ = bitcast!(c::PROT_READ); /// `PROT_WRITE` - const WRITE = c::PROT_WRITE; + const WRITE = bitcast!(c::PROT_WRITE); /// `PROT_EXEC` - const EXEC = c::PROT_EXEC; + const EXEC = bitcast!(c::PROT_EXEC); /// `PROT_GROWSUP` - #[cfg(any(target_os = "android", target_os = "linux"))] - const GROWSUP = c::PROT_GROWSUP; + #[cfg(linux_kernel)] + const GROWSUP = bitcast!(c::PROT_GROWSUP); /// `PROT_GROWSDOWN` - #[cfg(any(target_os = "android", target_os = "linux"))] - const GROWSDOWN = c::PROT_GROWSDOWN; + #[cfg(linux_kernel)] + const GROWSDOWN = bitcast!(c::PROT_GROWSDOWN); } } @@ -46,9 +50,11 @@ bitflags! { /// /// [`mmap`]: crate::io::mmap /// [`mmap_anonymous`]: crates::io::mmap_anonymous - pub struct MapFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MapFlags: u32 { /// `MAP_SHARED` - const SHARED = c::MAP_SHARED; + const SHARED = bitcast!(c::MAP_SHARED); /// `MAP_SHARED_VALIDATE` #[cfg(not(any( bsd, @@ -59,9 +65,9 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const SHARED_VALIDATE = c::MAP_SHARED_VALIDATE; + const SHARED_VALIDATE = bitcast!(c::MAP_SHARED_VALIDATE); /// `MAP_PRIVATE` - const PRIVATE = c::MAP_PRIVATE; + const PRIVATE = bitcast!(c::MAP_PRIVATE); /// `MAP_DENYWRITE` #[cfg(not(any( bsd, @@ -69,9 +75,9 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const DENYWRITE = c::MAP_DENYWRITE; + const DENYWRITE = bitcast!(c::MAP_DENYWRITE); /// `MAP_FIXED` - const FIXED = c::MAP_FIXED; + const FIXED = bitcast!(c::MAP_FIXED); /// `MAP_FIXED_NOREPLACE` #[cfg(not(any( bsd, @@ -82,7 +88,7 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const FIXED_NOREPLACE = c::MAP_FIXED_NOREPLACE; + const FIXED_NOREPLACE = bitcast!(c::MAP_FIXED_NOREPLACE); /// `MAP_GROWSDOWN` #[cfg(not(any( bsd, @@ -90,7 +96,7 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const GROWSDOWN = c::MAP_GROWSDOWN; + const GROWSDOWN = bitcast!(c::MAP_GROWSDOWN); /// `MAP_HUGETLB` #[cfg(not(any( bsd, @@ -98,7 +104,7 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const HUGETLB = c::MAP_HUGETLB; + const HUGETLB = bitcast!(c::MAP_HUGETLB); /// `MAP_HUGE_2MB` #[cfg(not(any( bsd, @@ -109,7 +115,7 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const HUGE_2MB = c::MAP_HUGE_2MB; + const HUGE_2MB = bitcast!(c::MAP_HUGE_2MB); /// `MAP_HUGE_1GB` #[cfg(not(any( bsd, @@ -120,7 +126,7 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const HUGE_1GB = c::MAP_HUGE_1GB; + const HUGE_1GB = bitcast!(c::MAP_HUGE_1GB); /// `MAP_LOCKED` #[cfg(not(any( bsd, @@ -128,16 +134,16 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const LOCKED = c::MAP_LOCKED; + const LOCKED = bitcast!(c::MAP_LOCKED); /// `MAP_NOCORE` #[cfg(freebsdlike)] - const NOCORE = c::MAP_NOCORE; + const NOCORE = bitcast!(c::MAP_NOCORE); /// `MAP_NORESERVE` #[cfg(not(any(freebsdlike, target_os = "redox")))] - const NORESERVE = c::MAP_NORESERVE; + const NORESERVE = bitcast!(c::MAP_NORESERVE); /// `MAP_NOSYNC` #[cfg(freebsdlike)] - const NOSYNC = c::MAP_NOSYNC; + const NOSYNC = bitcast!(c::MAP_NOSYNC); /// `MAP_POPULATE` #[cfg(not(any( bsd, @@ -145,7 +151,7 @@ bitflags! { target_os = "haiku", target_os = "redox", )))] - const POPULATE = c::MAP_POPULATE; + const POPULATE = bitcast!(c::MAP_POPULATE); /// `MAP_STACK` #[cfg(not(any( apple, @@ -155,10 +161,10 @@ bitflags! { target_os = "netbsd", target_os = "redox", )))] - const STACK = c::MAP_STACK; + const STACK = bitcast!(c::MAP_STACK); /// `MAP_PREFAULT_READ` #[cfg(target_os = "freebsd")] - const PREFAULT_READ = c::MAP_PREFAULT_READ; + const PREFAULT_READ = bitcast!(c::MAP_PREFAULT_READ); /// `MAP_SYNC` #[cfg(not(any( bsd, @@ -169,14 +175,14 @@ bitflags! { target_os = "haiku", target_os = "redox", all( - any(target_os = "android", target_os = "linux"), + linux_kernel, any(target_arch = "mips", target_arch = "mips64"), ) )))] - const SYNC = c::MAP_SYNC; + const SYNC = bitcast!(c::MAP_SYNC); /// `MAP_UNINITIALIZED` #[cfg(any())] - const UNINITIALIZED = c::MAP_UNINITIALIZED; + const UNINITIALIZED = bitcast!(c::MAP_UNINITIALIZED); } } @@ -188,9 +194,11 @@ bitflags! { /// /// [`mremap`]: crate::io::mremap /// [`mremap_fixed`]: crate::io::mremap_fixed - pub struct MremapFlags: i32 { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MremapFlags: u32 { /// `MREMAP_MAYMOVE` - const MAYMOVE = c::MREMAP_MAYMOVE; + const MAYMOVE = bitcast!(c::MREMAP_MAYMOVE); } } @@ -198,27 +206,31 @@ bitflags! { /// `MS_*` flags for use with [`msync`]. /// /// [`msync`]: crate::io::msync - pub struct MsyncFlags: i32 { + #[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 = c::MS_SYNC; + const SYNC = bitcast!(c::MS_SYNC); /// `MS_ASYNC`—Specifies that an update be scheduled, but the call /// returns immediately. - const ASYNC = c::MS_ASYNC; + 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 = c::MS_INVALIDATE; + const INVALIDATE = bitcast!(c::MS_INVALIDATE); } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `MLOCK_*` flags for use with [`mlock_with`]. /// /// [`mlock_with`]: crate::io::mlock_with - pub struct MlockFlags: i32 { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MlockFlags: u32 { /// `MLOCK_ONFAULT` - const ONFAULT = c::MLOCK_ONFAULT as _; + const ONFAULT = bitcast!(c::MLOCK_ONFAULT); } } @@ -227,122 +239,116 @@ bitflags! { /// [`madvise`]: crate::mm::madvise #[cfg(not(target_os = "redox"))] #[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] pub enum Advice { /// `POSIX_MADV_NORMAL` #[cfg(not(any(target_os = "android", target_os = "haiku")))] - Normal = c::POSIX_MADV_NORMAL, + Normal = bitcast!(c::POSIX_MADV_NORMAL), /// `POSIX_MADV_NORMAL` #[cfg(any(target_os = "android", target_os = "haiku"))] - Normal = c::MADV_NORMAL, + Normal = bitcast!(c::MADV_NORMAL), /// `POSIX_MADV_SEQUENTIAL` #[cfg(not(any(target_os = "android", target_os = "haiku")))] - Sequential = c::POSIX_MADV_SEQUENTIAL, + Sequential = bitcast!(c::POSIX_MADV_SEQUENTIAL), /// `POSIX_MADV_SEQUENTIAL` #[cfg(any(target_os = "android", target_os = "haiku"))] - Sequential = c::MADV_SEQUENTIAL, + Sequential = bitcast!(c::MADV_SEQUENTIAL), /// `POSIX_MADV_RANDOM` #[cfg(not(any(target_os = "android", target_os = "haiku")))] - Random = c::POSIX_MADV_RANDOM, + Random = bitcast!(c::POSIX_MADV_RANDOM), /// `POSIX_MADV_RANDOM` #[cfg(any(target_os = "android", target_os = "haiku"))] - Random = c::MADV_RANDOM, + Random = bitcast!(c::MADV_RANDOM), /// `POSIX_MADV_WILLNEED` #[cfg(not(any(target_os = "android", target_os = "haiku")))] - WillNeed = c::POSIX_MADV_WILLNEED, + WillNeed = bitcast!(c::POSIX_MADV_WILLNEED), /// `POSIX_MADV_WILLNEED` #[cfg(any(target_os = "android", target_os = "haiku"))] - WillNeed = c::MADV_WILLNEED, + WillNeed = bitcast!(c::MADV_WILLNEED), /// `POSIX_MADV_DONTNEED` #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "haiku")))] - DontNeed = c::POSIX_MADV_DONTNEED, + DontNeed = bitcast!(c::POSIX_MADV_DONTNEED), /// `POSIX_MADV_DONTNEED` #[cfg(any(target_os = "android", target_os = "haiku"))] - DontNeed = i32::MAX - 1, + 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 = i32::MAX, + LinuxDontNeed = bitcast!(i32::MAX), /// `MADV_DONTNEED` #[cfg(target_os = "android")] - LinuxDontNeed = c::MADV_DONTNEED, + LinuxDontNeed = bitcast!(c::MADV_DONTNEED), /// `MADV_FREE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxFree = c::MADV_FREE, + #[cfg(linux_kernel)] + LinuxFree = bitcast!(c::MADV_FREE), /// `MADV_REMOVE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxRemove = c::MADV_REMOVE, + #[cfg(linux_kernel)] + LinuxRemove = bitcast!(c::MADV_REMOVE), /// `MADV_DONTFORK` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDontFork = c::MADV_DONTFORK, + #[cfg(linux_kernel)] + LinuxDontFork = bitcast!(c::MADV_DONTFORK), /// `MADV_DOFORK` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDoFork = c::MADV_DOFORK, + #[cfg(linux_kernel)] + LinuxDoFork = bitcast!(c::MADV_DOFORK), /// `MADV_HWPOISON` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxHwPoison = c::MADV_HWPOISON, + #[cfg(linux_kernel)] + LinuxHwPoison = bitcast!(c::MADV_HWPOISON), /// `MADV_SOFT_OFFLINE` - #[cfg(all( - any(target_os = "android", target_os = "linux"), - not(any(target_arch = "mips", target_arch = "mips64")), - ))] - LinuxSoftOffline = c::MADV_SOFT_OFFLINE, + #[cfg(all(linux_kernel, not(any(target_arch = "mips", target_arch = "mips64"))))] + LinuxSoftOffline = bitcast!(c::MADV_SOFT_OFFLINE), /// `MADV_MERGEABLE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxMergeable = c::MADV_MERGEABLE, + #[cfg(linux_kernel)] + LinuxMergeable = bitcast!(c::MADV_MERGEABLE), /// `MADV_UNMERGEABLE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxUnmergeable = c::MADV_UNMERGEABLE, + #[cfg(linux_kernel)] + LinuxUnmergeable = bitcast!(c::MADV_UNMERGEABLE), /// `MADV_HUGEPAGE` (since Linux 2.6.38) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxHugepage = c::MADV_HUGEPAGE, + #[cfg(linux_kernel)] + LinuxHugepage = bitcast!(c::MADV_HUGEPAGE), /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxNoHugepage = c::MADV_NOHUGEPAGE, + #[cfg(linux_kernel)] + LinuxNoHugepage = bitcast!(c::MADV_NOHUGEPAGE), /// `MADV_DONTDUMP` (since Linux 3.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDontDump = c::MADV_DONTDUMP, + #[cfg(linux_kernel)] + LinuxDontDump = bitcast!(c::MADV_DONTDUMP), /// `MADV_DODUMP` (since Linux 3.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDoDump = c::MADV_DODUMP, + #[cfg(linux_kernel)] + LinuxDoDump = bitcast!(c::MADV_DODUMP), /// `MADV_WIPEONFORK` (since Linux 4.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK as i32, + #[cfg(linux_kernel)] + LinuxWipeOnFork = bitcast!(c::MADV_WIPEONFORK), /// `MADV_KEEPONFORK` (since Linux 4.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK as i32, + #[cfg(linux_kernel)] + LinuxKeepOnFork = bitcast!(c::MADV_KEEPONFORK), /// `MADV_COLD` (since Linux 5.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxCold = linux_raw_sys::general::MADV_COLD as i32, + #[cfg(linux_kernel)] + LinuxCold = bitcast!(c::MADV_COLD), /// `MADV_PAGEOUT` (since Linux 5.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT as i32, + #[cfg(linux_kernel)] + LinuxPageOut = bitcast!(c::MADV_PAGEOUT), /// `MADV_POPULATE_READ` (since Linux 5.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ as i32, + #[cfg(linux_kernel)] + LinuxPopulateRead = bitcast!(c::MADV_POPULATE_READ), /// `MADV_POPULATE_WRITE` (since Linux 5.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE as i32, + #[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")] @@ -352,15 +358,17 @@ impl Advice { pub const DontNeed: Self = Self::Normal; } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] bitflags! { /// `O_*` flags for use with [`userfaultfd`]. /// /// [`userfaultfd`]: crate::io::userfaultfd - pub struct UserfaultfdFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct UserfaultfdFlags: u32 { /// `O_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; + const CLOEXEC = bitcast!(c::O_CLOEXEC); /// `O_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; + const NONBLOCK = bitcast!(c::O_NONBLOCK); } } diff --git a/vendor/rustix/src/backend/libc/mod.rs b/vendor/rustix/src/backend/libc/mod.rs index f3433903d..357f99484 100644 --- a/vendor/rustix/src/backend/libc/mod.rs +++ b/vendor/rustix/src/backend/libc/mod.rs @@ -12,35 +12,89 @@ #![allow(clippy::useless_conversion)] mod conv; -mod offset; #[cfg(windows)] -mod io_lifetimes; -#[cfg(not(windows))] -#[cfg(not(feature = "std"))] pub(crate) mod fd { - pub(crate) use super::c::c_int as LibcFd; - pub use crate::io::fd::*; -} -#[cfg(windows)] -pub(crate) mod fd { - pub use super::io_lifetimes::*; + 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 Winsock2 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 Winsock2 API. + /// + /// [`as_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.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 Winsock2 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 Winsock2 API. + /// + /// [`into_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.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 Winsock2 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 Winsock2 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 Winsock2 API. + /// + /// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsFd.html + pub trait AsFd { + /// An `as_fd` function for Winsock2, where a `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))] -#[cfg(feature = "std")] pub(crate) mod fd { - pub use io_lifetimes::*; - - #[cfg(target_os = "wasi")] - #[allow(unused_imports)] - pub(crate) use super::c::c_int as LibcFd; - #[cfg(unix)] + pub use crate::maybe_polyfill::os::fd::{ + AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd, + }; #[allow(unused_imports)] - pub(crate) use std::os::unix::io::RawFd as LibcFd; - #[cfg(unix)] - pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; - #[cfg(target_os = "wasi")] - pub use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; + pub(crate) use RawFd as LibcFd; } // On Windows we emulate selected libc-compatible interfaces. On non-Windows, @@ -48,11 +102,13 @@ pub(crate) mod fd { #[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(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[cfg(feature = "io_uring")] pub(crate) mod io_uring; #[cfg(not(any(windows, target_os = "wasi")))] @@ -70,17 +126,30 @@ pub(crate) mod net; ))] 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(windows))] #[cfg(feature = "termios")] pub(crate) mod termios; #[cfg(not(windows))] #[cfg(feature = "thread")] pub(crate) mod thread; #[cfg(not(windows))] +#[cfg(feature = "time")] pub(crate) mod time; /// If the host libc is glibc, return `true` if it is less than version 2.25. @@ -93,11 +162,38 @@ pub(crate) mod time; #[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. + // 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 = "procfs", 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(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 = "nto", + target_os = "horizon", +)))] +const MAX_IOV: usize = 16; // The minimum value required by POSIX. diff --git a/vendor/rustix/src/backend/libc/net/addr.rs b/vendor/rustix/src/backend/libc/net/addr.rs index d00a48626..bf7d239de 100644 --- a/vendor/rustix/src/backend/libc/net/addr.rs +++ b/vendor/rustix/src/backend/libc/net/addr.rs @@ -1,18 +1,16 @@ -//! IPv4, IPv6, and Socket addresses. +//! Socket address utilities. -use super::super::c; +use crate::backend::c; #[cfg(unix)] -use crate::ffi::CStr; -#[cfg(unix)] -use crate::io; -#[cfg(unix)] -use crate::path; -#[cfg(not(windows))] -use core::convert::TryInto; -#[cfg(unix)] -use core::fmt; -#[cfg(unix)] -use core::slice; +use { + crate::ffi::CStr, + crate::io, + crate::path, + core::cmp::Ordering, + core::fmt, + core::hash::{Hash, Hasher}, + core::slice, +}; /// `struct sockaddr_un` #[cfg(unix)] @@ -56,14 +54,14 @@ impl SocketAddrUnix { } /// Construct a new abstract Unix-domain address from a byte slice. - #[cfg(any(target_os = "android", target_os = "linux"))] + #[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] = b'\0' as c::c_char; + unix.sun_path[0] = 0; for (i, b) in name.iter().enumerate() { unix.sun_path[1 + i] = *b as c::c_char; } @@ -94,11 +92,12 @@ impl SocketAddrUnix { #[inline] pub fn path(&self) -> Option<&CStr> { let len = self.len(); - if len != 0 && self.unix.sun_path[0] != b'\0' as c::c_char { + if len != 0 && self.unix.sun_path[0] != 0 { let end = len as usize - offsetof_sun_path(); let bytes = &self.unix.sun_path[..end]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. And - // `from_bytes_with_nul_unchecked` since the string is NUL-terminated. + // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. + // And `from_bytes_with_nul_unchecked` since the string is + // NUL-terminated. unsafe { Some(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( bytes.as_ptr().cast(), @@ -111,11 +110,11 @@ impl SocketAddrUnix { } /// For an abstract address, return the identifier. - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] #[inline] pub fn abstract_name(&self) -> Option<&[u8]> { let len = self.len(); - if len != 0 && self.unix.sun_path[0] == b'\0' as c::c_char { + if len != 0 && self.unix.sun_path[0] == 0 { let end = len as usize - offsetof_sun_path(); let bytes = &self.unix.sun_path[1..end]; // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. @@ -159,7 +158,7 @@ impl Eq for SocketAddrUnix {} #[cfg(unix)] impl PartialOrd for SocketAddrUnix { #[inline] - fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { let self_len = self.len() - offsetof_sun_path(); let other_len = other.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].partial_cmp(&other.unix.sun_path[..other_len]) @@ -169,7 +168,7 @@ impl PartialOrd for SocketAddrUnix { #[cfg(unix)] impl Ord for SocketAddrUnix { #[inline] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { + 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]) @@ -177,9 +176,9 @@ impl Ord for SocketAddrUnix { } #[cfg(unix)] -impl core::hash::Hash for SocketAddrUnix { +impl Hash for SocketAddrUnix { #[inline] - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { let self_len = self.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].hash(state) } @@ -191,7 +190,7 @@ impl fmt::Debug for SocketAddrUnix { if let Some(path) = self.path() { path.fmt(fmt) } else { - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] if let Some(name) = self.abstract_name() { return name.fmt(fmt); } diff --git a/vendor/rustix/src/backend/libc/net/ext.rs b/vendor/rustix/src/backend/libc/net/ext.rs index f4ad316dd..4b2d10756 100644 --- a/vendor/rustix/src/backend/libc/net/ext.rs +++ b/vendor/rustix/src/backend/libc/net/ext.rs @@ -1,4 +1,4 @@ -use super::super::c; +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 @@ -19,7 +19,6 @@ pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { addr.s_addr } -#[cfg(not(feature = "std"))] #[cfg(windows)] #[inline] pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { @@ -27,103 +26,52 @@ pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { unsafe { core::mem::transmute(addr) } } -// TODO: With Rust 1.55, we can use the above `in_addr_s_addr` definition that -// uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) 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(not(feature = "std"))] #[cfg(windows)] #[inline] pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { unsafe { core::mem::transmute(s_addr) } } -// TODO: With Rust 1.55, we can use the above `in_addr_new` definition that -// uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) 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(not(feature = "std"))] #[cfg(windows)] #[inline] pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { unsafe { core::mem::transmute(addr) } } -// TODO: With Rust 1.55, we can use the above `in6_addr_s6_addr` definition -// that uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) 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(not(feature = "std"))] #[cfg(windows)] #[inline] pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { unsafe { core::mem::transmute(s6_addr) } } -// TODO: With Rust 1.55, we can use the above `in6_addr_new` definition that -// uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) 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(not(feature = "std"))] -#[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) }; +pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 { addr.sin6_scope_id } -// TODO: With Rust 1.55, we can use the above `sockaddr_in6_sin6_scope_id` -// definition that uses a const-fn transmute. -#[cfg(feature = "std")] #[cfg(windows)] #[inline] -pub(crate) fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { - let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; +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 } @@ -150,7 +98,6 @@ pub(crate) const fn sockaddr_in6_new( } } -#[cfg(not(feature = "std"))] #[cfg(windows)] #[inline] pub(crate) const fn sockaddr_in6_new( @@ -169,25 +116,3 @@ pub(crate) const fn sockaddr_in6_new( }; unsafe { core::mem::transmute(addr) } } - -// TODO: With Rust 1.55, we can use the above `sockaddr_in6_new` definition -// that uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) 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 index f7196ae4f..1b68f1b26 100644 --- a/vendor/rustix/src/backend/libc/net/mod.rs +++ b/vendor/rustix/src/backend/libc/net/mod.rs @@ -1,7 +1,8 @@ pub(crate) mod addr; pub(crate) mod ext; +#[cfg(not(any(target_os = "redox", target_os = "wasi", windows)))] +pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; pub(crate) mod syscalls; -pub(crate) mod types; 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 new file mode 100644 index 000000000..e3f873747 --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/msghdr.rs @@ -0,0 +1,125 @@ +//! 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::backend::conv::{msg_control_len, msg_iov_len}; +use crate::backend::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; + +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6}; +use crate::utils::as_ptr; + +use core::mem::{size_of, zeroed, MaybeUninit}; + +/// Create a message header intended to receive a datagram. +pub(crate) fn with_recv_msghdr<R>( + name: &mut MaybeUninit<c::sockaddr_storage>, + iov: &mut [IoSliceMut<'_>], + control: &mut RecvAncillaryBuffer<'_>, + f: impl FnOnce(&mut c::msghdr) -> io::Result<R>, +) -> io::Result<R> { + control.clear(); + + let namelen = size_of::<c::sockaddr_storage>() as c::socklen_t; + let mut msghdr = { + let mut h: c::msghdr = unsafe { zeroed() }; + h.msg_name = name.as_mut_ptr().cast(); + h.msg_namelen = namelen; + h.msg_iov = iov.as_mut_ptr().cast(); + 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 + }; + + let res = f(&mut msghdr); + + // Reset the control length. + if res.is_ok() { + unsafe { + control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX)); + } + } + + res +} + +/// Create a message header intended to send without an address. +pub(crate) fn with_noaddr_msghdr<R>( + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + f({ + let mut h: c::msghdr = unsafe { zeroed() }; + 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 an IPv4 address. +pub(crate) fn with_v4_msghdr<R>( + addr: &SocketAddrV4, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + let encoded = unsafe { encode_sockaddr_v4(addr) }; + + f({ + let mut h: c::msghdr = unsafe { zeroed() }; + h.msg_name = as_ptr(&encoded) as _; + h.msg_namelen = size_of::<SocketAddrV4>() as _; + 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 an IPv6 address. +pub(crate) fn with_v6_msghdr<R>( + addr: &SocketAddrV6, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + let encoded = unsafe { encode_sockaddr_v6(addr) }; + + f({ + let mut h: c::msghdr = unsafe { zeroed() }; + h.msg_name = as_ptr(&encoded) as _; + h.msg_namelen = size_of::<SocketAddrV6>() as _; + 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 a Unix address. +#[cfg(all(unix, not(target_os = "redox")))] +pub(crate) fn with_unix_msghdr<R>( + addr: &crate::net::SocketAddrUnix, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + f({ + let mut h: c::msghdr = unsafe { zeroed() }; + h.msg_name = as_ptr(addr) as _; + h.msg_namelen = addr.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()); + h + }) +} diff --git a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs index 575102c27..c3b23e8c2 100644 --- a/vendor/rustix/src/backend/libc/net/read_sockaddr.rs +++ b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs @@ -1,13 +1,14 @@ -use super::super::c; +//! The BSD sockets API requires us to read the `ss_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; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; -#[cfg(not(windows))] -use alloc::vec::Vec; use core::mem::size_of; // This must match the header of `sockaddr`. @@ -46,6 +47,11 @@ pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr_stora (*storage.cast::<sockaddr_header>()).ss_family = c::AF_UNSPEC as _; } +/// Read a socket address encoded in a platform-specific format. +/// +/// # Safety +/// +/// `storage` must point to valid socket address storage. pub(crate) unsafe fn read_sockaddr( storage: *const c::sockaddr_storage, len: usize, @@ -61,7 +67,7 @@ pub(crate) unsafe fn read_sockaddr( if len < size_of::<c::sockaddr_in>() { return Err(io::Errno::INVAL); } - let decode = *storage.cast::<c::sockaddr_in>(); + let decode = &*storage.cast::<c::sockaddr_in>(); Ok(SocketAddrAny::V4(SocketAddrV4::new( Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), u16::from_be(decode.sin_port), @@ -71,7 +77,7 @@ pub(crate) unsafe fn read_sockaddr( if len < size_of::<c::sockaddr_in6>() { return Err(io::Errno::INVAL); } - let decode = *storage.cast::<c::sockaddr_in6>(); + let decode = &*storage.cast::<c::sockaddr_in6>(); #[cfg(not(windows))] let s6_addr = decode.sin6_addr.s6_addr; #[cfg(windows)] @@ -93,20 +99,40 @@ pub(crate) unsafe fn read_sockaddr( return Err(io::Errno::INVAL); } if len == offsetof_sun_path { - Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap())) + SocketAddrUnix::new(&[][..]).map(SocketAddrAny::Unix) } else { - let decode = *storage.cast::<c::sockaddr_un>(); + let decode = &*storage.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 { + return SocketAddrUnix::new_abstract_name(core::mem::transmute::< + &[c::c_char], + &[u8], + >( + &decode.sun_path[1..len - offsetof_sun_path], + )) + .map(SocketAddrAny::Unix); + } + + // Otherwise we expect a NUL-terminated filesystem path. // Trim off unused bytes from the end of `path_bytes`. let path_bytes = if cfg!(target_os = "freebsd") { // FreeBSD sometimes sets 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).unwrap()] + &decode.sun_path[..decode + .sun_path + .iter() + .position(|b| *b == 0) + .ok_or(io::Errno::INVAL)?] } else { // Otherwise, use the provided length. let provided_len = len - 1 - offsetof_sun_path; - if decode.sun_path[provided_len] != b'\0' as c::c_char { + if decode.sun_path[provided_len] != 0 { return Err(io::Errno::INVAL); } debug_assert_eq!( @@ -116,10 +142,8 @@ pub(crate) unsafe fn read_sockaddr( &decode.sun_path[..provided_len] }; - Ok(SocketAddrAny::Unix( - SocketAddrUnix::new(path_bytes.iter().map(|c| *c as u8).collect::<Vec<u8>>()) - .unwrap(), - )) + SocketAddrUnix::new(core::mem::transmute::<&[c::c_char], &[u8]>(path_bytes)) + .map(SocketAddrAny::Unix) } } _ => Err(io::Errno::INVAL), @@ -164,7 +188,7 @@ unsafe fn inner_read_sockaddr_os( match family { c::AF_INET => { assert!(len >= size_of::<c::sockaddr_in>()); - let decode = *storage.cast::<c::sockaddr_in>(); + let decode = &*storage.cast::<c::sockaddr_in>(); SocketAddrAny::V4(SocketAddrV4::new( Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), u16::from_be(decode.sin_port), @@ -172,7 +196,7 @@ unsafe fn inner_read_sockaddr_os( } c::AF_INET6 => { assert!(len >= size_of::<c::sockaddr_in6>()); - let decode = *storage.cast::<c::sockaddr_in6>(); + let decode = &*storage.cast::<c::sockaddr_in6>(); SocketAddrAny::V6(SocketAddrV6::new( Ipv6Addr::from(in6_addr_s6_addr(decode.sin6_addr)), u16::from_be(decode.sin6_port), @@ -186,11 +210,26 @@ unsafe fn inner_read_sockaddr_os( if len == offsetof_sun_path { SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) } else { - let decode = *storage.cast::<c::sockaddr_un>(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); + let decode = &*storage.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 { + return SocketAddrAny::Unix( + SocketAddrUnix::new_abstract_name(core::mem::transmute::< + &[c::c_char], + &[u8], + >( + &decode.sun_path[1..len - offsetof_sun_path], + )) + .unwrap(), + ); + } + + // Otherwise we expect a NUL-terminated filesystem path. + assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); let path_bytes = &decode.sun_path[..len - 1 - offsetof_sun_path]; // FreeBSD sometimes sets the length to longer than the length @@ -200,7 +239,7 @@ unsafe fn inner_read_sockaddr_os( let path_bytes = &path_bytes[..path_bytes.iter().position(|b| *b == 0).unwrap()]; SocketAddrAny::Unix( - SocketAddrUnix::new(path_bytes.iter().map(|c| *c as u8).collect::<Vec<u8>>()) + SocketAddrUnix::new(core::mem::transmute::<&[c::c_char], &[u8]>(path_bytes)) .unwrap(), ) } diff --git a/vendor/rustix/src/backend/libc/net/send_recv.rs b/vendor/rustix/src/backend/libc/net/send_recv.rs index 49c6f2c22..e91017e97 100644 --- a/vendor/rustix/src/backend/libc/net/send_recv.rs +++ b/vendor/rustix/src/backend/libc/net/send_recv.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; bitflags! { @@ -6,7 +6,9 @@ bitflags! { /// /// [`send`]: crate::net::send /// [`sendto`]: crate::net::sendto - pub struct SendFlags: i32 { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct SendFlags: u32 { /// `MSG_CONFIRM` #[cfg(not(any( bsd, @@ -14,15 +16,15 @@ bitflags! { windows, target_os = "haiku", )))] - const CONFIRM = c::MSG_CONFIRM; + const CONFIRM = bitcast!(c::MSG_CONFIRM); /// `MSG_DONTROUTE` - const DONTROUTE = c::MSG_DONTROUTE; + const DONTROUTE = bitcast!(c::MSG_DONTROUTE); /// `MSG_DONTWAIT` #[cfg(not(windows))] - const DONTWAIT = c::MSG_DONTWAIT; + const DONTWAIT = bitcast!(c::MSG_DONTWAIT); /// `MSG_EOR` #[cfg(not(windows))] - const EOT = c::MSG_EOR; + const EOT = bitcast!(c::MSG_EOR); /// `MSG_MORE` #[cfg(not(any( bsd, @@ -30,12 +32,12 @@ bitflags! { windows, target_os = "haiku", )))] - const MORE = c::MSG_MORE; + const MORE = bitcast!(c::MSG_MORE); #[cfg(not(any(apple, windows)))] /// `MSG_NOSIGNAL` - const NOSIGNAL = c::MSG_NOSIGNAL; + const NOSIGNAL = bitcast!(c::MSG_NOSIGNAL); /// `MSG_OOB` - const OOB = c::MSG_OOB; + const OOB = bitcast!(c::MSG_OOB); } } @@ -44,13 +46,15 @@ bitflags! { /// /// [`recv`]: crate::net::recv /// [`recvfrom`]: crate::net::recvfrom - pub struct RecvFlags: i32 { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct RecvFlags: u32 { #[cfg(not(any(apple, solarish, windows, target_os = "haiku")))] /// `MSG_CMSG_CLOEXEC` - const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; + const CMSG_CLOEXEC = bitcast!(c::MSG_CMSG_CLOEXEC); /// `MSG_DONTWAIT` #[cfg(not(windows))] - const DONTWAIT = c::MSG_DONTWAIT; + const DONTWAIT = bitcast!(c::MSG_DONTWAIT); /// `MSG_ERRQUEUE` #[cfg(not(any( bsd, @@ -58,14 +62,14 @@ bitflags! { windows, target_os = "haiku", )))] - const ERRQUEUE = c::MSG_ERRQUEUE; + const ERRQUEUE = bitcast!(c::MSG_ERRQUEUE); /// `MSG_OOB` - const OOB = c::MSG_OOB; + const OOB = bitcast!(c::MSG_OOB); /// `MSG_PEEK` - const PEEK = c::MSG_PEEK; + const PEEK = bitcast!(c::MSG_PEEK); /// `MSG_TRUNC` - const TRUNC = c::MSG_TRUNC as c::c_int; + const TRUNC = bitcast!(c::MSG_TRUNC); /// `MSG_WAITALL` - const WAITALL = c::MSG_WAITALL; + const WAITALL = bitcast!(c::MSG_WAITALL); } } diff --git a/vendor/rustix/src/backend/libc/net/syscalls.rs b/vendor/rustix/src/backend/libc/net/syscalls.rs index ac260e552..63067ff38 100644 --- a/vendor/rustix/src/backend/libc/net/syscalls.rs +++ b/vendor/rustix/src/backend/libc/net/syscalls.rs @@ -1,28 +1,29 @@ //! libc syscalls supporting `rustix::net`. -use super::super::c; -use super::super::conv::{borrowed_fd, ret, ret_owned_fd, ret_send_recv, send_recv_len}; #[cfg(unix)] use super::addr::SocketAddrUnix; use super::ext::{in6_addr_new, in_addr_new}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::read_sockaddr::initialize_family_to_unspec; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::read_sockaddr::{maybe_read_sockaddr_os, read_sockaddr_os}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::send_recv::{RecvFlags, SendFlags}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::types::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; +use crate::backend::c; +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::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; use crate::utils::as_ptr; -use core::convert::TryInto; use core::mem::{size_of, MaybeUninit}; +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +use { + super::msghdr::{with_noaddr_msghdr, with_recv_msghdr, with_v4_msghdr, with_v6_msghdr}, + crate::io::{IoSlice, IoSliceMut}, + crate::net::{RecvAncillaryBuffer, RecvMsgReturn, SendAncillaryBuffer}, +}; #[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use core::ptr::null_mut; +use { + super::read_sockaddr::{initialize_family_to_unspec, maybe_read_sockaddr_os, read_sockaddr_os}, + super::send_recv::{RecvFlags, SendFlags}, + super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}, + crate::net::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}, + core::ptr::null_mut, +}; #[cfg(not(any(target_os = "redox", target_os = "wasi")))] pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io::Result<usize> { @@ -31,7 +32,7 @@ pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io:: borrowed_fd(fd), buf.as_mut_ptr().cast(), send_recv_len(buf.len()), - flags.bits(), + bitflags_bits!(flags), )) } } @@ -43,7 +44,7 @@ pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Resu borrowed_fd(fd), buf.as_ptr().cast(), send_recv_len(buf.len()), - flags.bits(), + bitflags_bits!(flags), )) } } @@ -67,7 +68,7 @@ pub(crate) fn recvfrom( borrowed_fd(fd), buf.as_mut_ptr().cast(), send_recv_len(buf.len()), - flags.bits(), + bitflags_bits!(flags), storage.as_mut_ptr().cast(), &mut len, )) @@ -92,7 +93,7 @@ pub(crate) fn sendto_v4( borrowed_fd(fd), buf.as_ptr().cast(), send_recv_len(buf.len()), - flags.bits(), + bitflags_bits!(flags), as_ptr(&encode_sockaddr_v4(addr)).cast::<c::sockaddr>(), size_of::<SocketAddrV4>() as _, )) @@ -111,7 +112,7 @@ pub(crate) fn sendto_v6( borrowed_fd(fd), buf.as_ptr().cast(), send_recv_len(buf.len()), - flags.bits(), + bitflags_bits!(flags), as_ptr(&encode_sockaddr_v6(addr)).cast::<c::sockaddr>(), size_of::<SocketAddrV6>() as _, )) @@ -130,7 +131,7 @@ pub(crate) fn sendto_unix( borrowed_fd(fd), buf.as_ptr().cast(), send_recv_len(buf.len()), - flags.bits(), + bitflags_bits!(flags), as_ptr(&addr.unix).cast(), addr.addr_len(), )) @@ -141,13 +142,17 @@ pub(crate) fn sendto_unix( pub(crate) fn socket( domain: AddressFamily, type_: SocketType, - protocol: Protocol, + 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, - protocol.0, + raw_protocol as c::c_int, )) } } @@ -157,13 +162,17 @@ pub(crate) fn socket_with( domain: AddressFamily, type_: SocketType, flags: SocketFlags, - protocol: Protocol, + 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 | flags.bits(), - protocol.0, + (type_.0 | flags.bits()) as c::c_int, + raw_protocol as c::c_int, )) } } @@ -247,6 +256,105 @@ pub(crate) fn accept(sockfd: BorrowedFd<'_>) -> io::Result<OwnedFd> { } } +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn recvmsg( + sockfd: BorrowedFd<'_>, + iov: &mut [IoSliceMut<'_>], + control: &mut RecvAncillaryBuffer<'_>, + msg_flags: RecvFlags, +) -> io::Result<RecvMsgReturn> { + let mut storage = MaybeUninit::<c::sockaddr_storage>::uninit(); + + with_recv_msghdr(&mut storage, iov, control, |msghdr| { + let result = unsafe { + ret_send_recv(c::recvmsg( + borrowed_fd(sockfd), + msghdr, + bitflags_bits!(msg_flags), + )) + }; + + result.map(|bytes| { + // Get the address of the sender, if any. + let addr = + unsafe { maybe_read_sockaddr_os(msghdr.msg_name as _, msghdr.msg_namelen as _) }; + + RecvMsgReturn { + bytes, + address: addr, + flags: RecvFlags::from_bits_retain(bitcast!(msghdr.msg_flags)), + } + }) + }) +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn sendmsg( + sockfd: BorrowedFd<'_>, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_noaddr_msghdr(iov, control, |msghdr| unsafe { + ret_send_recv(c::sendmsg( + borrowed_fd(sockfd), + &msghdr, + bitflags_bits!(msg_flags), + )) + }) +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn sendmsg_v4( + sockfd: BorrowedFd<'_>, + addr: &SocketAddrV4, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_v4_msghdr(addr, iov, control, |msghdr| unsafe { + ret_send_recv(c::sendmsg( + borrowed_fd(sockfd), + &msghdr, + bitflags_bits!(msg_flags), + )) + }) +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn sendmsg_v6( + sockfd: BorrowedFd<'_>, + addr: &SocketAddrV6, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_v6_msghdr(addr, iov, control, |msghdr| unsafe { + ret_send_recv(c::sendmsg( + borrowed_fd(sockfd), + &msghdr, + bitflags_bits!(msg_flags), + )) + }) +} + +#[cfg(all(unix, not(target_os = "redox")))] +pub(crate) fn sendmsg_unix( + sockfd: BorrowedFd<'_>, + addr: &SocketAddrUnix, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + super::msghdr::with_unix_msghdr(addr, iov, control, |msghdr| unsafe { + ret_send_recv(c::sendmsg( + borrowed_fd(sockfd), + &msghdr, + bitflags_bits!(msg_flags), + )) + }) +} + #[cfg(not(any( apple, windows, @@ -260,7 +368,7 @@ pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, flags: SocketFlags) -> io::Res borrowed_fd(sockfd), null_mut(), null_mut(), - flags.bits(), + flags.bits() as c::c_int, ))?; Ok(owned_fd) } @@ -301,7 +409,7 @@ pub(crate) fn acceptfrom_with( borrowed_fd(sockfd), storage.as_mut_ptr().cast(), &mut len, - flags.bits(), + flags.bits() as c::c_int, ))?; Ok(( owned_fd, @@ -368,14 +476,18 @@ pub(crate) fn socketpair( domain: AddressFamily, type_: SocketType, flags: SocketFlags, - protocol: Protocol, + 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 as c::c_int | flags.bits(), - protocol.0, + (type_.0 | flags.bits()) as c::c_int, + raw_protocol as c::c_int, fds.as_mut_ptr().cast::<c::c_int>(), ))?; @@ -391,14 +503,10 @@ pub(crate) mod sockopt { use crate::net::sockopt::Timeout; use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; use crate::utils::as_mut_ptr; - use core::convert::TryInto; use core::time::Duration; #[cfg(windows)] use windows_sys::Win32::Foundation::BOOL; - // TODO: With Rust 1.53 we can use `Duration::ZERO` instead. - const DURATION_ZERO: Duration = Duration::from_secs(0); - #[inline] fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result<T> { use super::*; @@ -512,21 +620,16 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; - // TODO: With Rust 1.50, this could use `.then`. - Ok(if linger.l_onoff != 0 { - Some(Duration::from_secs(linger.l_linger as u64)) - } else { - None - }) + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] #[inline] pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] #[inline] pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result<bool> { getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) @@ -546,7 +649,7 @@ pub(crate) mod sockopt { #[cfg(not(windows))] let timeout = match timeout { Some(timeout) => { - if timeout == DURATION_ZERO { + if timeout == Duration::ZERO { return Err(io::Errno::INVAL); } @@ -577,7 +680,7 @@ pub(crate) mod sockopt { #[cfg(windows)] let timeout: u32 = match timeout { Some(timeout) => { - if timeout == DURATION_ZERO { + if timeout == Duration::ZERO { return Err(io::Errno::INVAL); } @@ -633,13 +736,13 @@ pub(crate) mod sockopt { #[cfg(any(apple, target_os = "freebsd"))] #[inline] - pub(crate) fn getsockopt_nosigpipe(fd: BorrowedFd<'_>) -> io::Result<bool> { + pub(crate) fn get_socket_nosigpipe(fd: BorrowedFd<'_>) -> io::Result<bool> { getsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE).map(to_bool) } #[cfg(any(apple, target_os = "freebsd"))] #[inline] - pub(crate) fn setsockopt_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { + pub(crate) fn set_socket_nosigpipe(fd: BorrowedFd<'_>, val: bool) -> io::Result<()> { setsockopt(fd, c::SOL_SOCKET, c::SO_NOSIGPIPE, from_bool(val)) } @@ -764,14 +867,14 @@ pub(crate) mod sockopt { setsockopt( fd, c::IPPROTO_IP as _, - c::IPV6_MULTICAST_LOOP, + c::IPV6_MULTICAST_HOPS, multicast_hops, ) } #[inline] pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_LOOP) + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) } #[inline] diff --git a/vendor/rustix/src/backend/libc/net/types.rs b/vendor/rustix/src/backend/libc/net/types.rs deleted file mode 100644 index d1d769cb4..000000000 --- a/vendor/rustix/src/backend/libc/net/types.rs +++ /dev/null @@ -1,500 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -/// A type for holding raw integer socket types. -#[doc(hidden)] -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 u32); - - /// `SOCK_DGRAM` - pub const DGRAM: Self = Self(c::SOCK_DGRAM as u32); - - /// `SOCK_SEQPACKET` - pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET as u32); - - /// `SOCK_RAW` - pub const RAW: Self = Self(c::SOCK_RAW as u32); - - /// `SOCK_RDM` - #[cfg(not(target_os = "haiku"))] - pub const RDM: Self = Self(c::SOCK_RDM as u32); - - /// 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. -#[doc(hidden)] -pub type RawAddressFamily = c::sa_family_t; - -/// `AF_*` constants. -#[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` - pub const INET: Self = Self(c::AF_INET as _); - /// `AF_INET6` - pub const INET6: Self = Self(c::AF_INET6 as _); - /// `AF_NETLINK` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - 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 = "haiku", - )))] - pub const AX25: Self = Self(c::AF_AX25 as _); - /// `AF_IPX` - pub const IPX: Self = Self(c::AF_IPX as _); - /// `AF_APPLETALK` - pub const APPLETALK: Self = Self(c::AF_APPLETALK as _); - /// `AF_NETROM` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const NETROM: Self = Self(c::AF_NETROM as _); - /// `AF_BRIDGE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); - /// `AF_ATMPVC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); - /// `AF_X25` - #[cfg(not(any( - bsd, - windows, - target_os = "haiku", - )))] - pub const X25: Self = Self(c::AF_X25 as _); - /// `AF_ROSE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const ROSE: Self = Self(c::AF_ROSE as _); - /// `AF_DECnet` - #[cfg(not(target_os = "haiku"))] - pub const DECnet: Self = Self(c::AF_DECnet as _); - /// `AF_NETBEUI` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); - /// `AF_SECURITY` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const SECURITY: Self = Self(c::AF_SECURITY as _); - /// `AF_KEY` - #[cfg(not(any( - bsd, - windows, - target_os = "haiku", - )))] - pub const KEY: Self = Self(c::AF_KEY as _); - /// `AF_PACKET` - #[cfg(not(any( - bsd, - windows, - target_os = "haiku", - )))] - pub const PACKET: Self = Self(c::AF_PACKET as _); - /// `AF_ASH` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const ASH: Self = Self(c::AF_ASH as _); - /// `AF_ECONET` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const ECONET: Self = Self(c::AF_ECONET as _); - /// `AF_ATMSVC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); - /// `AF_RDS` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const RDS: Self = Self(c::AF_RDS as _); - /// `AF_SNA` - #[cfg(not(target_os = "haiku"))] - pub const SNA: Self = Self(c::AF_SNA as _); - /// `AF_IRDA` - #[cfg(not(any( - bsd, - solarish, - target_os = "haiku", - )))] - pub const IRDA: Self = Self(c::AF_IRDA as _); - /// `AF_PPPOX` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const PPPOX: Self = Self(c::AF_PPPOX as _); - /// `AF_WANPIPE` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); - /// `AF_LLC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const LLC: Self = Self(c::AF_LLC as _); - /// `AF_CAN` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const CAN: Self = Self(c::AF_CAN as _); - /// `AF_TIPC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const TIPC: Self = Self(c::AF_TIPC as _); - /// `AF_BLUETOOTH` - #[cfg(not(any(apple, solarish, windows)))] - pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); - /// `AF_IUCV` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const IUCV: Self = Self(c::AF_IUCV as _); - /// `AF_RXRPC` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const RXRPC: Self = Self(c::AF_RXRPC as _); - /// `AF_ISDN` - #[cfg(not(any(solarish, windows, target_os = "haiku")))] - pub const ISDN: Self = Self(c::AF_ISDN as _); - /// `AF_PHONET` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const PHONET: Self = Self(c::AF_PHONET as _); - /// `AF_IEEE802154` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const IEEE802154: Self = Self(c::AF_IEEE802154 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. -#[doc(hidden)] -pub type RawProtocol = i32; - -/// `IPPROTO_*` constants for use with [`socket`] and [`socket_with`]. -/// -/// [`socket`]: crate::net::socket -/// [`socket_with`]: crate::net::socket_with -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct Protocol(pub(crate) RawProtocol); - -#[rustfmt::skip] -impl Protocol { - /// `IPPROTO_IP` - pub const IP: Self = Self(c::IPPROTO_IP as _); - /// `IPPROTO_ICMP` - pub const ICMP: Self = Self(c::IPPROTO_ICMP as _); - /// `IPPROTO_IGMP` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const IGMP: Self = Self(c::IPPROTO_IGMP as _); - /// `IPPROTO_IPIP` - #[cfg(not(any(solarish, windows, target_os = "haiku")))] - pub const IPIP: Self = Self(c::IPPROTO_IPIP as _); - /// `IPPROTO_TCP` - pub const TCP: Self = Self(c::IPPROTO_TCP as _); - /// `IPPROTO_EGP` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const EGP: Self = Self(c::IPPROTO_EGP as _); - /// `IPPROTO_PUP` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const PUP: Self = Self(c::IPPROTO_PUP as _); - /// `IPPROTO_UDP` - pub const UDP: Self = Self(c::IPPROTO_UDP as _); - /// `IPPROTO_IDP` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const IDP: Self = Self(c::IPPROTO_IDP as _); - /// `IPPROTO_TP` - #[cfg(not(any(solarish, windows, target_os = "haiku")))] - pub const TP: Self = Self(c::IPPROTO_TP as _); - /// `IPPROTO_DCCP` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "dragonfly", - target_os = "haiku", - target_os = "openbsd", - )))] - pub const DCCP: Self = Self(c::IPPROTO_DCCP as _); - /// `IPPROTO_IPV6` - pub const IPV6: Self = Self(c::IPPROTO_IPV6 as _); - /// `IPPROTO_RSVP` - #[cfg(not(any(solarish, windows, target_os = "haiku")))] - pub const RSVP: Self = Self(c::IPPROTO_RSVP as _); - /// `IPPROTO_GRE` - #[cfg(not(any(solarish, windows, target_os = "haiku")))] - pub const GRE: Self = Self(c::IPPROTO_GRE as _); - /// `IPPROTO_ESP` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const ESP: Self = Self(c::IPPROTO_ESP as _); - /// `IPPROTO_AH` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const AH: Self = Self(c::IPPROTO_AH as _); - /// `IPPROTO_MTP` - #[cfg(not(any( - solarish, - netbsdlike, - windows, - target_os = "haiku", - )))] - pub const MTP: Self = Self(c::IPPROTO_MTP as _); - /// `IPPROTO_BEETPH` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const BEETPH: Self = Self(c::IPPROTO_BEETPH as _); - /// `IPPROTO_ENCAP` - #[cfg(not(any(solarish, windows, target_os = "haiku")))] - pub const ENCAP: Self = Self(c::IPPROTO_ENCAP as _); - /// `IPPROTO_PIM` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const PIM: Self = Self(c::IPPROTO_PIM as _); - /// `IPPROTO_COMP` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "haiku", - )))] - pub const COMP: Self = Self(c::IPPROTO_COMP as _); - /// `IPPROTO_SCTP` - #[cfg(not(any(solarish, target_os = "dragonfly", target_os = "haiku", target_os = "openbsd")))] - pub const SCTP: Self = Self(c::IPPROTO_SCTP as _); - /// `IPPROTO_UDPLITE` - #[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "dragonfly", - target_os = "haiku", - )))] - pub const UDPLITE: Self = Self(c::IPPROTO_UDPLITE as _); - /// `IPPROTO_MPLS` - #[cfg(not(any( - apple, - solarish, - windows, - target_os = "dragonfly", - target_os = "haiku", - target_os = "netbsd", - )))] - pub const MPLS: Self = Self(c::IPPROTO_MPLS as _); - /// `IPPROTO_RAW` - pub const RAW: Self = Self(c::IPPROTO_RAW as _); - /// `IPPROTO_MPTCP` - #[cfg(not(any( - bsd, - solarish, - windows, - target_os = "android", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "haiku", - )))] - pub const MPTCP: Self = Self(c::IPPROTO_MPTCP as _); - /// `IPPROTO_FRAGMENT` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const FRAGMENT: Self = Self(c::IPPROTO_FRAGMENT as _); - /// `IPPROTO_ICMPV6` - pub const ICMPV6: Self = Self(c::IPPROTO_ICMPV6 as _); - /// `IPPROTO_MH` - #[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "dragonfly", - target_os = "haiku", - )))] - pub const MH: Self = Self(c::IPPROTO_MH as _); - /// `IPPROTO_ROUTING` - #[cfg(not(any(solarish, target_os = "haiku")))] - pub const ROUTING: Self = Self(c::IPPROTO_ROUTING as _); - - /// 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(i32)] -pub enum Shutdown { - /// `SHUT_RD`—Disable further read operations. - Read = c::SHUT_RD, - /// `SHUT_WR`—Disable further write operations. - Write = c::SHUT_WR, - /// `SHUT_RDWR`—Disable further read and write operations. - ReadWrite = c::SHUT_RDWR, -} - -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 - pub struct SocketFlags: c::c_int { - /// `SOCK_NONBLOCK` - #[cfg(not(any(apple, windows, target_os = "haiku")))] - const NONBLOCK = c::SOCK_NONBLOCK; - - /// `SOCK_CLOEXEC` - #[cfg(not(any(apple, windows, target_os = "haiku")))] - const CLOEXEC = c::SOCK_CLOEXEC; - } -} - -/// Timeout identifier for use with [`set_socket_timeout`] and -/// [`get_socket_timeout`]. -/// -/// [`set_socket_timeout`]: crate::net::sockopt::set_socket_timeout. -/// [`get_socket_timeout`]: crate::net::sockopt::get_socket_timeout. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum Timeout { - /// `SO_RCVTIMEO`—Timeout for receiving. - Recv = c::SO_RCVTIMEO, - - /// `SO_SNDTIMEO`—Timeout for sending. - Send = c::SO_SNDTIMEO, -} diff --git a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs index f8ab62966..efb5a4e14 100644 --- a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs +++ b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs @@ -1,11 +1,11 @@ //! The BSD sockets API requires us to read the `ss_family` field before //! we can interpret the rest of a `sockaddr` produced by the kernel. -use super::super::c; use super::addr::SocketAddrStorage; #[cfg(unix)] use super::addr::SocketAddrUnix; use super::ext::{in6_addr_new, in_addr_new, sockaddr_in6_new}; +use crate::backend::c; use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; use core::mem::size_of; diff --git a/vendor/rustix/src/backend/libc/offset.rs b/vendor/rustix/src/backend/libc/offset.rs deleted file mode 100644 index d7a803415..000000000 --- a/vendor/rustix/src/backend/libc/offset.rs +++ /dev/null @@ -1,410 +0,0 @@ -//! Automatically enable “large file” support features. - -#[cfg(not(windows))] -use super::c; - -#[cfg(not(any(linux_like, windows)))] -#[cfg(feature = "fs")] -pub(super) use c::{ - fstat as libc_fstat, fstatat as libc_fstatat, ftruncate as libc_ftruncate, ino_t as libc_ino_t, - lseek as libc_lseek, off_t as libc_off_t, -}; - -#[cfg(linux_like)] -#[cfg(feature = "fs")] -pub(super) use c::{ - fstat64 as libc_fstat, fstatat64 as libc_fstatat, ftruncate64 as libc_ftruncate, - ino64_t as libc_ino_t, lseek64 as libc_lseek, off64_t as libc_off_t, -}; - -#[cfg(linux_like)] -pub(super) use c::rlimit64 as libc_rlimit; - -#[cfg(not(any(linux_like, windows, target_os = "wasi")))] -#[cfg(feature = "mm")] -pub(super) use c::mmap as libc_mmap; - -#[cfg(not(any( - linux_like, - windows, - target_os = "fuchsia", - target_os = "redox", - target_os = "wasi", -)))] -pub(super) use c::{rlimit as libc_rlimit, RLIM_INFINITY as LIBC_RLIM_INFINITY}; - -#[cfg(not(any(linux_like, windows, target_os = "fuchsia", target_os = "wasi")))] -pub(super) use c::{getrlimit as libc_getrlimit, setrlimit as libc_setrlimit}; - -#[cfg(linux_like)] -pub(super) use c::{ - getrlimit64 as libc_getrlimit, setrlimit64 as libc_setrlimit, - RLIM64_INFINITY as LIBC_RLIM_INFINITY, -}; - -#[cfg(linux_like)] -#[cfg(feature = "mm")] -pub(super) use c::mmap64 as libc_mmap; - -// `prlimit64` wasn't supported in glibc until 2.13. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -weak_or_syscall! { - fn prlimit64( - pid: c::pid_t, - resource: c::__rlimit_resource_t, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64 - ) via SYS_prlimit64 -> c::c_int -} -#[cfg(all(target_os = "linux", target_env = "musl"))] -weak_or_syscall! { - fn prlimit64( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64 - ) via SYS_prlimit64 -> c::c_int -} -#[cfg(target_os = "android")] -weak_or_syscall! { - fn prlimit64( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64 - ) via SYS_prlimit64 -> c::c_int -} -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(super) unsafe fn libc_prlimit( - pid: c::pid_t, - resource: c::__rlimit_resource_t, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64, -) -> c::c_int { - prlimit64(pid, resource, new_limit, old_limit) -} -#[cfg(all(target_os = "linux", target_env = "musl"))] -pub(super) unsafe fn libc_prlimit( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64, -) -> c::c_int { - prlimit64(pid, resource, new_limit, old_limit) -} -#[cfg(target_os = "android")] -pub(super) unsafe fn libc_prlimit( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64, -) -> c::c_int { - prlimit64(pid, resource, new_limit, old_limit) -} - -#[cfg(not(any(linux_like, windows, target_os = "redox")))] -#[cfg(feature = "fs")] -pub(super) use c::openat as libc_openat; -#[cfg(linux_like)] -#[cfg(feature = "fs")] -pub(super) use c::openat64 as libc_openat; - -#[cfg(target_os = "fuchsia")] -#[cfg(feature = "fs")] -pub(super) use c::fallocate as libc_fallocate; -#[cfg(any(target_os = "android", target_os = "linux"))] -#[cfg(feature = "fs")] -pub(super) use c::fallocate64 as libc_fallocate; -#[cfg(not(any( - apple, - linux_like, - netbsdlike, - solarish, - windows, - target_os = "dragonfly", - target_os = "haiku", - target_os = "redox", -)))] -#[cfg(feature = "fs")] -pub(super) use c::posix_fadvise as libc_posix_fadvise; -#[cfg(linux_like)] -#[cfg(feature = "fs")] -pub(super) use c::posix_fadvise64 as libc_posix_fadvise; - -#[cfg(all(not(any( - windows, - target_os = "android", - target_os = "linux", - target_os = "emscripten", -))))] -pub(super) use c::{pread as libc_pread, pwrite as libc_pwrite}; -#[cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten"))] -pub(super) use c::{pread64 as libc_pread, pwrite64 as libc_pwrite}; -#[cfg(not(any( - apple, - windows, - target_os = "android", - target_os = "emscripten", - target_os = "haiku", - target_os = "linux", - target_os = "redox", - target_os = "solaris", -)))] -pub(super) use c::{preadv as libc_preadv, pwritev as libc_pwritev}; -#[cfg(any(target_os = "linux", target_os = "emscripten"))] -pub(super) use c::{preadv64 as libc_preadv, pwritev64 as libc_pwritev}; - -#[cfg(target_os = "android")] -mod readwrite_pv64 { - use super::c; - - // 64-bit offsets on 32-bit platforms are passed in endianness-specific - // lo/hi pairs. See src/backend/linux_raw/conv.rs for details. - #[cfg(all(target_endian = "little", target_pointer_width = "32"))] - fn lo(x: u64) -> usize { - (x >> 32) as usize - } - #[cfg(all(target_endian = "little", target_pointer_width = "32"))] - fn hi(x: u64) -> usize { - (x & 0xffff_ffff) as usize - } - #[cfg(all(target_endian = "big", target_pointer_width = "32"))] - fn lo(x: u64) -> usize { - (x & 0xffff_ffff) as usize - } - #[cfg(all(target_endian = "big", target_pointer_width = "32"))] - fn hi(x: u64) -> usize { - (x >> 32) as usize - } - - pub(in super::super) unsafe fn preadv64( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off64_t, - ) -> c::ssize_t { - // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to - // test for it, and call back to `c::syscall`. We don't use - // `weak_or_syscall` here because we need to pass the 64-bit offset - // specially. - weak! { - fn preadv64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t - } - if let Some(fun) = preadv64.get() { - fun(fd, iov, iovcnt, offset) - } else { - #[cfg(target_pointer_width = "32")] - { - c::syscall( - c::SYS_preadv, - fd, - iov, - iovcnt, - hi(offset as u64), - lo(offset as u64), - ) as c::ssize_t - } - #[cfg(target_pointer_width = "64")] - { - c::syscall(c::SYS_preadv, fd, iov, iovcnt, offset) as c::ssize_t - } - } - } - pub(in super::super) unsafe fn pwritev64( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off64_t, - ) -> c::ssize_t { - // See the comments in `preadv64`. - weak! { - fn pwritev64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t - } - if let Some(fun) = pwritev64.get() { - fun(fd, iov, iovcnt, offset) - } else { - #[cfg(target_pointer_width = "32")] - { - c::syscall( - c::SYS_pwritev, - fd, - iov, - iovcnt, - hi(offset as u64), - lo(offset as u64), - ) as c::ssize_t - } - #[cfg(target_pointer_width = "64")] - { - c::syscall(c::SYS_pwritev, fd, iov, iovcnt, offset) as c::ssize_t - } - } - } -} -#[cfg(target_os = "android")] -pub(super) use readwrite_pv64::{preadv64 as libc_preadv, pwritev64 as libc_pwritev}; - -// macOS added preadv and pwritev in version 11.0 -#[cfg(apple)] -mod readwrite_pv { - use super::c; - - weakcall! { - pub(in super::super) fn preadv( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off_t - ) -> c::ssize_t - } - weakcall! { - pub(in super::super) fn pwritev( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, offset: c::off_t - ) -> c::ssize_t - } -} -#[cfg(apple)] -pub(super) use readwrite_pv::{preadv as libc_preadv, pwritev as libc_pwritev}; - -// glibc added `preadv64v2` and `pwritev64v2` in version 2.26. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -mod readwrite_pv64v2 { - use super::c; - - // 64-bit offsets on 32-bit platforms are passed in endianness-specific - // lo/hi pairs. See src/backend/linux_raw/conv.rs for details. - #[cfg(all(target_endian = "little", target_pointer_width = "32"))] - fn lo(x: u64) -> usize { - (x >> 32) as usize - } - #[cfg(all(target_endian = "little", target_pointer_width = "32"))] - fn hi(x: u64) -> usize { - (x & 0xffff_ffff) as usize - } - #[cfg(all(target_endian = "big", target_pointer_width = "32"))] - fn lo(x: u64) -> usize { - (x & 0xffff_ffff) as usize - } - #[cfg(all(target_endian = "big", target_pointer_width = "32"))] - fn hi(x: u64) -> usize { - (x >> 32) as usize - } - - pub(in super::super) unsafe fn preadv64v2( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off64_t, - flags: c::c_int, - ) -> c::ssize_t { - // Older glibc lacks `preadv64v2`, so use the `weak!` mechanism to - // test for it, and call back to `c::syscall`. We don't use - // `weak_or_syscall` here because we need to pass the 64-bit offset - // specially. - weak! { - fn preadv64v2(c::c_int, *const c::iovec, c::c_int, c::off64_t, c::c_int) -> c::ssize_t - } - if let Some(fun) = preadv64v2.get() { - fun(fd, iov, iovcnt, offset, flags) - } else { - #[cfg(target_pointer_width = "32")] - { - c::syscall( - c::SYS_preadv, - fd, - iov, - iovcnt, - hi(offset as u64), - lo(offset as u64), - flags, - ) as c::ssize_t - } - #[cfg(target_pointer_width = "64")] - { - c::syscall(c::SYS_preadv2, fd, iov, iovcnt, offset, flags) as c::ssize_t - } - } - } - pub(in super::super) unsafe fn pwritev64v2( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off64_t, - flags: c::c_int, - ) -> c::ssize_t { - // See the comments in `preadv64v2`. - weak! { - fn pwritev64v2(c::c_int, *const c::iovec, c::c_int, c::off64_t, c::c_int) -> c::ssize_t - } - if let Some(fun) = pwritev64v2.get() { - fun(fd, iov, iovcnt, offset, flags) - } else { - #[cfg(target_pointer_width = "32")] - { - c::syscall( - c::SYS_pwritev, - fd, - iov, - iovcnt, - hi(offset as u64), - lo(offset as u64), - flags, - ) as c::ssize_t - } - #[cfg(target_pointer_width = "64")] - { - c::syscall(c::SYS_pwritev2, fd, iov, iovcnt, offset, flags) as c::ssize_t - } - } - } -} -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(super) use readwrite_pv64v2::{preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2}; - -#[cfg(not(any( - apple, - netbsdlike, - solarish, - windows, - target_os = "aix", - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", - target_os = "l4re", - target_os = "redox", -)))] -#[cfg(feature = "fs")] -pub(super) use c::posix_fallocate as libc_posix_fallocate; -#[cfg(target_os = "l4re")] -#[cfg(feature = "fs")] -pub(super) use c::posix_fallocate64 as libc_posix_fallocate; -#[cfg(not(any( - linux_like, - solarish, - windows, - target_os = "haiku", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[cfg(feature = "fs")] -pub(super) use {c::fstatfs as libc_fstatfs, c::statfs as libc_statfs}; -#[cfg(not(any( - linux_like, - windows, - target_os = "haiku", - target_os = "redox", - target_os = "wasi", -)))] -#[cfg(feature = "fs")] -pub(super) use {c::fstatvfs as libc_fstatvfs, c::statvfs as libc_statvfs}; - -#[cfg(linux_like)] -#[cfg(feature = "fs")] -pub(super) use { - c::fstatfs64 as libc_fstatfs, c::fstatvfs64 as libc_fstatvfs, c::statfs64 as libc_statfs, - c::statvfs64 as libc_statvfs, -}; diff --git a/vendor/rustix/src/backend/libc/param/auxv.rs b/vendor/rustix/src/backend/libc/param/auxv.rs index a770c60d8..0eeb972cc 100644 --- a/vendor/rustix/src/backend/libc/param/auxv.rs +++ b/vendor/rustix/src/backend/libc/param/auxv.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; #[cfg(any( all(target_os = "android", target_pointer_width = "64"), target_os = "linux", diff --git a/vendor/rustix/src/backend/libc/pid/mod.rs b/vendor/rustix/src/backend/libc/pid/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/libc/pid/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/pid/syscalls.rs b/vendor/rustix/src/backend/libc/pid/syscalls.rs new file mode 100644 index 000000000..d0ed4bc9f --- /dev/null +++ b/vendor/rustix/src/backend/libc/pid/syscalls.rs @@ -0,0 +1,14 @@ +//! 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 new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/libc/pipe/mod.rs @@ -0,0 +1,2 @@ +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 new file mode 100644 index 000000000..c5ded9174 --- /dev/null +++ b/vendor/rustix/src/backend/libc/pipe/syscalls.rs @@ -0,0 +1,111 @@ +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 = "haiku", 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::optional_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 = "haiku", 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 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 = optional_as_mut_ptr(off_in).cast(); + let off_out = optional_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 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 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_sz(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_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?; + + unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)) } +} diff --git a/vendor/rustix/src/backend/libc/pipe/types.rs b/vendor/rustix/src/backend/libc/pipe/types.rs new file mode 100644 index 000000000..f48d8041b --- /dev/null +++ b/vendor/rustix/src/backend/libc/pipe/types.rs @@ -0,0 +1,93 @@ +#[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::io::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 = "haiku", + target_os = "openbsd", + target_os = "redox", + )))] + const DIRECT = bitcast!(c::O_DIRECT); + /// `O_NONBLOCK` + const NONBLOCK = bitcast!(c::O_NONBLOCK); + } +} + +#[cfg(linux_kernel)] +bitflags! { + /// `SPLICE_F_*` constants for use with [`splice`], [`vmsplice`], + /// and [`tee`]. + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct SpliceFlags: c::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; + } +} + +/// A buffer type used 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. +#[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 as *mut 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() as *mut c::c_void, + iov_len: buf.len() as _, + }, + _lifetime: PhantomData, + } + } +} + +#[cfg(not(any(apple, target_os = "wasi")))] +#[test] +fn test_types() { + use core::mem::size_of; + assert_eq!(size_of::<PipeFlags>(), size_of::<c::c_int>()); + + #[cfg(linux_kernel)] + assert_eq!(size_of::<SpliceFlags>(), size_of::<c::c_int>()); +} diff --git a/vendor/rustix/src/backend/libc/prctl/mod.rs b/vendor/rustix/src/backend/libc/prctl/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/libc/prctl/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/prctl/syscalls.rs b/vendor/rustix/src/backend/libc/prctl/syscalls.rs new file mode 100644 index 000000000..451cecc29 --- /dev/null +++ b/vendor/rustix/src/backend/libc/prctl/syscalls.rs @@ -0,0 +1,14 @@ +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/cpu_set.rs b/vendor/rustix/src/backend/libc/process/cpu_set.rs index a9d6d89c2..4cf06b96a 100644 --- a/vendor/rustix/src/backend/libc/process/cpu_set.rs +++ b/vendor/rustix/src/backend/libc/process/cpu_set.rs @@ -2,8 +2,8 @@ #![allow(non_snake_case)] -use super::super::c; use super::types::{RawCpuSet, CPU_SETSIZE}; +use crate::backend::c; #[inline] pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { @@ -43,9 +43,8 @@ pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { unsafe { c::CPU_ISSET(cpu, cpuset) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { - use core::convert::TryInto; unsafe { c::CPU_COUNT(cpuset).try_into().unwrap() } } diff --git a/vendor/rustix/src/backend/libc/process/mod.rs b/vendor/rustix/src/backend/libc/process/mod.rs index 8675c1af9..24f43d443 100644 --- a/vendor/rustix/src/backend/libc/process/mod.rs +++ b/vendor/rustix/src/backend/libc/process/mod.rs @@ -1,9 +1,4 @@ -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] pub(crate) mod cpu_set; #[cfg(not(windows))] pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs index d8f4fe3a4..0aa29b0b1 100644 --- a/vendor/rustix/src/backend/libc/process/syscalls.rs +++ b/vendor/rustix/src/backend/libc/process/syscalls.rs @@ -1,52 +1,43 @@ //! libc syscalls supporting `rustix::process`. -use super::super::c; -#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] -use super::super::conv::borrowed_fd; -use super::super::conv::{c_str, ret, ret_c_int, ret_discarded_char_ptr}; -#[cfg(not(target_os = "wasi"))] -use super::super::conv::{ret_infallible, ret_pid_t, ret_usize}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::{syscall_ret, syscall_ret_u32}; -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] use super::types::RawCpuSet; -#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +use crate::backend::c; +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +use crate::backend::conv::ret_infallible; +#[cfg(linux_kernel)] +use crate::backend::conv::ret_u32; +#[cfg(not(target_os = "wasi"))] +use crate::backend::conv::{borrowed_fd, ret_pid_t, ret_usize}; +#[cfg(feature = "fs")] +use crate::backend::conv::{c_str, ret_discarded_char_ptr}; +use crate::backend::conv::{ret, ret_c_int}; +#[cfg(not(target_os = "wasi"))] use crate::fd::BorrowedFd; #[cfg(target_os = "linux")] -use crate::fd::{AsRawFd, OwnedFd}; +use crate::fd::{AsRawFd, OwnedFd, RawFd}; +#[cfg(feature = "fs")] use crate::ffi::CStr; #[cfg(feature = "fs")] use crate::fs::Mode; use crate::io; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::process::Sysinfo; -#[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +use crate::process::Uid; +#[cfg(linux_kernel)] +use crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}; +#[cfg(not(target_os = "wasi"))] +use crate::process::{Gid, Pid, RawPid, Signal, WaitOptions, WaitStatus}; +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +use crate::process::{Resource, Rlimit}; +#[cfg(not(any(target_os = "redox", target_os = "openbsd", target_os = "wasi")))] use crate::process::{WaitId, WaitidOptions, WaitidStatus}; use core::mem::MaybeUninit; #[cfg(target_os = "linux")] -use {super::super::conv::syscall_ret_owned_fd, crate::process::PidfdFlags}; -#[cfg(any(target_os = "android", target_os = "linux"))] use { - super::super::offset::libc_prlimit, - crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}, -}; -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -use { - super::super::offset::{libc_getrlimit, libc_rlimit, libc_setrlimit, LIBC_RLIM_INFINITY}, - crate::process::{Resource, Rlimit}, -}; -#[cfg(not(target_os = "wasi"))] -use { - super::types::RawUname, - crate::process::{Gid, Pid, RawNonZeroPid, RawPid, Signal, Uid, WaitOptions, WaitStatus}, - core::convert::TryInto, + 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))) } @@ -57,17 +48,29 @@ 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(feature = "fs")] #[cfg(not(target_os = "wasi"))] -pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result<()> { +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(any(target_os = "android", target_os = "linux"))] +// 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`. @@ -75,79 +78,36 @@ pub(crate) fn membarrier_query() -> MembarrierQuery { // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES const MEMBARRIER_CMD_QUERY: u32 = 0; unsafe { - match syscall_ret_u32(c::syscall(c::SYS_membarrier, MEMBARRIER_CMD_QUERY, 0)) { - Ok(query) => MembarrierQuery::from_bits_unchecked(query), + match ret_u32(membarrier_all(MEMBARRIER_CMD_QUERY as i32, 0)) { + Ok(query) => MembarrierQuery::from_bits_retain(query), Err(_) => MembarrierQuery::empty(), } } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { syscall_ret(c::syscall(c::SYS_membarrier, cmd as u32, 0)) } + unsafe { ret(membarrier_all(cmd as i32, 0)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; - unsafe { - syscall_ret(c::syscall( - c::SYS_membarrier, - cmd as u32, - MEMBARRIER_CMD_FLAG_CPU, - cpu.as_raw(), - )) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getuid() -> Uid { - unsafe { - let uid = c::getuid(); - Uid::from_raw(uid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn geteuid() -> Uid { - unsafe { - let uid = c::geteuid(); - Uid::from_raw(uid) - } -} -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getgid() -> Gid { - unsafe { - let gid = c::getgid(); - Gid::from_raw(gid) + syscall! { + fn membarrier_cpu( + cmd: c::c_int, + flags: c::c_uint, + cpu_id: c::c_int + ) via SYS_membarrier -> c::c_int } -} -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getegid() -> Gid { unsafe { - let gid = c::getegid(); - Gid::from_raw(gid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getpid() -> Pid { - unsafe { - let pid = c::getpid(); - debug_assert_ne!(pid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)) + ret(membarrier_cpu( + cmd as i32, + MEMBARRIER_CMD_FLAG_CPU, + bitcast!(cpu.as_raw()), + )) } } @@ -166,8 +126,7 @@ pub(crate) fn getppid() -> Option<Pid> { pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { unsafe { let pgid = ret_pid_t(c::getpgid(Pid::as_raw(pid) as _))?; - debug_assert_ne!(pgid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid))) + Ok(Pid::from_raw_unchecked(pgid)) } } @@ -183,17 +142,11 @@ pub(crate) fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { pub(crate) fn getpgrp() -> Pid { unsafe { let pgid = c::getpgrp(); - debug_assert_ne!(pgid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid)) + Pid::from_raw_unchecked(pgid) } } -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] #[inline] pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { unsafe { @@ -205,12 +158,7 @@ pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io: } } -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] #[inline] pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> { unsafe { @@ -230,21 +178,10 @@ pub(crate) fn sched_yield() { } #[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::<RawUname>::uninit(); - unsafe { - ret_infallible(c::uname(uname.as_mut_ptr())); - uname.assume_init() - } -} - -#[cfg(not(target_os = "wasi"))] #[cfg(feature = "fs")] #[inline] pub(crate) fn umask(mask: Mode) -> Mode { - // TODO: Use `from_bits_retain` when we switch to bitflags 2.0. - unsafe { Mode::from_bits_truncate(c::umask(mask.bits() as _) as _) } + unsafe { Mode::from_bits_retain(c::umask(mask.bits() as c::mode_t).into()) } } #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] @@ -259,7 +196,7 @@ pub(crate) fn nice(inc: i32) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[inline] pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -271,7 +208,7 @@ pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[inline] pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -283,7 +220,7 @@ pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[inline] pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { libc_errno::set_errno(libc_errno::Errno(0)); @@ -295,13 +232,13 @@ pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { } } -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", 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 = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[inline] pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { unsafe { @@ -313,7 +250,7 @@ pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<( } } -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[inline] pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { unsafe { @@ -328,9 +265,9 @@ pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] #[inline] pub(crate) fn getrlimit(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::<libc_rlimit>::uninit(); + let mut result = MaybeUninit::<c::rlimit>::uninit(); unsafe { - ret_infallible(libc_getrlimit(limit as _, result.as_mut_ptr())); + ret_infallible(c::getrlimit(limit as _, result.as_mut_ptr())); rlimit_from_libc(result.assume_init()) } } @@ -339,16 +276,16 @@ pub(crate) fn getrlimit(limit: Resource) -> Rlimit { #[inline] pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { let lim = rlimit_to_libc(new)?; - unsafe { ret(libc_setrlimit(limit as _, &lim)) } + unsafe { ret(c::setrlimit(limit as _, &lim)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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::<libc_rlimit>::uninit(); + let mut result = MaybeUninit::<c::rlimit>::uninit(); unsafe { - ret(libc_prlimit( + ret(c::prlimit( Pid::as_raw(pid), limit as _, &lim, @@ -358,15 +295,15 @@ pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Res } } -/// Convert a Rust [`Rlimit`] to a C `libc_rlimit`. +/// Convert a Rust [`Rlimit`] to a C `c::rlimit`. #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -fn rlimit_from_libc(lim: libc_rlimit) -> Rlimit { - let current = if lim.rlim_cur == LIBC_RLIM_INFINITY { +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 == LIBC_RLIM_INFINITY { + let maximum = if lim.rlim_max == c::RLIM_INFINITY { None } else { Some(lim.rlim_max.try_into().unwrap()) @@ -374,19 +311,19 @@ fn rlimit_from_libc(lim: libc_rlimit) -> Rlimit { Rlimit { current, maximum } } -/// Convert a C `libc_rlimit` to a Rust `Rlimit`. +/// Convert a C `c::rlimit` to a Rust `Rlimit`. #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -fn rlimit_to_libc(lim: Rlimit) -> io::Result<libc_rlimit> { +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 => LIBC_RLIM_INFINITY as _, + None => c::RLIM_INFINITY as _, }; let rlim_max = match maximum { Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => LIBC_RLIM_INFINITY as _, + None => c::RLIM_INFINITY as _, }; - Ok(libc_rlimit { rlim_cur, rlim_max }) + Ok(c::rlimit { rlim_cur, rlim_max }) } #[cfg(not(target_os = "wasi"))] @@ -413,12 +350,7 @@ pub(crate) fn _waitpid( unsafe { let mut status: c::c_int = 0; let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?; - Ok(RawNonZeroPid::new(pid).map(|non_zero| { - ( - Pid::from_raw_nonzero(non_zero), - WaitStatus::new(status as _), - ) - })) + Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status as _)))) } } @@ -503,8 +435,8 @@ unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidS // `si_pid` is supposedly the better way to check that the struct has been // filled, e.g. the Linux manpage 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 + // 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 { @@ -514,27 +446,12 @@ unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidS } } -#[inline] -pub(crate) fn exit_group(code: c::c_int) -> ! { - // `_exit` and `_Exit` are the same; it's just a matter of which ones - // the libc bindings expose. - #[cfg(any(target_os = "wasi", target_os = "solid"))] - unsafe { - c::_Exit(code) - } - #[cfg(unix)] - unsafe { - c::_exit(code) - } -} - #[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 _))?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + Ok(Pid::from_raw_unchecked(pid)) } } @@ -543,8 +460,7 @@ pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> { pub(crate) fn setsid() -> io::Result<Pid> { unsafe { let pid = ret_c_int(c::setsid())?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + Ok(Pid::from_raw_unchecked(pid)) } } @@ -589,18 +505,6 @@ pub(crate) fn test_kill_current_process_group() -> io::Result<()> { unsafe { ret(c::kill(0, 0)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] -#[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)) -} - #[cfg(freebsdlike)] #[inline] pub(crate) unsafe fn procctl( @@ -614,11 +518,38 @@ pub(crate) unsafe fn procctl( #[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 { - syscall_ret_owned_fd(c::syscall( - c::SYS_pidfd_open, + ret_owned_fd(pidfd_open( pid.as_raw_nonzero().get(), - flags.bits(), + bitflags_bits!(flags), + )) + } +} + +#[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), )) } } @@ -630,21 +561,8 @@ pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> { unsafe { ret_usize(c::getgroups(len, buf.as_mut_ptr().cast()) as isize) } } -#[cfg(any(target_os = "android", target_os = "linux"))] -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 = "redox", 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 = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn ioctl_tiocsctty(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCSCTTY as _, &0_u32)) } } diff --git a/vendor/rustix/src/backend/libc/process/types.rs b/vendor/rustix/src/backend/libc/process/types.rs index e7f10dbff..980c0effe 100644 --- a/vendor/rustix/src/backend/libc/process/types.rs +++ b/vendor/rustix/src/backend/libc/process/types.rs @@ -1,8 +1,4 @@ -use super::super::c; - -/// `sysinfo` -#[cfg(any(target_os = "android", target_os = "linux"))] -pub type Sysinfo = c::sysinfo; +use crate::backend::c; /// A command for use with [`membarrier`] and [`membarrier_cpu`]. /// @@ -11,7 +7,7 @@ pub type Sysinfo = c::sysinfo; /// [`membarrier`]: crate::process::membarrier /// [`membarrier_cpu`]: crate::process::membarrier_cpu /// [`membarrier_query`]: crate::process::membarrier_query -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[derive(Copy, Clone, Eq, PartialEq, Debug)] #[repr(u32)] pub enum MembarrierCommand { @@ -46,48 +42,48 @@ pub enum MembarrierCommand { /// [`prlimit`]: crate::process::prlimit #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] #[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] +#[repr(u32)] pub enum Resource { /// `RLIMIT_CPU` - Cpu = c::RLIMIT_CPU as c::c_int, + Cpu = bitcast!(c::RLIMIT_CPU), /// `RLIMIT_FSIZE` - Fsize = c::RLIMIT_FSIZE as c::c_int, + Fsize = bitcast!(c::RLIMIT_FSIZE), /// `RLIMIT_DATA` - Data = c::RLIMIT_DATA as c::c_int, + Data = bitcast!(c::RLIMIT_DATA), /// `RLIMIT_STACK` - Stack = c::RLIMIT_STACK as c::c_int, + Stack = bitcast!(c::RLIMIT_STACK), /// `RLIMIT_CORE` #[cfg(not(target_os = "haiku"))] - Core = c::RLIMIT_CORE as c::c_int, + Core = bitcast!(c::RLIMIT_CORE), /// `RLIMIT_RSS` #[cfg(not(any(apple, solarish, target_os = "haiku")))] - Rss = c::RLIMIT_RSS as c::c_int, + Rss = bitcast!(c::RLIMIT_RSS), /// `RLIMIT_NPROC` #[cfg(not(any(solarish, target_os = "haiku")))] - Nproc = c::RLIMIT_NPROC as c::c_int, + Nproc = bitcast!(c::RLIMIT_NPROC), /// `RLIMIT_NOFILE` - Nofile = c::RLIMIT_NOFILE as c::c_int, + Nofile = bitcast!(c::RLIMIT_NOFILE), /// `RLIMIT_MEMLOCK` #[cfg(not(any(solarish, target_os = "aix", target_os = "haiku")))] - Memlock = c::RLIMIT_MEMLOCK as c::c_int, + Memlock = bitcast!(c::RLIMIT_MEMLOCK), /// `RLIMIT_AS` #[cfg(not(target_os = "openbsd"))] - As = c::RLIMIT_AS as c::c_int, + As = bitcast!(c::RLIMIT_AS), /// `RLIMIT_LOCKS` #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - Locks = c::RLIMIT_LOCKS as c::c_int, + Locks = bitcast!(c::RLIMIT_LOCKS), /// `RLIMIT_SIGPENDING` #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - Sigpending = c::RLIMIT_SIGPENDING as c::c_int, + Sigpending = bitcast!(c::RLIMIT_SIGPENDING), /// `RLIMIT_MSGQUEUE` #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - Msgqueue = c::RLIMIT_MSGQUEUE as c::c_int, + Msgqueue = bitcast!(c::RLIMIT_MSGQUEUE), /// `RLIMIT_NICE` #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - Nice = c::RLIMIT_NICE as c::c_int, + Nice = bitcast!(c::RLIMIT_NICE), /// `RLIMIT_RTPRIO` #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] - Rtprio = c::RLIMIT_RTPRIO as c::c_int, + Rtprio = bitcast!(c::RLIMIT_RTPRIO), /// `RLIMIT_RTTIME` #[cfg(not(any( bsd, @@ -97,7 +93,7 @@ pub enum Resource { target_os = "emscripten", target_os = "haiku", )))] - Rttime = c::RLIMIT_RTTIME as c::c_int, + Rttime = bitcast!(c::RLIMIT_RTTIME), } #[cfg(apple)] @@ -107,224 +103,21 @@ impl Resource { pub const Rss: Self = Self::As; } -/// A signal number for use with [`kill_process`], [`kill_process_group`], -/// and [`kill_current_process_group`]. -/// -/// [`kill_process`]: crate::process::kill_process -/// [`kill_process_group`]: crate::process::kill_process_group -/// [`kill_current_process_group`]: crate::process::kill_current_process_group -#[cfg(not(target_os = "wasi"))] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum Signal { - /// `SIGHUP` - Hup = c::SIGHUP, - /// `SIGINT` - Int = c::SIGINT, - /// `SIGQUIT` - Quit = c::SIGQUIT, - /// `SIGILL` - Ill = c::SIGILL, - /// `SIGTRAP` - Trap = c::SIGTRAP, - /// `SIGABRT`, aka `SIGIOT` - #[doc(alias = "Iot")] - #[doc(alias = "Abrt")] - Abort = c::SIGABRT, - /// `SIGBUS` - Bus = c::SIGBUS, - /// `SIGFPE` - Fpe = c::SIGFPE, - /// `SIGKILL` - Kill = c::SIGKILL, - /// `SIGUSR1` - Usr1 = c::SIGUSR1, - /// `SIGSEGV` - Segv = c::SIGSEGV, - /// `SIGUSR2` - Usr2 = c::SIGUSR2, - /// `SIGPIPE` - Pipe = c::SIGPIPE, - /// `SIGALRM` - #[doc(alias = "Alrm")] - Alarm = c::SIGALRM, - /// `SIGTERM` - Term = c::SIGTERM, - /// `SIGSTKFLT` - #[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - all( - any(target_os = "android", target_os = "linux"), - any( - target_arch = "mips", - target_arch = "mips64", - target_arch = "sparc", - target_arch = "sparc64" - ), - ) - )))] - Stkflt = c::SIGSTKFLT, - /// `SIGCHLD` - #[doc(alias = "Chld")] - Child = c::SIGCHLD, - /// `SIGCONT` - Cont = c::SIGCONT, - /// `SIGSTOP` - Stop = c::SIGSTOP, - /// `SIGTSTP` - Tstp = c::SIGTSTP, - /// `SIGTTIN` - Ttin = c::SIGTTIN, - /// `SIGTTOU` - Ttou = c::SIGTTOU, - /// `SIGURG` - Urg = c::SIGURG, - /// `SIGXCPU` - Xcpu = c::SIGXCPU, - /// `SIGXFSZ` - Xfsz = c::SIGXFSZ, - /// `SIGVTALRM` - #[doc(alias = "Vtalrm")] - Vtalarm = c::SIGVTALRM, - /// `SIGPROF` - Prof = c::SIGPROF, - /// `SIGWINCH` - Winch = c::SIGWINCH, - /// `SIGIO`, aka `SIGPOLL` - #[doc(alias = "Poll")] - #[cfg(not(target_os = "haiku"))] - Io = c::SIGIO, - /// `SIGPWR` - #[cfg(not(any(bsd, target_os = "haiku")))] - #[doc(alias = "Pwr")] - Power = c::SIGPWR, - /// `SIGSYS`, aka `SIGUNUSED` - #[doc(alias = "Unused")] - Sys = c::SIGSYS, - /// `SIGEMT` - #[cfg(bsd)] - Emt = c::SIGEMT, - /// `SIGINFO` - #[cfg(bsd)] - Info = c::SIGINFO, - /// `SIGTHR` - #[cfg(target_os = "freebsd")] - #[doc(alias = "Lwp")] - Thr = c::SIGTHR, - /// `SIGLIBRT` - #[cfg(target_os = "freebsd")] - Librt = c::SIGLIBRT, -} - -#[cfg(not(target_os = "wasi"))] -impl Signal { - /// Convert a raw signal number into a `Signal`, if possible. - pub fn from_raw(sig: i32) -> Option<Self> { - match sig as _ { - 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), - c::SIGUSR1 => Some(Self::Usr1), - c::SIGSEGV => Some(Self::Segv), - 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 = "haiku", - all( - any(target_os = "android", target_os = "linux"), - any( - target_arch = "mips", - target_arch = "mips64", - target_arch = "sparc", - target_arch = "sparc64" - ), - ) - )))] - c::SIGSTKFLT => Some(Self::Stkflt), - c::SIGCHLD => Some(Self::Child), - c::SIGCONT => Some(Self::Cont), - c::SIGSTOP => Some(Self::Stop), - c::SIGTSTP => Some(Self::Tstp), - c::SIGTTIN => Some(Self::Ttin), - c::SIGTTOU => Some(Self::Ttou), - c::SIGURG => Some(Self::Urg), - c::SIGXCPU => Some(Self::Xcpu), - c::SIGXFSZ => Some(Self::Xfsz), - c::SIGVTALRM => Some(Self::Vtalarm), - c::SIGPROF => Some(Self::Prof), - c::SIGWINCH => Some(Self::Winch), - #[cfg(not(target_os = "haiku"))] - c::SIGIO => Some(Self::Io), - #[cfg(not(any(bsd, target_os = "haiku")))] - c::SIGPWR => Some(Self::Power), - c::SIGSYS => Some(Self::Sys), - #[cfg(bsd)] - 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, - } - } -} - pub const EXIT_SUCCESS: c::c_int = c::EXIT_SUCCESS; pub const EXIT_FAILURE: c::c_int = c::EXIT_FAILURE; #[cfg(not(target_os = "wasi"))] pub const EXIT_SIGNALED_SIGABRT: c::c_int = 128 + c::SIGABRT; -/// A process identifier as a raw integer. -#[cfg(not(target_os = "wasi"))] -pub type RawPid = c::pid_t; -/// A non-zero process identifier as a raw non-zero integer. -#[cfg(not(target_os = "wasi"))] -pub type RawNonZeroPid = core::num::NonZeroI32; -/// A group identifier as a raw integer. -#[cfg(not(target_os = "wasi"))] -pub type RawGid = c::gid_t; -/// A user identifier as a raw integer. -#[cfg(not(target_os = "wasi"))] -pub type RawUid = c::uid_t; /// A CPU identifier as a raw integer. -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub type RawCpuid = u32; -#[cfg(target_os = "freebsd")] +#[cfg(freebsdlike)] pub type RawId = c::id_t; -#[cfg(not(target_os = "wasi"))] -pub(crate) type RawUname = c::utsname; - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] pub(crate) type RawCpuSet = c::cpu_set_t; -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] +#[cfg(any(linux_kernel, target_os = "dragonfly", target_os = "fuchsia"))] #[inline] pub(crate) fn raw_cpu_set_new() -> RawCpuSet { let mut set = unsafe { core::mem::zeroed() }; @@ -332,7 +125,7 @@ pub(crate) fn raw_cpu_set_new() -> RawCpuSet { set } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; #[cfg(target_os = "dragonfly")] pub(crate) const CPU_SETSIZE: usize = 256; diff --git a/vendor/rustix/src/backend/libc/process/wait.rs b/vendor/rustix/src/backend/libc/process/wait.rs index c09ee1002..9a932cfab 100644 --- a/vendor/rustix/src/backend/libc/process/wait.rs +++ b/vendor/rustix/src/backend/libc/process/wait.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; pub(crate) use c::{ WCONTINUED, WEXITSTATUS, WIFCONTINUED, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, diff --git a/vendor/rustix/src/backend/libc/pty/mod.rs b/vendor/rustix/src/backend/libc/pty/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/libc/pty/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/pty/syscalls.rs b/vendor/rustix/src/backend/libc/pty/syscalls.rs new file mode 100644 index 000000000..178201ead --- /dev/null +++ b/vendor/rustix/src/backend/libc/pty/syscalls.rs @@ -0,0 +1,86 @@ +//! libc syscalls supporting `rustix::pty`. + +use crate::backend::c; +use crate::backend::conv::{borrowed_fd, ret}; +use crate::fd::BorrowedFd; +use crate::io; +#[cfg(not(target_os = "android"))] +use {crate::backend::conv::ret_owned_fd, crate::fd::OwnedFd, crate::pty::OpenptFlags}; +#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] +use { + crate::ffi::{CStr, CString}, + crate::path::SMALL_PATH_BUFFER_SIZE, + alloc::borrow::ToOwned, + alloc::vec::Vec, +}; + +#[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(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))] +#[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(target_os = "freebsd", linux_like, target_os = "fuchsia"))] + let r = unsafe { c::ptsname_r(borrowed_fd(fd), buffer.as_mut_ptr().cast(), buffer.len()) }; + + // 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 u64, &mut name) { + 0 => { + let len = CStr::from_ptr(name.as_ptr().cast()).to_bytes().len(); + std::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)); + } + + buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially + 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))) } +} + +#[cfg(target_os = "linux")] +#[inline] +pub(crate) fn ioctl_tiocgptpeer(fd: BorrowedFd, flags: OpenptFlags) -> io::Result<OwnedFd> { + unsafe { ret_owned_fd(c::ioctl(borrowed_fd(fd), c::TIOCGPTPEER, flags.bits())) } +} diff --git a/vendor/rustix/src/backend/libc/rand/syscalls.rs b/vendor/rustix/src/backend/libc/rand/syscalls.rs index 2dcff139e..8a995f2e6 100644 --- a/vendor/rustix/src/backend/libc/rand/syscalls.rs +++ b/vendor/rustix/src/backend/libc/rand/syscalls.rs @@ -1,9 +1,9 @@ //! libc syscalls supporting `rustix::rand`. -#[cfg(any(target_os = "android", target_os = "linux"))] -use {super::super::c, super::super::conv::ret_usize, crate::io, crate::rand::GetRandomFlags}; +#[cfg(linux_kernel)] +use {crate::backend::c, crate::backend::conv::ret_usize, crate::io, crate::rand::GetRandomFlags}; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] pub(crate) fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result<usize> { // `getrandom` wasn't supported in glibc until 2.25. weak_or_syscall! { diff --git a/vendor/rustix/src/backend/libc/rand/types.rs b/vendor/rustix/src/backend/libc/rand/types.rs index e12bd9cbd..730cf3a34 100644 --- a/vendor/rustix/src/backend/libc/rand/types.rs +++ b/vendor/rustix/src/backend/libc/rand/types.rs @@ -1,13 +1,15 @@ -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::c; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] +use crate::backend::c; +#[cfg(linux_kernel)] use bitflags::bitflags; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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; diff --git a/vendor/rustix/src/backend/libc/system/mod.rs b/vendor/rustix/src/backend/libc/system/mod.rs new file mode 100644 index 000000000..bff7fd564 --- /dev/null +++ b/vendor/rustix/src/backend/libc/system/mod.rs @@ -0,0 +1,3 @@ +#[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 new file mode 100644 index 000000000..a731e9302 --- /dev/null +++ b/vendor/rustix/src/backend/libc/system/syscalls.rs @@ -0,0 +1,40 @@ +//! 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(linux_kernel)] +use crate::system::Sysinfo; +use core::mem::MaybeUninit; +#[cfg(not(any(target_os = "emscripten", target_os = "redox", 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 { + ret_infallible(c::uname(uname.as_mut_ptr())); + 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 = "redox", 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)?, + )) + } +} diff --git a/vendor/rustix/src/backend/libc/system/types.rs b/vendor/rustix/src/backend/libc/system/types.rs new file mode 100644 index 000000000..731e89bed --- /dev/null +++ b/vendor/rustix/src/backend/libc/system/types.rs @@ -0,0 +1,8 @@ +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 index c82c95958..ef944f04d 100644 --- a/vendor/rustix/src/backend/libc/termios/mod.rs +++ b/vendor/rustix/src/backend/libc/termios/mod.rs @@ -1,3 +1 @@ pub(crate) mod syscalls; -#[cfg(not(target_os = "wasi"))] -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/termios/syscalls.rs b/vendor/rustix/src/backend/libc/termios/syscalls.rs index dba73c960..d4182f4fe 100644 --- a/vendor/rustix/src/backend/libc/termios/syscalls.rs +++ b/vendor/rustix/src/backend/libc/termios/syscalls.rs @@ -4,46 +4,62 @@ //! //! See the `rustix::backend::syscalls` module documentation for details. -use super::super::c; -use super::super::conv::{borrowed_fd, ret, ret_pid_t}; +use crate::backend::c; +use crate::backend::conv::{borrowed_fd, ret, ret_pid_t}; use crate::fd::BorrowedFd; #[cfg(feature = "procfs")] #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] use crate::ffi::CStr; -#[cfg(not(target_os = "wasi"))] -use crate::io; -#[cfg(not(target_os = "wasi"))] -use crate::process::{Pid, RawNonZeroPid}; -#[cfg(not(target_os = "wasi"))] -use crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize}; use core::mem::MaybeUninit; +#[cfg(not(target_os = "wasi"))] +use { + crate::io, + crate::pid::Pid, + crate::termios::{Action, OptionalActions, QueueSelector, Termios, Winsize}, + crate::utils::as_mut_ptr, +}; #[cfg(not(target_os = "wasi"))] pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { - let mut result = MaybeUninit::<Termios>::uninit(); + // If we have `TCGETS2`, use it, so that we fill in the `c_ispeed` and + // `c_ospeed` fields. + #[cfg(linux_kernel)] unsafe { - ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr()))?; - Ok(result.assume_init()) + use crate::termios::{ControlModes, InputModes, LocalModes, OutputModes, SpecialCodes}; + use core::mem::zeroed; + + let mut termios2 = MaybeUninit::<c::termios2>::uninit(); + + ret(c::ioctl( + borrowed_fd(fd), + c::TCGETS2.into(), + termios2.as_mut_ptr(), + ))?; + + let termios2 = 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(zeroed()), + input_speed: termios2.c_ispeed, + output_speed: termios2.c_ospeed, + }; + result.special_codes.0[..termios2.c_cc.len()].copy_from_slice(&termios2.c_cc); + + Ok(result) } -} -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "x32", - target_arch = "riscv64", - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips64", - ) -))] -pub(crate) fn tcgetattr2(fd: BorrowedFd<'_>) -> io::Result<crate::termios::Termios2> { - let mut result = MaybeUninit::<crate::termios::Termios2>::uninit(); + #[cfg(not(linux_kernel))] unsafe { - ret(c::ioctl(borrowed_fd(fd), c::TCGETS2, result.as_mut_ptr()))?; + let mut result = MaybeUninit::<Termios>::uninit(); + + ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr().cast()))?; + Ok(result.assume_init()) } } @@ -52,8 +68,7 @@ pub(crate) fn tcgetattr2(fd: BorrowedFd<'_>) -> io::Result<crate::termios::Termi pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { unsafe { let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + Ok(Pid::from_raw_unchecked(pid)) } } @@ -68,38 +83,65 @@ pub(crate) fn tcsetattr( optional_actions: OptionalActions, termios: &Termios, ) -> io::Result<()> { + // If we have `TCSETS2`, use it, so that we use the `c_ispeed` and + // `c_ospeed` fields. + #[cfg(linux_kernel)] unsafe { - ret(c::tcsetattr( - borrowed_fd(fd), - optional_actions as _, - termios, - )) + use crate::termios::speed; + use core::mem::zeroed; + use linux_raw_sys::general::{termios2, BOTHER, CBAUD, IBSHIFT}; + + #[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] + use linux_raw_sys::ioctl::{TCSETS, TCSETS2}; + + // linux-raw-sys' ioctl-generation script for sparc isn't working yet, + // so as a temporary workaround, declare these manually. + #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] + const TCSETS: u32 = 0x80245409; + #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] + const TCSETS2: u32 = 0x802c540d; + + // Translate from `optional_actions` into an ioctl request code. On MIPS, + // `optional_actions` already has `TCGETS` added to it. + let request = TCSETS2 + + if cfg!(any(target_arch = "mips", target_arch = "mips64")) { + optional_actions as u32 - TCSETS + } else { + optional_actions as u32 + }; + + let input_speed = termios.input_speed(); + let output_speed = termios.output_speed(); + let mut termios2 = 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: zeroed(), + c_ispeed: input_speed, + 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 &= !CBAUD; + termios2.c_cflag |= speed::encode(output_speed).unwrap_or(BOTHER); + termios2.c_cflag &= !(CBAUD << IBSHIFT); + termios2.c_cflag |= speed::encode(input_speed).unwrap_or(BOTHER) << IBSHIFT; + let nccs = termios2.c_cc.len(); + termios2 + .c_cc + .copy_from_slice(&termios.special_codes.0[..nccs]); + + ret(c::ioctl(borrowed_fd(fd), request as _, &termios2)) } -} -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "x32", - target_arch = "riscv64", - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips64", - ) -))] -pub(crate) fn tcsetattr2( - fd: BorrowedFd, - optional_actions: OptionalActions, - termios: &crate::termios::Termios2, -) -> io::Result<()> { + #[cfg(not(linux_kernel))] unsafe { - ret(c::ioctl( + ret(c::tcsetattr( borrowed_fd(fd), - (c::TCSETS2 as u32 + optional_actions as u32) as _, - termios, + optional_actions as _, + crate::utils::as_ptr(termios).cast(), )) } } @@ -128,8 +170,7 @@ pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result<Pid> { unsafe { let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + Ok(Pid::from_raw_unchecked(pid)) } } @@ -151,42 +192,142 @@ pub(crate) fn tcgetwinsize(fd: BorrowedFd) -> io::Result<Winsize> { } } -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn cfgetospeed(termios: &Termios) -> Speed { - unsafe { c::cfgetospeed(termios) } +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] +pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCEXCL as _)) } } -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn cfgetispeed(termios: &Termios) -> Speed { - unsafe { c::cfgetispeed(termios) } +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] +pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCNXCL as _)) } } #[cfg(not(target_os = "wasi"))] #[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - unsafe { c::cfmakeraw(termios) } +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(target_os = "wasi"))] #[inline] -pub(crate) fn cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - unsafe { ret(c::cfsetospeed(termios, speed)) } +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(target_os = "wasi"))] #[inline] -pub(crate) fn cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - unsafe { ret(c::cfsetispeed(termios, speed)) } +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(target_os = "wasi"))] #[inline] -pub(crate) fn cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - unsafe { ret(c::cfsetspeed(termios, speed)) } +pub(crate) fn cfmakeraw(termios: &mut Termios) { + unsafe { c::cfmakeraw(as_mut_ptr(termios).cast()) } } pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { @@ -200,7 +341,7 @@ pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { #[cfg(feature = "procfs")] #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> { +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()) { 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 fdb7fc644..000000000 --- a/vendor/rustix/src/backend/libc/termios/types.rs +++ /dev/null @@ -1,736 +0,0 @@ -use super::super::c; - -/// `TCSA*` values for use with [`tcsetattr`]. -/// -/// [`tcsetattr`]: crate::termios::tcsetattr -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum OptionalActions { - /// `TCSANOW`—Make the change immediately. - #[doc(alias = "TCSANOW")] - Now = c::TCSANOW, - - /// `TCSADRAIN`—Make the change after all output has been transmitted. - #[doc(alias = "TCSADRAIN")] - Drain = c::TCSADRAIN, - - /// `TCSAFLUSH`—Discard any pending input and then make the change - /// after all output has been transmitted. - #[doc(alias = "TCSAFLUSH")] - Flush = c::TCSAFLUSH, -} - -/// `TC*` values for use with [`tcflush`]. -/// -/// [`tcflush`]: crate::termios::tcflush -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum QueueSelector { - /// `TCIFLUSH`—Flush data received but not read. - #[doc(alias = "TCIFLUSH")] - IFlush = c::TCIFLUSH, - - /// `TCOFLUSH`—Flush data written but not transmitted. - #[doc(alias = "TCOFLUSH")] - OFlush = c::TCOFLUSH, - - /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. - #[doc(alias = "TCIOFLUSH")] - IOFlush = c::TCIOFLUSH, -} - -/// `TC*` values for use with [`tcflow`]. -/// -/// [`tcflow`]: crate::termios::tcflow -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum Action { - /// `TCOOFF`—Suspend output. - #[doc(alias = "TCOOFF")] - OOff = c::TCOOFF, - - /// `TCOON`—Restart suspended output. - #[doc(alias = "TCOON")] - OOn = c::TCOON, - - /// `TCIOFF`—Transmits a STOP byte. - #[doc(alias = "TCIOFF")] - IOff = c::TCIOFF, - - /// `TCION`—Transmits a START byte. - #[doc(alias = "TCION")] - IOn = c::TCION, -} - -/// `struct termios` for use with [`tcgetattr`] and [`tcsetattr`]. -/// -/// [`tcgetattr`]: crate::termios::tcgetattr -/// [`tcsetattr`]: crate::termios::tcsetattr -#[doc(alias = "termios")] -pub type Termios = c::termios; - -/// `struct termios2` for use with [`tcgetattr2`] and [`tcsetattr2`]. -/// -/// [`tcgetattr2`]: crate::termios::tcgetattr2 -/// [`tcsetattr2`]: crate::termios::tcsetattr2 -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "x32", - target_arch = "riscv64", - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips64", - ) -))] -#[doc(alias = "termios2")] -pub type Termios2 = c::termios2; - -/// `struct winsize` for use with [`tcgetwinsize`]. -/// -/// [`tcgetwinsize`]: crate::termios::tcgetwinsize -#[doc(alias = "winsize")] -pub type Winsize = c::winsize; - -/// `tcflag_t`—A type for the flags fields of [`Termios`]. -#[doc(alias = "tcflag_t")] -pub type Tcflag = c::tcflag_t; - -/// `speed_t`—A return type for [`cfsetspeed`] and similar. -/// -/// [`cfsetspeed`]: crate::termios::cfsetspeed -#[doc(alias = "speed_t")] -pub type Speed = c::speed_t; - -/// `VINTR` -pub const VINTR: usize = c::VINTR as usize; - -/// `VQUIT` -pub const VQUIT: usize = c::VQUIT as usize; - -/// `VERASE` -pub const VERASE: usize = c::VERASE as usize; - -/// `VKILL` -pub const VKILL: usize = c::VKILL as usize; - -/// `VEOF` -pub const VEOF: usize = c::VEOF as usize; - -/// `VTIME` -pub const VTIME: usize = c::VTIME as usize; - -/// `VMIN` -pub const VMIN: usize = c::VMIN as usize; - -/// `VSWTC` -#[cfg(not(any( - apple, - solarish, - target_os = "aix", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "haiku", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const VSWTC: usize = c::VSWTC as usize; - -/// `VSTART` -pub const VSTART: usize = c::VSTART as usize; - -/// `VSTOP` -pub const VSTOP: usize = c::VSTOP as usize; - -/// `VSUSP` -pub const VSUSP: usize = c::VSUSP as usize; - -/// `VEOL` -pub const VEOL: usize = c::VEOL as usize; - -/// `VREPRINT` -#[cfg(not(target_os = "haiku"))] -pub const VREPRINT: usize = c::VREPRINT as usize; - -/// `VDISCARD` -#[cfg(not(any(target_os = "aix", target_os = "haiku")))] -pub const VDISCARD: usize = c::VDISCARD as usize; - -/// `VWERASE` -#[cfg(not(any(target_os = "aix", target_os = "haiku")))] -pub const VWERASE: usize = c::VWERASE as usize; - -/// `VLNEXT` -#[cfg(not(target_os = "haiku"))] -pub const VLNEXT: usize = c::VLNEXT as usize; - -/// `VEOL2` -pub const VEOL2: usize = c::VEOL2 as usize; - -/// `IGNBRK` -pub const IGNBRK: Tcflag = c::IGNBRK; - -/// `BRKINT` -pub const BRKINT: Tcflag = c::BRKINT; - -/// `IGNPAR` -pub const IGNPAR: Tcflag = c::IGNPAR; - -/// `PARMRK` -pub const PARMRK: Tcflag = c::PARMRK; - -/// `INPCK` -pub const INPCK: Tcflag = c::INPCK; - -/// `ISTRIP` -pub const ISTRIP: Tcflag = c::ISTRIP; - -/// `INLCR` -pub const INLCR: Tcflag = c::INLCR; - -/// `IGNCR` -pub const IGNCR: Tcflag = c::IGNCR; - -/// `ICRNL` -pub const ICRNL: Tcflag = c::ICRNL; - -/// `IUCLC` -#[cfg(any(solarish, target_os = "haiku"))] -pub const IUCLC: Tcflag = c::IUCLC; - -/// `IXON` -pub const IXON: Tcflag = c::IXON; - -/// `IXANY` -#[cfg(not(target_os = "redox"))] -pub const IXANY: Tcflag = c::IXANY; - -/// `IXOFF` -pub const IXOFF: Tcflag = c::IXOFF; - -/// `IMAXBEL` -#[cfg(not(any(target_os = "haiku", target_os = "redox")))] -pub const IMAXBEL: Tcflag = c::IMAXBEL; - -/// `IUTF8` -#[cfg(not(any( - solarish, - target_os = "aix", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "haiku", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const IUTF8: Tcflag = c::IUTF8; - -/// `OPOST` -pub const OPOST: Tcflag = c::OPOST; - -/// `OLCUC` -#[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "redox", -)))] -pub const OLCUC: Tcflag = c::OLCUC; - -/// `ONLCR` -pub const ONLCR: Tcflag = c::ONLCR; - -/// `OCRNL` -pub const OCRNL: Tcflag = c::OCRNL; - -/// `ONOCR` -pub const ONOCR: Tcflag = c::ONOCR; - -/// `ONLRET` -pub const ONLRET: Tcflag = c::ONLRET; - -/// `OFILL` -#[cfg(not(bsd))] -pub const OFILL: Tcflag = c::OFILL; - -/// `OFDEL` -#[cfg(not(bsd))] -pub const OFDEL: Tcflag = c::OFDEL; - -/// `NLDLY` -#[cfg(not(any(bsd, solarish, target_os = "redox")))] -pub const NLDLY: Tcflag = c::NLDLY; - -/// `NL0` -#[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] -pub const NL0: Tcflag = c::NL0; - -/// `NL1` -#[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] -pub const NL1: Tcflag = c::NL1; - -/// `CRDLY` -#[cfg(not(any(bsd, solarish, target_os = "redox")))] -pub const CRDLY: Tcflag = c::CRDLY; - -/// `CR0` -#[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] -pub const CR0: Tcflag = c::CR0; - -/// `CR1` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const CR1: Tcflag = c::CR1; - -/// `CR2` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const CR2: Tcflag = c::CR2; - -/// `CR3` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const CR3: Tcflag = c::CR3; - -/// `TABDLY` -#[cfg(not(any(netbsdlike, solarish, target_os = "dragonfly", target_os = "redox",)))] -pub const TABDLY: Tcflag = c::TABDLY; - -/// `TAB0` -#[cfg(not(any( - netbsdlike, - solarish, - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const TAB0: Tcflag = c::TAB0; - -/// `TAB1` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const TAB1: Tcflag = c::TAB1; - -/// `TAB2` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const TAB2: Tcflag = c::TAB2; - -/// `TAB3` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const TAB3: Tcflag = c::TAB3; - -/// `BSDLY` -#[cfg(not(any(bsd, solarish, target_os = "redox")))] -pub const BSDLY: Tcflag = c::BSDLY; - -/// `BS0` -#[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] -pub const BS0: Tcflag = c::BS0; - -/// `BS1` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const BS1: Tcflag = c::BS1; - -/// `FFDLY` -#[cfg(not(any(target_env = "musl", bsd, solarish, target_os = "redox")))] -pub const FFDLY: Tcflag = c::FFDLY; - -/// `FF0` -#[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] -pub const FF0: Tcflag = c::FF0; - -/// `FF1` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const FF1: Tcflag = c::FF1; - -/// `VTDLY` -#[cfg(not(any(target_env = "musl", bsd, solarish, target_os = "redox")))] -pub const VTDLY: Tcflag = c::VTDLY; - -/// `VT0` -#[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))] -pub const VT0: Tcflag = c::VT0; - -/// `VT1` -#[cfg(not(any( - target_env = "musl", - bsd, - solarish, - target_os = "emscripten", - target_os = "fuchsia", - target_os = "redox", -)))] -pub const VT1: Tcflag = c::VT1; - -/// `B0` -pub const B0: Speed = c::B0; - -/// `B50` -pub const B50: Speed = c::B50; - -/// `B75` -pub const B75: Speed = c::B75; - -/// `B110` -pub const B110: Speed = c::B110; - -/// `B134` -pub const B134: Speed = c::B134; - -/// `B150` -pub const B150: Speed = c::B150; - -/// `B200` -pub const B200: Speed = c::B200; - -/// `B300` -pub const B300: Speed = c::B300; - -/// `B600` -pub const B600: Speed = c::B600; - -/// `B1200` -pub const B1200: Speed = c::B1200; - -/// `B1800` -pub const B1800: Speed = c::B1800; - -/// `B2400` -pub const B2400: Speed = c::B2400; - -/// `B4800` -pub const B4800: Speed = c::B4800; - -/// `B9600` -pub const B9600: Speed = c::B9600; - -/// `B19200` -pub const B19200: Speed = c::B19200; - -/// `B38400` -pub const B38400: Speed = c::B38400; - -/// `B57600` -#[cfg(not(target_os = "aix"))] -pub const B57600: Speed = c::B57600; - -/// `B115200` -#[cfg(not(target_os = "aix"))] -pub const B115200: Speed = c::B115200; - -/// `B230400` -#[cfg(not(target_os = "aix"))] -pub const B230400: Speed = c::B230400; - -/// `B460800` -#[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "openbsd" -)))] -pub const B460800: Speed = c::B460800; - -/// `B500000` -#[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] -pub const B500000: Speed = c::B500000; - -/// `B576000` -#[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))] -pub const B576000: Speed = c::B576000; - -/// `B921600` -#[cfg(not(any( - apple, - target_os = "aix", - target_os = "dragonfly", - target_os = "haiku", - target_os = "openbsd" -)))] -pub const B921600: Speed = c::B921600; - -/// `B1000000` -#[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] -pub const B1000000: Speed = c::B1000000; - -/// `B1152000` -#[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] -pub const B1152000: Speed = c::B1152000; - -/// `B1500000` -#[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] -pub const B1500000: Speed = c::B1500000; - -/// `B2000000` -#[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))] -pub const B2000000: Speed = c::B2000000; - -/// `B2500000` -#[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", -)))] -pub const B2500000: Speed = c::B2500000; - -/// `B3000000` -#[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", -)))] -pub const B3000000: Speed = c::B3000000; - -/// `B3500000` -#[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", -)))] -pub const B3500000: Speed = c::B3500000; - -/// `B4000000` -#[cfg(not(any( - target_arch = "sparc", - target_arch = "sparc64", - bsd, - target_os = "aix", - target_os = "haiku", - target_os = "solaris", -)))] -pub const B4000000: Speed = c::B4000000; - -/// `BOTHER` -#[cfg(any(target_os = "android", target_os = "linux"))] -pub const BOTHER: Speed = c::BOTHER; - -/// `CSIZE` -pub const CSIZE: Tcflag = c::CSIZE; - -/// `CS5` -pub const CS5: Tcflag = c::CS5; - -/// `CS6` -pub const CS6: Tcflag = c::CS6; - -/// `CS7` -pub const CS7: Tcflag = c::CS7; - -/// `CS8` -pub const CS8: Tcflag = c::CS8; - -/// `CSTOPB` -pub const CSTOPB: Tcflag = c::CSTOPB; - -/// `CREAD` -pub const CREAD: Tcflag = c::CREAD; - -/// `PARENB` -pub const PARENB: Tcflag = c::PARENB; - -/// `PARODD` -pub const PARODD: Tcflag = c::PARODD; - -/// `HUPCL` -pub const HUPCL: Tcflag = c::HUPCL; - -/// `CLOCAL` -pub const CLOCAL: Tcflag = c::CLOCAL; - -/// `ISIG` -pub const ISIG: Tcflag = c::ISIG; - -/// `ICANON`—A flag for the `c_lflag` field of [`Termios`] indicating -/// canonical mode. -pub const ICANON: Tcflag = c::ICANON; - -/// `ECHO` -pub const ECHO: Tcflag = c::ECHO; - -/// `ECHOE` -pub const ECHOE: Tcflag = c::ECHOE; - -/// `ECHOK` -pub const ECHOK: Tcflag = c::ECHOK; - -/// `ECHONL` -pub const ECHONL: Tcflag = c::ECHONL; - -/// `NOFLSH` -pub const NOFLSH: Tcflag = c::NOFLSH; - -/// `TOSTOP` -pub const TOSTOP: Tcflag = c::TOSTOP; - -/// `IEXTEN` -pub const IEXTEN: Tcflag = c::IEXTEN; - -/// `EXTA` -#[cfg(not(any( - solarish, - target_os = "emscripten", - target_os = "haiku", - target_os = "redox", -)))] -pub const EXTA: Speed = c::EXTA; - -/// `EXTB` -#[cfg(not(any( - solarish, - target_os = "emscripten", - target_os = "haiku", - target_os = "redox", -)))] -pub const EXTB: Speed = c::EXTB; - -/// `CBAUD` -#[cfg(not(any(bsd, target_os = "haiku", target_os = "redox")))] -pub const CBAUD: Tcflag = c::CBAUD; - -/// `CBAUDEX` -#[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "redox", -)))] -pub const CBAUDEX: Tcflag = c::CBAUDEX; - -/// `CIBAUD` -#[cfg(not(any( - target_arch = "powerpc", - target_arch = "powerpc64", - bsd, - target_os = "emscripten", - target_os = "haiku", - target_os = "redox", -)))] -pub const CIBAUD: Tcflag = c::CIBAUD; - -/// `CIBAUD` -// glibc on powerpc lacks a definition for `CIBAUD`, even though the Linux -// headers and Musl on powerpc both have one. So define it manually. -#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] -pub const CIBAUD: Tcflag = 0o77600000; - -/// `CMSPAR` -#[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "emscripten", - target_os = "haiku", - target_os = "redox", -)))] -pub const CMSPAR: Tcflag = c::CMSPAR; - -/// `CRTSCTS` -#[cfg(not(any(target_os = "aix", target_os = "redox")))] -pub const CRTSCTS: Tcflag = c::CRTSCTS; - -/// `XCASE` -#[cfg(any(target_arch = "s390x", target_os = "haiku"))] -pub const XCASE: Tcflag = c::XCASE; - -/// `ECHOCTL` -#[cfg(not(any(target_os = "redox")))] -pub const ECHOCTL: Tcflag = c::ECHOCTL; - -/// `ECHOPRT` -#[cfg(not(any(target_os = "redox")))] -pub const ECHOPRT: Tcflag = c::ECHOPRT; - -/// `ECHOKE` -#[cfg(not(any(target_os = "redox")))] -pub const ECHOKE: Tcflag = c::ECHOKE; - -/// `FLUSHO` -#[cfg(not(any(target_os = "redox")))] -pub const FLUSHO: Tcflag = c::FLUSHO; - -/// `PENDIN` -#[cfg(not(any(target_os = "redox")))] -pub const PENDIN: Tcflag = c::PENDIN; - -/// `EXTPROC` -#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "redox")))] -pub const EXTPROC: Tcflag = c::EXTPROC; - -/// `XTABS` -#[cfg(not(any( - bsd, - solarish, - target_os = "aix", - target_os = "haiku", - target_os = "redox", -)))] -pub const XTABS: Tcflag = c::XTABS; diff --git a/vendor/rustix/src/backend/libc/thread/syscalls.rs b/vendor/rustix/src/backend/libc/thread/syscalls.rs index adf4bb700..6066fd0d4 100644 --- a/vendor/rustix/src/backend/libc/thread/syscalls.rs +++ b/vendor/rustix/src/backend/libc/thread/syscalls.rs @@ -1,18 +1,23 @@ //! libc syscalls supporting `rustix::thread`. -use super::super::c; -use super::super::conv::ret; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::{borrowed_fd, ret_c_int, syscall_ret}; -use super::super::time::types::LibcTimespec; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::fd::BorrowedFd; +use crate::backend::c; +use crate::backend::conv::ret; use crate::io; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::process::{Pid, RawNonZeroPid}; #[cfg(not(target_os = "redox"))] use crate::thread::{NanosleepRelativeResult, Timespec}; +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +use crate::timespec::LibcTimespec; use core::mem::MaybeUninit; +#[cfg(linux_kernel)] +use { + crate::backend::conv::{borrowed_fd, ret_c_int}, + crate::fd::BorrowedFd, + crate::pid::Pid, + crate::utils::as_mut_ptr, +}; #[cfg(not(any( apple, freebsdlike, @@ -47,16 +52,17 @@ weak!(fn __nanosleep64(*const LibcTimespec, *mut LibcTimespec) -> c::c_int); )))] #[inline] pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - let mut remain = MaybeUninit::<LibcTimespec>::uninit(); let flags = 0; - // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe by - // default. + // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe + // by default. #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", ))] unsafe { + let mut remain = MaybeUninit::<LibcTimespec>::uninit(); + if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { match libc_clock_nanosleep( id as c::clockid_t, @@ -81,6 +87,8 @@ pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> Nanos target_env = "gnu", )))] unsafe { + let mut remain = MaybeUninit::<Timespec>::uninit(); + match c::clock_nanosleep(id as c::clockid_t, flags, request, remain.as_mut_ptr()) { 0 => NanosleepRelativeResult::Ok, err if err == io::Errno::INTR.0 => { @@ -96,7 +104,6 @@ pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> Nanos target_env = "gnu", ))] unsafe fn clock_nanosleep_relative_old(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - use core::convert::TryInto; let tv_sec = match request.tv_sec.try_into() { Ok(tv_sec) => tv_sec, Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), @@ -142,8 +149,8 @@ unsafe fn clock_nanosleep_relative_old(id: ClockId, request: &Timespec) -> Nanos pub(crate) fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { let flags = c::TIMER_ABSTIME; - // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe by - // default. + // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe + // by default. #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -182,8 +189,6 @@ pub(crate) fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::R target_env = "gnu", ))] fn clock_nanosleep_absolute_old(id: ClockId, request: &Timespec) -> io::Result<()> { - use core::convert::TryInto; - let flags = c::TIMER_ABSTIME; let old_request = c::timespec { @@ -199,8 +204,6 @@ fn clock_nanosleep_absolute_old(id: ClockId, request: &Timespec) -> io::Result<( #[cfg(not(target_os = "redox"))] #[inline] pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { - let mut remain = MaybeUninit::<LibcTimespec>::uninit(); - // 32-bit gnu version: libc has `nanosleep` but it is not y2038 safe by // default. #[cfg(all( @@ -208,6 +211,8 @@ pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { target_env = "gnu", ))] unsafe { + let mut remain = MaybeUninit::<LibcTimespec>::uninit(); + if let Some(libc_nanosleep) = __nanosleep64.get() { match ret(libc_nanosleep(&request.clone().into(), remain.as_mut_ptr())) { Ok(()) => NanosleepRelativeResult::Ok, @@ -227,6 +232,8 @@ pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { target_env = "gnu", )))] unsafe { + let mut remain = MaybeUninit::<Timespec>::uninit(); + match ret(c::nanosleep(request, remain.as_mut_ptr())) { Ok(()) => NanosleepRelativeResult::Ok, Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(remain.assume_init()), @@ -240,7 +247,6 @@ pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { target_env = "gnu", ))] unsafe fn nanosleep_old(request: &Timespec) -> NanosleepRelativeResult { - use core::convert::TryInto; let tv_sec = match request.tv_sec.try_into() { Ok(tv_sec) => tv_sec, Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), @@ -266,7 +272,7 @@ unsafe fn nanosleep_old(request: &Timespec) -> NanosleepRelativeResult { } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] #[must_use] pub(crate) fn gettid() -> Pid { @@ -279,12 +285,11 @@ pub(crate) fn gettid() -> Pid { unsafe { let tid = gettid(); - debug_assert_ne!(tid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid)) + Pid::from_raw_unchecked(tid) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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, @@ -296,68 +301,104 @@ pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result<c::c_int> { unsafe { ret_c_int(setns(borrowed_fd(fd), nstype)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] pub(crate) fn unshare(flags: crate::thread::UnshareFlags) -> io::Result<()> { unsafe { ret(c::unshare(flags.bits() as i32)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[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<()> { - let header: *mut _ = header; - unsafe { syscall_ret(c::syscall(c::SYS_capget, header, data.as_mut_ptr())) } + 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(any(target_os = "android", target_os = "linux"))] +#[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<()> { - let header: *mut _ = header; - unsafe { syscall_ret(c::syscall(c::SYS_capset, header, data.as_ptr())) } + 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(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] -pub(crate) fn setuid_thread(uid: crate::process::Uid) -> io::Result<()> { - unsafe { syscall_ret(c::syscall(c::SYS_setuid, uid.as_raw())) } +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(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] pub(crate) fn setresuid_thread( - ruid: crate::process::Uid, - euid: crate::process::Uid, - suid: crate::process::Uid, + 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; - unsafe { syscall_ret(c::syscall(SYS, ruid.as_raw(), euid.as_raw(), suid.as_raw())) } + + 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(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] -pub(crate) fn setgid_thread(gid: crate::process::Gid) -> io::Result<()> { - unsafe { syscall_ret(c::syscall(c::SYS_setgid, gid.as_raw())) } +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(any(target_os = "android", target_os = "linux"))] +#[cfg(linux_kernel)] #[inline] pub(crate) fn setresgid_thread( - rgid: crate::process::Gid, - egid: crate::process::Gid, - sgid: crate::process::Gid, + 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; - unsafe { syscall_ret(c::syscall(SYS, rgid.as_raw(), egid.as_raw(), sgid.as_raw())) } + + 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())) } } diff --git a/vendor/rustix/src/backend/libc/time/syscalls.rs b/vendor/rustix/src/backend/libc/time/syscalls.rs index 9d341d886..14ca22b2d 100644 --- a/vendor/rustix/src/backend/libc/time/syscalls.rs +++ b/vendor/rustix/src/backend/libc/time/syscalls.rs @@ -1,20 +1,22 @@ //! libc syscalls supporting `rustix::time`. -use super::super::c; -use super::super::conv::ret; -#[cfg(feature = "time")] -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -use super::super::time::types::LibcItimerspec; -use super::super::time::types::LibcTimespec; -use super::types::Timespec; +use crate::backend::c; +use crate::backend::conv::ret; #[cfg(not(target_os = "wasi"))] -use super::types::{ClockId, DynamicClockId}; +use crate::clockid::{ClockId, DynamicClockId}; use crate::io; +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +use crate::timespec::LibcTimespec; +use crate::timespec::Timespec; use core::mem::MaybeUninit; -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(feature = "time")] use { - super::super::conv::{borrowed_fd, ret_owned_fd}, + crate::backend::conv::{borrowed_fd, ret_owned_fd}, + crate::backend::time::types::LibcItimerspec, crate::fd::{BorrowedFd, OwnedFd}, crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, }; @@ -51,8 +53,6 @@ weak!(fn __timerfd_settime64(c::c_int, c::c_int, *const LibcItimerspec, *mut Lib #[inline] #[must_use] pub(crate) fn clock_getres(id: ClockId) -> Timespec { - let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); - // 32-bit gnu version: libc has `clock_getres` but it is not y2038 safe by // default. #[cfg(all( @@ -60,6 +60,8 @@ pub(crate) fn clock_getres(id: ClockId) -> Timespec { target_env = "gnu", ))] unsafe { + let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); + if let Some(libc_clock_getres) = __clock_getres64.get() { ret(libc_clock_getres(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); timespec.assume_init().into() @@ -74,6 +76,7 @@ pub(crate) fn clock_getres(id: ClockId) -> Timespec { target_env = "gnu", )))] unsafe { + let mut timespec = MaybeUninit::<Timespec>::uninit(); let _ = c::clock_getres(id as c::clockid_t, timespec.as_mut_ptr()); timespec.assume_init() } @@ -102,13 +105,13 @@ unsafe fn clock_getres_old(id: ClockId) -> Timespec { #[inline] #[must_use] pub(crate) fn clock_gettime(id: ClockId) -> Timespec { - let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); - #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", ))] unsafe { + let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); + if let Some(libc_clock_gettime) = __clock_gettime64.get() { ret(libc_clock_gettime( id as c::clockid_t, @@ -130,6 +133,7 @@ pub(crate) fn clock_gettime(id: ClockId) -> Timespec { target_env = "gnu", )))] unsafe { + let mut timespec = MaybeUninit::<Timespec>::uninit(); ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); timespec.assume_init() } @@ -157,34 +161,33 @@ unsafe fn clock_gettime_old(id: ClockId) -> Timespec { #[cfg(not(target_os = "wasi"))] #[inline] pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timespec> { - let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); unsafe { let id: c::clockid_t = match id { DynamicClockId::Known(id) => id as c::clockid_t, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] DynamicClockId::Dynamic(fd) => { use crate::fd::AsRawFd; const CLOCKFD: i32 = 3; (!fd.as_raw_fd() << 3) | CLOCKFD } - #[cfg(not(any(target_os = "android", target_os = "linux")))] + #[cfg(not(linux_kernel))] DynamicClockId::Dynamic(_fd) => { // Dynamic clocks are not supported on this platform. return Err(io::Errno::INVAL); } - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] DynamicClockId::Tai => c::CLOCK_TAI, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(any(linux_kernel, target_os = "openbsd"))] DynamicClockId::Boottime => c::CLOCK_BOOTTIME, - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(linux_kernel)] DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM, }; @@ -193,6 +196,8 @@ pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timesp target_env = "gnu", ))] { + let mut timespec = MaybeUninit::<LibcTimespec>::uninit(); + if let Some(libc_clock_gettime) = __clock_gettime64.get() { ret(libc_clock_gettime( id as c::clockid_t, @@ -210,6 +215,8 @@ pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result<Timesp target_env = "gnu", )))] { + let mut timespec = MaybeUninit::<Timespec>::uninit(); + ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr()))?; Ok(timespec.assume_init()) @@ -277,9 +284,7 @@ pub(crate) fn clock_settime(id: ClockId, timespec: Timespec) -> io::Result<()> { any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", ))] -#[must_use] unsafe fn clock_settime_old(id: ClockId, timespec: Timespec) -> io::Result<()> { - use core::convert::TryInto; let old_timespec = c::timespec { tv_sec: timespec .tv_sec @@ -290,13 +295,13 @@ unsafe fn clock_settime_old(id: ClockId, timespec: Timespec) -> io::Result<()> { ret(c::clock_settime(id as c::clockid_t, &old_timespec)) } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(feature = "time")] pub(crate) fn timerfd_create(id: TimerfdClockId, flags: TimerfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(c::timerfd_create(id as c::clockid_t, flags.bits())) } + unsafe { ret_owned_fd(c::timerfd_create(id as c::clockid_t, bitflags_bits!(flags))) } } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(feature = "time")] pub(crate) fn timerfd_settime( fd: BorrowedFd<'_>, @@ -313,7 +318,7 @@ pub(crate) fn timerfd_settime( if let Some(libc_timerfd_settime) = __timerfd_settime64.get() { ret(libc_timerfd_settime( borrowed_fd(fd), - flags.bits(), + bitflags_bits!(flags), &new_value.clone().into(), result.as_mut_ptr(), ))?; @@ -330,7 +335,7 @@ pub(crate) fn timerfd_settime( unsafe { ret(c::timerfd_settime( borrowed_fd(fd), - flags.bits(), + bitflags_bits!(flags), new_value, result.as_mut_ptr(), ))?; @@ -338,7 +343,7 @@ pub(crate) fn timerfd_settime( } } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -349,8 +354,6 @@ unsafe fn timerfd_settime_old( flags: TimerfdTimerFlags, new_value: &Itimerspec, ) -> io::Result<Itimerspec> { - use core::convert::TryInto; - let mut old_result = MaybeUninit::<c::itimerspec>::uninit(); // Convert `new_value` to the old `itimerspec` format. @@ -383,7 +386,7 @@ unsafe fn timerfd_settime_old( ret(c::timerfd_settime( borrowed_fd(fd), - flags.bits(), + bitflags_bits!(flags), &old_new_value, old_result.as_mut_ptr(), ))?; @@ -409,7 +412,7 @@ unsafe fn timerfd_settime_old( }) } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(feature = "time")] pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { let mut result = MaybeUninit::<LibcItimerspec>::uninit(); @@ -437,15 +440,13 @@ pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { } } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", ))] #[cfg(feature = "time")] unsafe fn timerfd_gettime_old(fd: BorrowedFd<'_>) -> io::Result<Itimerspec> { - use core::convert::TryInto; - let mut old_result = MaybeUninit::<c::itimerspec>::uninit(); ret(c::timerfd_gettime(borrowed_fd(fd), old_result.as_mut_ptr()))?; diff --git a/vendor/rustix/src/backend/libc/time/types.rs b/vendor/rustix/src/backend/libc/time/types.rs index c78aeb21a..e1d4a8736 100644 --- a/vendor/rustix/src/backend/libc/time/types.rs +++ b/vendor/rustix/src/backend/libc/time/types.rs @@ -1,220 +1,25 @@ -use super::super::c; -#[cfg(not(target_os = "wasi"))] -use crate::fd::BorrowedFd; -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -use bitflags::bitflags; - -/// `struct timespec` -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -pub type Timespec = c::timespec; - -/// `struct timespec` +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +use crate::backend::c; #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", ))] -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Timespec { - /// Seconds. - pub tv_sec: Secs, - - /// Nanoseconds. Must be less than 1_000_000_000. - pub tv_nsec: Nsecs, -} - -/// A type for the `tv_sec` field of [`Timespec`]. -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -#[allow(deprecated)] -pub type Secs = c::time_t; - -/// A type for the `tv_sec` field of [`Timespec`]. -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -pub type Secs = i64; - -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] -pub type Nsecs = i64; - -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] -pub type Nsecs = c::c_long; - -/// On most platforms, `LibcTimespec` is just `Timespec`. -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -pub(crate) type LibcTimespec = Timespec; - -/// 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(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[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: Nsecs, - - #[cfg(target_endian = "little")] - padding: core::mem::MaybeUninit<u32>, -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -impl From<LibcTimespec> for Timespec { - #[inline] - fn from(t: LibcTimespec) -> Self { - Self { - tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec, - } - } -} - +use crate::timespec::LibcTimespec; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", ))] -impl From<Timespec> for LibcTimespec { - #[inline] - fn from(t: Timespec) -> Self { - Self { - tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec, - padding: core::mem::MaybeUninit::uninit(), - } - } -} - -/// `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(target_os = "dragonfly"), repr(i32))] -#[cfg_attr(target_os = "dragonfly", repr(u64))] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - Realtime = c::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC` - Monotonic = c::CLOCK_MONOTONIC, - - /// `CLOCK_UPTIME` - #[cfg(any(freebsdlike))] - Uptime = c::CLOCK_UPTIME, - - /// `CLOCK_PROCESS_CPUTIME_ID` - #[cfg(not(any(netbsdlike, solarish, target_os = "redox")))] - ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, - - /// `CLOCK_THREAD_CPUTIME_ID` - #[cfg(not(any(netbsdlike, solarish, target_os = "redox")))] - ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, - - /// `CLOCK_REALTIME_COARSE` - #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] - RealtimeCoarse = c::CLOCK_REALTIME_COARSE, - - /// `CLOCK_MONOTONIC_COARSE` - #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] - MonotonicCoarse = c::CLOCK_MONOTONIC_COARSE, - - /// `CLOCK_MONOTONIC_RAW` - #[cfg(any(target_os = "android", target_os = "linux"))] - MonotonicRaw = c::CLOCK_MONOTONIC_RAW, -} - -/// `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. -#[cfg(apple)] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - Realtime = c::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC` - Monotonic = c::CLOCK_MONOTONIC, - - /// `CLOCK_PROCESS_CPUTIME_ID` - ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, - - /// `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`, available on Linux >= 3.0 - #[cfg(any(target_os = "android", target_os = "linux"))] - RealtimeAlarm, - - /// `CLOCK_TAI`, available on Linux >= 3.10 - #[cfg(any(target_os = "android", target_os = "linux"))] - Tai, - - /// `CLOCK_BOOTTIME`, available on Linux >= 2.6.39 - #[cfg(any(target_os = "android", target_os = "linux"))] - Boottime, - - /// `CLOCK_BOOTTIME_ALARM`, available on Linux >= 2.6.39 - #[cfg(any(target_os = "android", target_os = "linux"))] - BoottimeAlarm, -} +use crate::timespec::Timespec; +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +use bitflags::bitflags; /// `struct itimerspec` for use with [`timerfd_gettime`] and /// [`timerfd_settime`]. /// /// [`timerfd_gettime`]: crate::time::timerfd_gettime /// [`timerfd_settime`]: crate::time::timerfd_settime -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(not(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -226,7 +31,7 @@ pub type Itimerspec = c::itimerspec; /// /// [`timerfd_gettime`]: crate::time::timerfd_gettime /// [`timerfd_settime`]: crate::time::timerfd_settime -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -240,7 +45,7 @@ pub struct Itimerspec { } /// On most platforms, `LibcItimerspec` is just `Itimerspec`. -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(not(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -249,7 +54,7 @@ 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(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -261,7 +66,7 @@ pub(crate) struct LibcItimerspec { pub it_value: LibcTimespec, } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -276,7 +81,7 @@ impl From<LibcItimerspec> for Itimerspec { } } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[cfg(all( any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), target_env = "gnu", @@ -291,41 +96,45 @@ impl From<Itimerspec> for LibcItimerspec { } } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] bitflags! { /// `TFD_*` flags for use with [`timerfd_create`]. /// /// [`timerfd_create`]: crate::time::timerfd_create - pub struct TimerfdFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct TimerfdFlags: u32 { /// `TFD_NONBLOCK` - const NONBLOCK = c::TFD_NONBLOCK; + const NONBLOCK = bitcast!(c::TFD_NONBLOCK); /// `TFD_CLOEXEC` - const CLOEXEC = c::TFD_CLOEXEC; + const CLOEXEC = bitcast!(c::TFD_CLOEXEC); } } -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] bitflags! { /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. /// /// [`timerfd_settime`]: crate::time::timerfd_settime - pub struct TimerfdTimerFlags: c::c_int { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct TimerfdTimerFlags: u32 { /// `TFD_TIMER_ABSTIME` - const ABSTIME = c::TFD_TIMER_ABSTIME; + const ABSTIME = bitcast!(c::TFD_TIMER_ABSTIME); /// `TFD_TIMER_CANCEL_ON_SET` - #[cfg(any(target_os = "android", target_os = "linux"))] - const CANCEL_ON_SET = c::TFD_TIMER_CANCEL_ON_SET; + #[cfg(linux_kernel)] + const CANCEL_ON_SET = bitcast!(c::TFD_TIMER_CANCEL_ON_SET); } } /// `CLOCK_*` constants for use with [`timerfd_create`]. /// /// [`timerfd_create`]: crate::time::timerfd_create -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(any(linux_kernel, target_os = "fuchsia"))] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(i32)] +#[repr(u32)] #[non_exhaustive] pub enum TimerfdClockId { /// `CLOCK_REALTIME`—A clock that tells the “real” time. @@ -334,7 +143,7 @@ pub enum TimerfdClockId { /// 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. - Realtime = c::CLOCK_REALTIME, + Realtime = bitcast!(c::CLOCK_REALTIME), /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. /// @@ -344,25 +153,33 @@ pub enum TimerfdClockId { /// /// This clock does not advance while the system is suspended; see /// `Boottime` for a clock that does. - Monotonic = c::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. - Boottime = c::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. - RealtimeAlarm = c::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. - BoottimeAlarm = c::CLOCK_BOOTTIME_ALARM, + BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM), +} + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +#[test] +fn test_types() { + use core::mem::size_of; + assert_eq!(size_of::<TimerfdFlags>(), size_of::<c::c_int>()); + assert_eq!(size_of::<TimerfdTimerFlags>(), size_of::<c::c_int>()); } diff --git a/vendor/rustix/src/backend/libc/ugid/mod.rs b/vendor/rustix/src/backend/libc/ugid/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/libc/ugid/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/ugid/syscalls.rs b/vendor/rustix/src/backend/libc/ugid/syscalls.rs new file mode 100644 index 000000000..0d3f622dc --- /dev/null +++ b/vendor/rustix/src/backend/libc/ugid/syscalls.rs @@ -0,0 +1,42 @@ +use crate::backend::c; +use crate::ugid::{Gid, Uid}; + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getuid() -> Uid { + unsafe { + let uid = c::getuid(); + Uid::from_raw(uid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn geteuid() -> Uid { + unsafe { + let uid = c::geteuid(); + Uid::from_raw(uid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getgid() -> Gid { + unsafe { + let gid = c::getgid(); + Gid::from_raw(gid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getegid() -> Gid { + unsafe { + let gid = c::getegid(); + Gid::from_raw(gid) + } +} diff --git a/vendor/rustix/src/backend/libc/winsock_c.rs b/vendor/rustix/src/backend/libc/winsock_c.rs index a30f2c86f..0a1554a86 100644 --- a/vendor/rustix/src/backend/libc/winsock_c.rs +++ b/vendor/rustix/src/backend/libc/winsock_c.rs @@ -2,6 +2,7 @@ #![allow(unused_imports)] #![allow(non_camel_case_types)] +#![allow(dead_code)] use windows_sys::Win32::Networking::WinSock; @@ -32,16 +33,12 @@ pub(crate) const AF_UNSPEC: i32 = WinSock::AF_UNSPEC as _; // `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, socklen_t, WSAPoll as poll, - ADDRESS_FAMILY as sa_family_t, ADDRINFOA as addrinfo, IN6_ADDR as in6_addr, IN_ADDR as in_addr, - IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MREQ as ipv6_mreq, IPV6_MULTICAST_LOOP, - IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MREQ as ip_mreq, IP_MULTICAST_LOOP, - IP_MULTICAST_TTL, IP_TTL, LINGER as linger, POLLERR, POLLHUP, POLLIN, POLLNVAL, POLLOUT, - POLLPRI, POLLRDBAND, POLLRDNORM, POLLWRBAND, POLLWRNORM, 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, SOL_SOCKET, SO_BROADCAST, - SO_ERROR, SO_LINGER, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, - WSAEACCES as EACCES, WSAEADDRINUSE as EADDRINUSE, WSAEADDRNOTAVAIL as EADDRNOTAVAIL, + 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, |